1 /* 2 * Sigma Control API DUT (station/AP) 3 * Copyright (c) 2010-2011, Atheros Communications, Inc. 4 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc. 5 * Copyright (c) 2018-2019, The Linux Foundation 6 * All Rights Reserved. 7 * Licensed under the Clear BSD license. See README for more details. 8 */ 9 10 #include "sigma_dut.h" 11 #include <sys/stat.h> 12 #include <sys/wait.h> 13 #include <sys/utsname.h> 14 #include <sys/ioctl.h> 15 #ifdef __linux__ 16 #include <limits.h> 17 #include <dirent.h> 18 #include <string.h> 19 #include <sys/types.h> 20 #include <unistd.h> 21 #endif /* __linux__ */ 22 #ifdef __QNXNTO__ 23 #include <ifaddrs.h> 24 #include <net/if_dl.h> 25 #endif /* __QNXNTO__ */ 26 #include "wpa_ctrl.h" 27 #include "wpa_helpers.h" 28 #ifdef ANDROID 29 #include <hardware_legacy/wifi.h> 30 #include <grp.h> 31 #include <pwd.h> 32 #endif /* ANDROID */ 33 34 /* Temporary files for ap_send_addba_req */ 35 #define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp" 36 #define VI_QOS_FILE "/tmp/vi-qos.txt" 37 #define VI_QOS_REFFILE "/etc/vi-qos.txt" 38 39 /* Configuration file name on Android */ 40 #ifndef ANDROID_CONFIG_FILE 41 #define ANDROID_CONFIG_FILE "/data/misc/wifi/hostapd.conf" 42 #endif /* ANDROID_CONFIG_FILE */ 43 /* Maximum length of the line in the configuration file */ 44 #define MAX_CONF_LINE_LEN (156) 45 46 #ifndef SIGMA_DUT_HOSTAPD_PID_FILE 47 #define SIGMA_DUT_HOSTAPD_PID_FILE "/tmp/sigma_dut-ap-hostapd.pid" 48 #endif /* SIGMA_DUT_HOSTAPD_PID_FILE */ 49 50 /* The following is taken from Hotspot 2.0 testplan Appendix B.1 */ 51 #define ANQP_VENUE_NAME_1 "02019c0002083d656e6757692d466920416c6c69616e63650a3239383920436f7070657220526f61640a53616e746120436c6172612c2043412039353035312c205553415b63686957692d4669e88194e79b9fe5ae9ee9aa8ce5aea40ae4ba8ce4b99de585abe4b99de5b9b4e5ba93e69f8fe8b7af0ae59ca3e5858be68b89e68b892c20e58aa0e588a9e7a68fe5b0bce4ba9a39353035312c20e7be8ee59bbd" 52 #define ANQP_VENUE_NAME_1_CHI "P\"\x63\x68\x69\x3a\x57\x69\x2d\x46\x69\xe8\x81\x94\xe7\x9b\x9f\xe5\xae\x9e\xe9\xaa\x8c\xe5\xae\xa4\\n\xe4\xba\x8c\xe4\xb9\x9d\xe5\x85\xab\xe4\xb9\x9d\xe5\xb9\xb4\xe5\xba\x93\xe6\x9f\x8f\xe8\xb7\xaf\\n\xe5\x9c\xa3\xe5\x85\x8b\xe6\x8b\x89\xe6\x8b\x89\x2c\x20\xe5\x8a\xa0\xe5\x88\xa9\xe7\xa6\x8f\xe5\xb0\xbc\xe4\xba\x9a\x39\x35\x30\x35\x31\x2c\x20\xe7\xbe\x8e\xe5\x9b\xbd\"" 53 #define ANQP_IP_ADDR_TYPE_1 "060101000c" 54 #define ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "dddd2700506f9a11030011656e6757692d466920416c6c69616e63650e63686957692d4669e88194e79b9f" 55 #define ANQP_HS20_WAN_METRICS_1 "dddd1300506f9a11040001c40900008001000000000000" 56 #define ANQP_HS20_CONNECTION_CAPABILITY_1 "dddd3200506f9a1105000100000006140001061600000650000106bb010106bb060006c4130011f4010111c413001194110132000001" 57 #define QOS_MAP_SET_1 "53,2,22,6,8,15,0,7,255,255,16,31,32,39,255,255,40,47,255,255" 58 #define QOS_MAP_SET_2 "8,15,0,7,255,255,16,31,32,39,255,255,40,47,48,63" 59 60 #define ADV_OF_CHARGE_1 \ 61 "bc01000000d200454e475553443c3f786d6c2076657273696f6e3d22312e30222065" \ 62 "6e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f77" \ 63 "77772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f" \ 64 "74302f76312e302f616f637069223e3c4465736372697074696f6e3e57692d46692061636365" \ 65 "737320666f72203120686f75722c207768696c6520796f752077616974206174207468652067" \ 66 "6174652c2024302e39393c2f4465736372697074696f6e3e3c2f506c616e3ee3004652414341" \ 67 "443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d38223f" \ 68 "3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f72672f737065" \ 69 "63696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f637069223e3c" \ 70 "4465736372697074696f6e3e416363c3a8732057692d46692070656e64616e74203120686575" \ 71 "72652c2070656e64616e742071756520766f757320617474656e64657a20c3a0206c6120706f" \ 72 "7274652c20302c393920243c2f4465736372697074696f6e3e3c2f506c616e3ea101010000c7" \ 73 "00454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d2255" \ 74 "54462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77692d66692e6f" \ 75 "72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76312e302f616f" \ 76 "637069223e3c4465736372697074696f6e3e446f776e6c6f616420766964656f7320666f7220" \ 77 "796f757220666c696768742c2024322e393920666f7220313047423c2f446573637269707469" \ 78 "6f6e3e3c2f506c616e3ed3004652414341443c3f786d6c2076657273696f6e3d22312e302220" \ 79 "656e636f64696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f" \ 80 "7777772e77692d66692e6f72672f73706563696669636174696f6e732f686f7473706f743264" \ 81 "6f74302f76312e302f616f637069223e3c4465736372697074696f6e3e54c3a96cc3a9636861" \ 82 "7267657a2064657320766964c3a96f7320706f757220766f74726520766f6c2c20322c393920" \ 83 "2420706f757220313020476f3c2f4465736372697074696f6e3e3c2f506c616e3ee40003002b" \ 84 "736572766963652d70726f76696465722e636f6d3b66656465726174696f6e2e6578616d706c" \ 85 "652e636f6db400454e475553443c3f786d6c2076657273696f6e3d22312e302220656e636f64" \ 86 "696e673d225554462d38223f3e3c506c616e20786d6c6e733d22687474703a2f2f7777772e77" \ 87 "692d66692e6f72672f73706563696669636174696f6e732f686f7473706f7432646f74302f76" \ 88 "312e302f616f637069223e3c4465736372697074696f6e3e46726565207769746820796f7572" \ 89 "20737562736372697074696f6e213c2f4465736372697074696f6e3e3c2f506c616e3e" 90 91 /* 92 * MTU for Ethernet need to take into account 8-byte SNAP header 93 * to be added when encapsulating Ethernet frame into 802.11. 94 */ 95 #ifndef IEEE80211_MAX_DATA_LEN_DMG 96 #define IEEE80211_MAX_DATA_LEN_DMG 7920 97 #endif /* IEEE80211_MAX_DATA_LEN_DMG */ 98 #ifndef IEEE80211_SNAP_LEN_DMG 99 #define IEEE80211_SNAP_LEN_DMG 8 100 #endif /* IEEE80211_SNAP_LEN_DMG */ 101 102 extern char *sigma_wpas_ctrl; 103 extern char *sigma_hapd_ctrl; 104 extern char *ap_inet_addr; 105 extern char *ap_inet_mask; 106 extern char *sigma_radio_ifname[]; 107 108 static int ath_ap_start_hostapd(struct sigma_dut *dut); 109 static void ath_ap_set_params(struct sigma_dut *dut); 110 static int kill_process(struct sigma_dut *dut, char *proc_name, 111 unsigned char is_proc_instance_one, int sig); 112 113 114 static int ap_ft_enabled(struct sigma_dut *dut) 115 { 116 return dut->ap_ft_oa == 1 || 117 dut->ap_ft_ds == VALUE_ENABLED || 118 dut->ap_key_mgmt == AP_WPA2_FT_EAP || 119 dut->ap_key_mgmt == AP_WPA2_FT_PSK || 120 dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP || 121 (dut->ap_akm_values & 122 ((1 << AKM_FT_EAP) | 123 (1 << AKM_FT_PSK) | 124 (1 << AKM_FT_SAE) | 125 (1 << AKM_FT_SUITE_B) | 126 (1 << AKM_FT_FILS_SHA256) | 127 (1 << AKM_FT_FILS_SHA384))); 128 } 129 130 131 static enum sigma_cmd_result cmd_ap_ca_version(struct sigma_dut *dut, 132 struct sigma_conn *conn, 133 struct sigma_cmd *cmd) 134 { 135 /* const char *name = get_param(cmd, "NAME"); */ 136 send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0"); 137 return 0; 138 } 139 140 141 static void kill_hostapd_process_pid(struct sigma_dut *dut) 142 { 143 FILE *f; 144 int pid, res; 145 char path[100]; 146 int count; 147 148 f = fopen(SIGMA_DUT_HOSTAPD_PID_FILE, "r"); 149 if (!f) 150 return; 151 res = fscanf(f, "%d", &pid); 152 fclose(f); 153 if (res != 1) 154 return; 155 sigma_dut_print(dut, DUT_MSG_INFO, "Killing hostapd pid %d", pid); 156 kill(pid, SIGTERM); 157 snprintf(path, sizeof(path), "/proc/%d", pid); 158 for (count = 0; count < 20 && file_exists(path); count++) 159 usleep(100000); 160 } 161 162 163 int get_hwaddr(const char *ifname, unsigned char *hwaddr) 164 { 165 #ifndef __QNXNTO__ 166 struct ifreq ifr; 167 int s; 168 169 s = socket(AF_INET, SOCK_DGRAM, 0); 170 if (s < 0) 171 return -1; 172 memset(&ifr, 0, sizeof(ifr)); 173 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 174 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 175 perror("ioctl"); 176 close(s); 177 return -1; 178 } 179 close(s); 180 memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6); 181 #else /* __QNXNTO__ */ 182 struct ifaddrs *ifaddrshead = NULL; 183 int found = 0; 184 struct ifaddrs *temp_ifap = NULL; 185 struct sockaddr_dl *sdl = NULL; 186 187 if (getifaddrs(&ifaddrshead) != 0) { 188 perror("getifaddrs failed"); 189 return -1; 190 } 191 192 for (temp_ifap = ifaddrshead; ifaddrshead && !found; 193 ifaddrshead = ifaddrshead->ifa_next) { 194 if (ifaddrshead->ifa_addr->sa_family == AF_LINK && 195 strcmp(ifaddrshead->ifa_name, ifname) == 0) { 196 found = 1; 197 sdl = (struct sockaddr_dl *) ifaddrshead->ifa_addr; 198 if (sdl) 199 memcpy(hwaddr, LLADDR(sdl), sdl->sdl_alen); 200 } 201 } 202 203 if (temp_ifap) 204 freeifaddrs(temp_ifap); 205 206 if (!found) { 207 perror("Failed to get the interface"); 208 return -1; 209 } 210 #endif /* __QNXNTO__ */ 211 return 0; 212 } 213 214 215 static void ath_ap_set_group_id(struct sigma_dut *dut, const char *ifname, 216 const char *val) 217 { 218 char buf[60]; 219 220 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 55 %d", 221 ifname, atoi(val)); 222 if (system(buf) != 0) { 223 sigma_dut_print(dut, DUT_MSG_ERROR, 224 "wifitool ap_group_id failed"); 225 } 226 } 227 228 229 void ath_set_cts_width(struct sigma_dut *dut, const char *ifname, 230 const char *val) 231 { 232 char buf[60]; 233 234 /* TODO: Enable support for other values */ 235 if (strcasecmp(val, "40") == 0) { 236 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 1", 237 ifname); 238 if (system(buf) != 0) { 239 sigma_dut_print(dut, DUT_MSG_ERROR, 240 "wifitool cts_width failed"); 241 } 242 snprintf(buf, sizeof(buf), 243 "athdiag --set --address=0x10024 --val=0xd90b8a14"); 244 if (system(buf) != 0) { 245 sigma_dut_print(dut, DUT_MSG_ERROR, 246 "disabling phy restart failed"); 247 } 248 } else { 249 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported CTS_WIDTH"); 250 } 251 } 252 253 254 void ath_config_dyn_bw_sig(struct sigma_dut *dut, const char *ifname, 255 const char *val) 256 { 257 char buf[60]; 258 259 if (strcasecmp(val, "enable") == 0) { 260 dut->ap_dyn_bw_sig = VALUE_ENABLED; 261 run_iwpriv(dut, ifname, "cwmenable 1"); 262 263 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 96 1", 264 ifname); 265 if (system(buf) != 0) { 266 sigma_dut_print(dut, DUT_MSG_ERROR, 267 "disabling RTS from rate control logic failed"); 268 } 269 } else if (strcasecmp(val, "disable") == 0) { 270 dut->ap_dyn_bw_sig = VALUE_DISABLED; 271 run_iwpriv(dut, ifname, "cwmenable 0"); 272 } else { 273 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported DYN_BW_SGL"); 274 } 275 } 276 277 278 static void wcn_config_ap_ldpc(struct sigma_dut *dut, const char *ifname) 279 { 280 if (dut->ap_ldpc == VALUE_NOT_SET) 281 return; 282 run_iwpriv(dut, ifname, "ldpc %d", dut->ap_ldpc != VALUE_DISABLED); 283 } 284 285 286 static void mac80211_config_rts_force(struct sigma_dut *dut, const char *ifname, 287 const char *val) 288 { 289 char buf[60]; 290 char fname[128], path[128], *pos; 291 ssize_t res; 292 293 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211", 294 ifname); 295 if (res < 0 || res >= sizeof(fname)) 296 return; 297 298 res = readlink(fname, path, sizeof(path)); 299 if (res < 0) 300 return; 301 302 if (res >= (int) sizeof(path)) 303 res = sizeof(path) - 1; 304 path[res] = '\0'; 305 306 pos = strrchr(path, '/'); 307 if (!pos) 308 pos = path; 309 else 310 pos++; 311 312 if (strcasecmp(val, "enable") == 0) { 313 dut->ap_sig_rts = VALUE_ENABLED; 314 res = snprintf(buf, sizeof(buf), "iw %s set rts 64", pos); 315 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 316 sigma_dut_print(dut, DUT_MSG_ERROR, 317 "iw set rts 64 failed"); 318 } 319 } else if (strcasecmp(val, "disable") == 0) { 320 dut->ap_sig_rts = VALUE_DISABLED; 321 res = snprintf(buf, sizeof(buf), "iw %s set rts 2347", pos); 322 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 323 sigma_dut_print(dut, DUT_MSG_ERROR, 324 "iw rts 2347 failed"); 325 } 326 } else { 327 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE"); 328 } 329 330 } 331 332 333 static void ath_config_rts_force(struct sigma_dut *dut, const char *ifname, 334 const char *val) 335 { 336 char buf[60]; 337 338 if (strcasecmp(val, "enable") == 0) { 339 dut->ap_sig_rts = VALUE_ENABLED; 340 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname); 341 if (system(buf) != 0) { 342 sigma_dut_print(dut, DUT_MSG_ERROR, 343 "iwconfig rts 64 failed"); 344 } 345 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 100 1", 346 ifname); 347 if (system(buf) != 0) { 348 sigma_dut_print(dut, DUT_MSG_ERROR, 349 "wifitool beeliner_fw_test 100 1 failed"); 350 } 351 } else if (strcasecmp(val, "disable") == 0) { 352 dut->ap_sig_rts = VALUE_DISABLED; 353 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname); 354 if (system(buf) != 0) { 355 sigma_dut_print(dut, DUT_MSG_ERROR, 356 "iwconfig rts 2347 failed"); 357 } 358 } else { 359 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported RTS_FORCE"); 360 } 361 } 362 363 364 static void ath_radio(struct sigma_dut *dut, const char *val) 365 { 366 if (strcasecmp(val, "on") == 0) { 367 if (dut->ap_interface_5g == 1) { 368 run_system(dut, "uci set wireless.wifi0.disabled=0"); 369 } else if (dut->ap_interface_2g == 1) { 370 run_system(dut, "uci set wireless.wifi1.disabled=0"); 371 } else { 372 run_system(dut, "uci set wireless.wifi0.disabled=0"); 373 run_system(dut, "uci set wireless.wifi1.disabled=0"); 374 } 375 run_system(dut, "uci commit"); 376 run_system(dut, "wifi down"); 377 run_system(dut, "wifi up"); 378 } else if (strcasecmp(val, "off") == 0) { 379 if (dut->ap_interface_5g == 1) { 380 run_system(dut, "uci set wireless.wifi0.disabled=1"); 381 } else if (dut->ap_interface_2g == 1) { 382 run_system(dut, "uci set wireless.wifi1.disabled=1"); 383 } else { 384 run_system(dut, "uci set wireless.wifi0.disabled=1"); 385 run_system(dut, "uci set wireless.wifi1.disabled=1"); 386 } 387 run_system(dut, "uci commit"); 388 run_system(dut, "wifi down"); 389 run_system(dut, "wifi up"); 390 } 391 } 392 393 394 static void deauth_disassoc(struct sigma_dut *dut, const char *ifname, 395 const char *val) 396 { 397 if (strcasecmp(val, "disable") == 0) 398 run_iwpriv(dut, ifname, "stealthdown 1"); 399 } 400 401 402 static void ath_set_txpower(struct sigma_dut *dut, const char *ifname, 403 const char *val) 404 { 405 char buf[60]; 406 407 if (strcasecmp(val, "high") == 0) 408 snprintf(buf, sizeof(buf), "iwconfig %s txpower 29", ifname); 409 else if (strcasecmp(val, "low") == 0) 410 snprintf(buf, sizeof(buf), "iwconfig %s txpower 1", ifname); 411 else 412 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported txpower"); 413 414 if (system(buf) != 0) 415 sigma_dut_print(dut, DUT_MSG_ERROR, "setting txpower failed"); 416 } 417 418 419 static enum ap_mode get_mode(const char *str) 420 { 421 if (strcasecmp(str, "11a") == 0) 422 return AP_11a; 423 else if (strcasecmp(str, "11g") == 0) 424 return AP_11g; 425 else if (strcasecmp(str, "11b") == 0) 426 return AP_11b; 427 else if (strcasecmp(str, "11na") == 0) 428 return AP_11na; 429 else if (strcasecmp(str, "11ng") == 0) 430 return AP_11ng; 431 else if (strcasecmp(str, "11ac") == 0 || strcasecmp(str, "ac") == 0) 432 return AP_11ac; 433 else if (strcasecmp(str, "11ad") == 0) 434 return AP_11ad; 435 else if (strcasecmp(str, "11ax") == 0) 436 return AP_11ax; 437 else 438 return AP_inval; 439 } 440 441 442 static int run_hostapd_cli(struct sigma_dut *dut, char *buf) 443 { 444 char command[1000]; 445 const char *bin; 446 enum driver_type drv = get_driver_type(dut); 447 char *sigma_hapd_file = sigma_hapd_ctrl; 448 449 if (file_exists("hostapd_cli")) 450 bin = "./hostapd_cli"; 451 else if (file_exists("../../hostapd/hostapd_cli")) 452 bin = "../../hostapd/hostapd_cli"; 453 else 454 bin = "hostapd_cli"; 455 456 if (drv == DRIVER_OPENWRT && sigma_hapd_ctrl == NULL) { 457 sigma_hapd_file = "/var/run/hostapd-wifi0"; 458 459 if (sigma_radio_ifname[0] && 460 strcmp(sigma_radio_ifname[0], "wifi1") == 0) 461 sigma_hapd_file = "/var/run/hostapd-wifi1"; 462 else if (sigma_radio_ifname[0] && 463 strcmp(sigma_radio_ifname[0], "wifi2") == 0) 464 sigma_hapd_file = "/var/run/hostapd-wifi2"; 465 } 466 467 if (sigma_hapd_file) 468 snprintf(command, sizeof(command), "%s -p %s %s", 469 bin, sigma_hapd_file, buf); 470 else 471 snprintf(command, sizeof(command), "%s %s", bin, buf); 472 return run_system(dut, command); 473 } 474 475 476 static int ath_set_lci_config(struct sigma_dut *dut, const char *val, 477 struct sigma_cmd *cmd) 478 { 479 FILE *f; 480 int i; 481 482 f = fopen("/tmp/lci_cfg.txt", "w"); 483 if (!f) { 484 sigma_dut_print(dut, DUT_MSG_ERROR, 485 "Failed to open /tmp/lci_cfg.txt"); 486 return -1; 487 } 488 489 for (i = 2; i < cmd->count; i++) 490 fprintf(f, "%s = %s \n", cmd->params[i], cmd->values[i]); 491 fprintf(f, "\n"); 492 fclose(f); 493 494 return 0; 495 } 496 497 498 static void set_ap_country_code(struct sigma_dut *dut) 499 { 500 #if defined(ANDROID) || defined(LINUX_EMBEDDED) 501 char buf[256]; 502 503 if (dut->ap_countrycode[0]) { 504 snprintf(buf, sizeof(buf), "DRIVER COUNTRY %s", 505 dut->ap_countrycode); 506 if (wpa_command(get_station_ifname(dut), buf) < 0) 507 sigma_dut_print(dut, DUT_MSG_ERROR, 508 "Failed to set country code"); 509 else 510 sigma_dut_print(dut, DUT_MSG_INFO, 511 "Successfully set country code to %s", 512 dut->ap_countrycode); 513 } 514 #endif 515 } 516 517 518 static void set_vht_mcsmap_nss(struct sigma_dut *dut, int nss, int mcs) 519 { 520 switch (nss) { 521 case 1: 522 switch (mcs) { 523 case 7: 524 dut->ap_vhtmcs_map = 0xfffc; 525 break; 526 case 8: 527 dut->ap_vhtmcs_map = 0xfffd; 528 break; 529 case 9: 530 dut->ap_vhtmcs_map = 0xfffe; 531 break; 532 default: 533 dut->ap_vhtmcs_map = 0xfffe; 534 break; 535 } 536 break; 537 case 2: 538 switch (mcs) { 539 case 7: 540 dut->ap_vhtmcs_map = 0xfff0; 541 break; 542 case 8: 543 dut->ap_vhtmcs_map = 0xfff5; 544 break; 545 case 9: 546 dut->ap_vhtmcs_map = 0xfffa; 547 break; 548 default: 549 dut->ap_vhtmcs_map = 0xfffa; 550 break; 551 } 552 break; 553 case 3: 554 switch (mcs) { 555 case 7: 556 dut->ap_vhtmcs_map = 0xffc0; 557 break; 558 case 8: 559 dut->ap_vhtmcs_map = 0xffd5; 560 break; 561 case 9: 562 dut->ap_vhtmcs_map = 0xffea; 563 break; 564 default: 565 dut->ap_vhtmcs_map = 0xffea; 566 break; 567 } 568 default: 569 dut->ap_vhtmcs_map = 0xffea; 570 break; 571 } 572 } 573 574 575 /* Get 2*nss bitmask */ 576 /* We are trying to pack 2-bit MCS values per NSS in a 16-bit wide field. 577 * IEEE P802.11ax/D5.0, 9.4.2.247.4 supported HE-MCS And NSS Set field 578 * defines the following format for the 16 bit value. */ 579 580 #define HE_GET_MCS_NSS_PACK_MASK(nss) ((1 << ((nss) << 1)) - 1) 581 582 static void he_reset_mcs_values_for_unsupported_ss(uint8_t *mcsnssmap, 583 uint8_t nss) 584 { 585 uint8_t nssmask; 586 587 if (nss <= 4) { 588 nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss); 589 mcsnssmap[0] |= nssmask; 590 mcsnssmap[1] = 0xff; 591 } else if (nss > 4 && nss <= 8) { 592 nssmask = ~HE_GET_MCS_NSS_PACK_MASK(nss - 4); 593 mcsnssmap[0] &= 0xff; 594 mcsnssmap[1] |= nssmask; 595 } 596 } 597 598 599 static void get_he_mcs_nssmap(uint8_t *mcsnssmap, uint8_t nss, 600 uint8_t mcs) 601 { 602 switch (mcs) { 603 case 11: 604 mcsnssmap[0] = 0xaa; 605 mcsnssmap[1] = 0xaa; 606 break; 607 case 9: 608 mcsnssmap[0] = 0x55; 609 mcsnssmap[1] = 0x55; 610 break; 611 case 7: 612 mcsnssmap[0] = 0x0; 613 mcsnssmap[1] = 0x0; 614 break; 615 } 616 he_reset_mcs_values_for_unsupported_ss(mcsnssmap, nss); 617 } 618 619 620 static enum sigma_cmd_result cmd_ap_set_wireless(struct sigma_dut *dut, 621 struct sigma_conn *conn, 622 struct sigma_cmd *cmd) 623 { 624 /* const char *name = get_param(cmd, "NAME"); */ 625 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 626 const char *val; 627 unsigned int wlan_tag = 1; 628 const char *ifname = get_main_ifname(dut); 629 char buf[128]; 630 631 /* Allow program to be overridden if specified in the ap_set_wireless 632 * to support some 60 GHz test scripts where the program may be 60 GHz 633 * or WPS. */ 634 val = get_param(cmd, "PROGRAM"); 635 if (val) 636 dut->program = sigma_program_to_enum(val); 637 638 val = get_param(cmd, "WLAN_TAG"); 639 if (val) { 640 wlan_tag = atoi(val); 641 if (wlan_tag < 1 || wlan_tag > 3) { 642 /* 643 * The only valid WLAN Tags as of now as per the latest 644 * WFA scripts are 1, 2, and 3. 645 */ 646 send_resp(dut, conn, SIGMA_INVALID, 647 "errorCode,Invalid WLAN_TAG"); 648 return STATUS_SENT; 649 } 650 } 651 652 val = get_param(cmd, "Interface"); 653 if (val) { 654 if (strcasecmp(val, "5G") == 0) 655 dut->ap_interface_5g = 1; 656 else 657 dut->ap_interface_2g = 1; 658 659 if (dut->ap_interface_5g && dut->ap_interface_2g) 660 dut->ap_is_dual = 1; 661 } 662 663 val = get_param(cmd, "CountryCode"); 664 if (val) { 665 if (strlen(val) > sizeof(dut->ap_countrycode) - 1) 666 return INVALID_SEND_STATUS; 667 snprintf(dut->ap_countrycode, sizeof(dut->ap_countrycode), 668 "%s", val); 669 670 /* 671 * Regdomain self-managed driver does not accept hostapd country 672 * code setting in all cases. Try to use wpa_supplicant DRIVER 673 * command first to set the driver to a specific country code 674 * before starting AP functionality. This is targeting cases 675 * where wpa_supplicant is running on the device as well for 676 * non-AP mode functionality. 677 */ 678 if (get_driver_type(dut) == DRIVER_LINUX_WCN) 679 set_ap_country_code(dut); 680 } 681 682 val = get_param(cmd, "regulatory_mode"); 683 if (val) { 684 if (strcasecmp(val, "11d") == 0 || strcasecmp(val, "11h") == 0) 685 dut->ap_regulatory_mode = AP_80211D_MODE_ENABLED; 686 } 687 688 val = get_param(cmd, "SSID"); 689 if (val) { 690 if (strlen(val) > sizeof(dut->ap_ssid) - 1) 691 return INVALID_SEND_STATUS; 692 693 if (wlan_tag == 1) { 694 /* 695 * If tag is not specified, it is deemed to be 1. 696 * Hence tag of 1 is a special case and the values 697 * corresponding to wlan-tag=1 are stored separately 698 * from the values corresponding tags 2 and 3. 699 * This approach minimises the changes to existing code 700 * since most of the sigma_dut code does not deal with 701 * WLAN-TAG CAPI variable. 702 */ 703 snprintf(dut->ap_ssid, 704 sizeof(dut->ap_ssid), "%s", val); 705 } else { 706 snprintf(dut->ap_tag_ssid[wlan_tag - 2], 707 sizeof(dut->ap_tag_ssid[wlan_tag - 2]), 708 "%s", val); 709 } 710 } 711 712 val = get_param(cmd, "CHANNEL"); 713 if (val) { 714 const char *pos; 715 dut->ap_channel = atoi(val); 716 pos = strchr(val, ';'); 717 if (pos) { 718 pos++; 719 dut->ap_channel_1 = atoi(pos); 720 } 721 } 722 723 /* Overwrite the AP channel with DFS channel if configured */ 724 val = get_param(cmd, "dfs_chan"); 725 if (val) { 726 dut->ap_channel = atoi(val); 727 } 728 729 val = get_param(cmd, "dfs_mode"); 730 if (val) { 731 if (strcasecmp(val, "Enable") == 0) 732 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED; 733 else if (strcasecmp(val, "Disable") == 0) 734 dut->ap_dfs_mode = AP_DFS_MODE_DISABLED; 735 else 736 sigma_dut_print(dut, DUT_MSG_ERROR, 737 "Unsupported dfs_mode value: %s", val); 738 } 739 740 val = get_param(cmd, "MODE"); 741 if (val) { 742 char *str, *pos; 743 744 str = strdup(val); 745 if (str == NULL) 746 return INVALID_SEND_STATUS; 747 pos = strchr(str, ';'); 748 if (pos) 749 *pos++ = '\0'; 750 751 dut->ap_is_dual = 0; 752 dut->ap_mode = get_mode(str); 753 if (dut->ap_mode == AP_inval) { 754 send_resp(dut, conn, SIGMA_INVALID, 755 "errorCode,Unsupported MODE"); 756 free(str); 757 return STATUS_SENT; 758 } 759 if (dut->ap_mode == AP_11ac && dut->ap_80plus80 != 1) 760 dut->ap_chwidth = AP_80; 761 762 if (pos) { 763 dut->ap_mode_1 = get_mode(pos); 764 if (dut->ap_mode_1 == AP_inval) { 765 send_resp(dut, conn, SIGMA_INVALID, 766 "errorCode,Unsupported MODE"); 767 free(str); 768 return STATUS_SENT; 769 } 770 if (dut->ap_mode_1 == AP_11ac) 771 dut->ap_chwidth_1 = AP_80; 772 dut->ap_is_dual = 1; 773 } 774 775 free(str); 776 } else if (dut->ap_mode == AP_inval) { 777 if (dut->ap_channel <= 11) 778 dut->ap_mode = AP_11ng; 779 else if (dut->program == PROGRAM_VHT) 780 dut->ap_mode = AP_11ac; 781 else 782 dut->ap_mode = AP_11na; 783 } 784 785 /* Override the AP mode in case of 60 GHz */ 786 if (dut->program == PROGRAM_60GHZ) { 787 dut->ap_mode = AP_11ad; 788 /* Workaround to force channel 2 if not specified */ 789 if (!dut->ap_channel) 790 dut->ap_channel = 2; 791 } 792 793 switch (dut->ap_mode) { 794 case AP_11g: 795 case AP_11b: 796 case AP_11ng: 797 dut->use_5g = 0; 798 break; 799 case AP_11a: 800 case AP_11na: 801 case AP_11ac: 802 dut->use_5g = 1; 803 break; 804 case AP_11ax: 805 if (dut->ap_channel >= 1 && dut->ap_channel <= 14) 806 dut->use_5g = 0; 807 else if (dut->ap_channel >= 36 && dut->ap_channel <= 171) 808 dut->use_5g = 1; 809 break; 810 case AP_11ad: 811 case AP_inval: 812 break; 813 } 814 815 val = get_param(cmd, "WME"); 816 if (val) { 817 if (strcasecmp(val, "on") == 0) 818 dut->ap_wme = AP_WME_ON; 819 else if (strcasecmp(val, "off") == 0) 820 dut->ap_wme = AP_WME_OFF; 821 else 822 sigma_dut_print(dut, DUT_MSG_ERROR, 823 "Unsupported WME value: %s", val); 824 } 825 826 val = get_param(cmd, "WMMPS"); 827 if (val) { 828 if (strcasecmp(val, "on") == 0) 829 dut->ap_wmmps = AP_WMMPS_ON; 830 else if (strcasecmp(val, "off") == 0) 831 dut->ap_wmmps = AP_WMMPS_OFF; 832 else 833 sigma_dut_print(dut, DUT_MSG_ERROR, 834 "Unsupported WMMPS value: %s", val); 835 } 836 837 val = get_param(cmd, "RTS"); 838 if (val) 839 dut->ap_rts = atoi(val); 840 841 val = get_param(cmd, "FRGMNT"); 842 if (val) 843 dut->ap_frgmnt = atoi(val); 844 845 /* TODO: PWRSAVE */ 846 847 val = get_param(cmd, "BCNINT"); 848 if (val) 849 dut->ap_bcnint = atoi(val); 850 851 val = get_param(cmd, "RADIO"); 852 if (val) { 853 enum driver_type drv = get_driver_type(dut); 854 855 if (strcasecmp(val, "on") == 0) { 856 if (drv == DRIVER_OPENWRT) 857 ath_radio(dut, val); 858 if (drv == DRIVER_ATHEROS) 859 ath_ap_start_hostapd(dut); 860 else if (cmd_ap_config_commit(dut, conn, cmd) <= 0) 861 return STATUS_SENT; 862 } else if (strcasecmp(val, "off") == 0) { 863 if (drv == DRIVER_OPENWRT) { 864 ath_radio(dut, val); 865 } else if (dut->use_hostapd_pid_file) { 866 kill_hostapd_process_pid(dut); 867 } else if (kill_process(dut, "(hostapd)", 1, 868 SIGTERM) == 0 || 869 system("killall hostapd") == 0) { 870 sigma_dut_print(dut, DUT_MSG_INFO, 871 "Killed hostapd on radio,off"); 872 } 873 } else { 874 send_resp(dut, conn, SIGMA_INVALID, 875 "errorCode,Unsupported RADIO value"); 876 return STATUS_SENT; 877 } 878 } 879 880 val = get_param(cmd, "P2PMgmtBit"); 881 if (val) 882 dut->ap_p2p_mgmt = atoi(val); 883 884 /* TODO: ChannelUsage */ 885 886 /* TODO: 40_INTOLERANT */ 887 888 val = get_param(cmd, "ADDBA_REJECT"); 889 if (val) { 890 if (strcasecmp(val, "Enable") == 0) 891 dut->ap_addba_reject = VALUE_ENABLED; 892 else if (strcasecmp(val, "Disable") == 0) 893 dut->ap_addba_reject = VALUE_DISABLED; 894 } 895 896 val = get_param(cmd, "AMPDU"); 897 if (val) { 898 if (strcasecmp(val, "Enable") == 0) 899 dut->ap_ampdu = VALUE_ENABLED; 900 else if (strcasecmp(val, "Disable") == 0) 901 dut->ap_ampdu = VALUE_DISABLED; 902 } 903 904 val = get_param(cmd, "AMPDU_EXP"); 905 if (val) 906 dut->ap_ampdu_exp = atoi(val); 907 908 val = get_param(cmd, "AMSDU"); 909 if (val) { 910 if (strcasecmp(val, "Enable") == 0) 911 dut->ap_amsdu = VALUE_ENABLED; 912 else if (strcasecmp(val, "Disable") == 0) 913 dut->ap_amsdu = VALUE_DISABLED; 914 } 915 916 val = get_param(cmd, "NoAck"); 917 if (val) { 918 if (strcasecmp(val, "on") == 0) 919 dut->ap_noack = VALUE_ENABLED; 920 else if (strcasecmp(val, "off") == 0) 921 dut->ap_noack = VALUE_DISABLED; 922 } 923 924 /* TODO: GREENFIELD */ 925 /* TODO: MCS_32 */ 926 927 val = get_param(cmd, "OFFSET"); 928 if (val) { 929 if (strcasecmp(val, "Above") == 0) 930 dut->ap_chwidth_offset = SEC_CH_40ABOVE; 931 else if (strcasecmp(val, "Below") == 0) 932 dut->ap_chwidth_offset = SEC_CH_40BELOW; 933 } 934 935 val = get_param(cmd, "MCS_FIXEDRATE"); 936 if (val) { 937 dut->ap_fixed_rate = 1; 938 dut->ap_mcs = atoi(val); 939 } 940 941 val = get_param(cmd, "SPATIAL_RX_STREAM"); 942 if (val) { 943 if (strcasecmp(val, "1SS") == 0 || strcasecmp(val, "1") == 0) { 944 dut->ap_rx_streams = 1; 945 if (dut->device_type == AP_testbed) 946 dut->ap_vhtmcs_map = 0xfffc; 947 } else if (strcasecmp(val, "2SS") == 0 || 948 strcasecmp(val, "2") == 0) { 949 dut->ap_rx_streams = 2; 950 if (dut->device_type == AP_testbed) 951 dut->ap_vhtmcs_map = 0xfff0; 952 } else if (strcasecmp(val, "3SS") == 0 || 953 strcasecmp(val, "3") == 0) { 954 dut->ap_rx_streams = 3; 955 if (dut->device_type == AP_testbed) 956 dut->ap_vhtmcs_map = 0xffc0; 957 } else if (strcasecmp(val, "4SS") == 0 || 958 strcasecmp(val, "4") == 0) { 959 dut->ap_rx_streams = 4; 960 } 961 } 962 963 val = get_param(cmd, "SPATIAL_TX_STREAM"); 964 if (val) { 965 if (strcasecmp(val, "1SS") == 0 || 966 strcasecmp(val, "1") == 0) { 967 dut->ap_tx_streams = 1; 968 if (dut->device_type == AP_testbed) 969 dut->ap_vhtmcs_map = 0xfffc; 970 } else if (strcasecmp(val, "2SS") == 0 || 971 strcasecmp(val, "2") == 0) { 972 dut->ap_tx_streams = 2; 973 if (dut->device_type == AP_testbed) 974 dut->ap_vhtmcs_map = 0xfff0; 975 } else if (strcasecmp(val, "3SS") == 0 || 976 strcasecmp(val, "3") == 0) { 977 dut->ap_tx_streams = 3; 978 if (dut->device_type == AP_testbed) 979 dut->ap_vhtmcs_map = 0xffc0; 980 } else if (strcasecmp(val, "4SS") == 0 || 981 strcasecmp(val, "4") == 0) { 982 dut->ap_tx_streams = 4; 983 } 984 } 985 986 val = get_param(cmd, "BSS_max_idle"); 987 if (val) { 988 if (strncasecmp(val, "Enable", 7) == 0) { 989 dut->wnm_bss_max_feature = VALUE_ENABLED; 990 } else if (strncasecmp(val, "Disable", 8) == 0) { 991 dut->wnm_bss_max_feature = VALUE_DISABLED; 992 } else { 993 send_resp(dut, conn, SIGMA_ERROR, 994 "errorCode,Invalid value for BSS_max_Feature"); 995 return STATUS_SENT; 996 } 997 } 998 999 val = get_param(cmd, "BSS_Idle_Protection_options"); 1000 if (val) { 1001 int protection = (int) strtol(val, (char **) NULL, 10); 1002 1003 if (protection != 1 && protection != 0) { 1004 send_resp(dut, conn, SIGMA_ERROR, 1005 "errorCode,Invalid value for BSS_Idle_Protection_options"); 1006 return STATUS_SENT; 1007 } 1008 dut->wnm_bss_max_protection = protection ? 1009 VALUE_ENABLED : VALUE_DISABLED; 1010 } 1011 1012 val = get_param(cmd, "BSS_max_Idle_period"); 1013 if (val) { 1014 long int idle_time = strtol(val, (char **) NULL, 10); 1015 1016 if (idle_time == LONG_MIN || idle_time == LONG_MAX) { 1017 send_resp(dut, conn, SIGMA_ERROR, 1018 "errorCode,Invalid value for BSS_max_Idle_period"); 1019 return STATUS_SENT; 1020 } 1021 dut->wnm_bss_max_idle_time = (int) idle_time; 1022 } 1023 1024 val = get_param(cmd, "PROXY_ARP"); 1025 if (val) 1026 dut->ap_proxy_arp = (int) strtol(val, (char **) NULL, 10); 1027 1028 val = get_param(cmd, "nss_mcs_cap"); 1029 if (val) { 1030 int nss, mcs; 1031 char token[20]; 1032 char *result = NULL; 1033 char *saveptr; 1034 1035 if (strlen(val) >= sizeof(token)) 1036 return INVALID_SEND_STATUS; 1037 strlcpy(token, val, sizeof(token)); 1038 result = strtok_r(token, ";", &saveptr); 1039 if (!result) { 1040 send_resp(dut, conn, SIGMA_ERROR, 1041 "errorCode,VHT NSS not specified"); 1042 return STATUS_SENT; 1043 } 1044 nss = atoi(result); 1045 result = strtok_r(NULL, ";", &saveptr); 1046 if (result == NULL) { 1047 send_resp(dut, conn, SIGMA_ERROR, 1048 "errorCode,VHTMCS not specified"); 1049 return STATUS_SENT; 1050 } 1051 result = strtok_r(result, "-", &saveptr); 1052 result = strtok_r(NULL, "-", &saveptr); 1053 if (!result) { 1054 send_resp(dut, conn, SIGMA_ERROR, 1055 "errorCode,VHT MCS not specified"); 1056 return STATUS_SENT; 1057 } 1058 mcs = atoi(result); 1059 if (dut->program == PROGRAM_HE) { 1060 uint16_t mcsnssmap = 0; 1061 1062 get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs); 1063 dut->he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap; 1064 dut->he_ul_mcs = mcs; 1065 } else { 1066 set_vht_mcsmap_nss(dut, nss, mcs); 1067 } 1068 } 1069 1070 /* TODO: MPDU_MIN_START_SPACING */ 1071 /* TODO: RIFS_TEST */ 1072 /* TODO: SGI20 */ 1073 1074 val = get_param(cmd, "STBC_TX"); 1075 if (val) 1076 dut->ap_tx_stbc = atoi(val); 1077 1078 val = get_param(cmd, "WIDTH"); 1079 if (val) { 1080 if (strcasecmp(val, "20") == 0) 1081 dut->ap_chwidth = AP_20; 1082 else if (strcasecmp(val, "40") == 0) 1083 dut->ap_chwidth = AP_40; 1084 else if (strcasecmp(val, "80") == 0) 1085 dut->ap_chwidth = AP_80; 1086 else if (strcasecmp(val, "160") == 0) 1087 dut->ap_chwidth = AP_160; 1088 else if (strcasecmp(val, "80plus80") == 0) { 1089 dut->ap_80plus80 = 1; 1090 dut->ap_chwidth = AP_80_80; 1091 } else if (strcasecmp(val, "Auto") == 0) 1092 dut->ap_chwidth = AP_AUTO; 1093 else { 1094 send_resp(dut, conn, SIGMA_INVALID, 1095 "errorCode,Unsupported WIDTH"); 1096 return STATUS_SENT; 1097 } 1098 } 1099 1100 /* TODO: WIDTH_SCAN */ 1101 1102 val = get_param(cmd, "TDLSProhibit"); 1103 dut->ap_tdls_prohibit = val && strcasecmp(val, "Enabled") == 0; 1104 val = get_param(cmd, "TDLSChswitchProhibit"); 1105 dut->ap_tdls_prohibit_chswitch = 1106 val && strcasecmp(val, "Enabled") == 0; 1107 val = get_param(cmd, "HS2"); 1108 if (val && wlan_tag == 1) 1109 dut->ap_hs2 = atoi(val); 1110 val = get_param(cmd, "P2P_CROSS_CONNECT"); 1111 if (val) 1112 dut->ap_p2p_cross_connect = strcasecmp(val, "Enabled") == 0; 1113 1114 val = get_param(cmd, "FakePubKey"); 1115 dut->ap_fake_pkhash = val && atoi(val); 1116 1117 val = get_param(cmd, "vht_tkip"); 1118 dut->ap_allow_vht_tkip = val && strcasecmp(val, "Enable") == 0; 1119 val = get_param(cmd, "vht_wep"); 1120 dut->ap_allow_vht_wep = val && strcasecmp(val, "Enable") == 0; 1121 1122 val = get_param(cmd, "Protect_mode"); 1123 dut->ap_disable_protection = val && strcasecmp(val, "Disable") == 0; 1124 1125 val = get_param(cmd, "DYN_BW_SGNL"); 1126 if (val) { 1127 switch (get_driver_type(dut)) { 1128 case DRIVER_OPENWRT: 1129 switch (get_openwrt_driver_type()) { 1130 case OPENWRT_DRIVER_ATHEROS: 1131 ath_config_dyn_bw_sig(dut, ifname, val); 1132 break; 1133 default: 1134 send_resp(dut, conn, SIGMA_ERROR, 1135 "errorCode,Unsupported DYN_BW_SGNL with OpenWrt driver"); 1136 return STATUS_SENT; 1137 } 1138 break; 1139 case DRIVER_WCN: 1140 case DRIVER_LINUX_WCN: 1141 ath_config_dyn_bw_sig(dut, ifname, val); 1142 break; 1143 default: 1144 sigma_dut_print(dut, DUT_MSG_ERROR, 1145 "Unsupported DYN_BW_SGL with the current driver"); 1146 break; 1147 } 1148 } 1149 1150 val = get_param(cmd, "SGI80"); 1151 if (val) { 1152 if (strcasecmp(val, "enable") == 0) 1153 dut->ap_sgi80 = 1; 1154 else if (strcasecmp(val, "disable") == 0) 1155 dut->ap_sgi80 = 0; 1156 else { 1157 send_resp(dut, conn, SIGMA_INVALID, 1158 "errorCode,Unsupported SGI80"); 1159 return STATUS_SENT; 1160 } 1161 } 1162 1163 val = get_param(cmd, "LDPC"); 1164 if (val) { 1165 if (strcasecmp(val, "enable") == 0) 1166 dut->ap_ldpc = VALUE_ENABLED; 1167 else if (strcasecmp(val, "disable") == 0) 1168 dut->ap_ldpc = VALUE_DISABLED; 1169 else { 1170 send_resp(dut, conn, SIGMA_INVALID, 1171 "errorCode,Unsupported LDPC"); 1172 return STATUS_SENT; 1173 } 1174 switch (get_driver_type(dut)) { 1175 case DRIVER_WCN: 1176 case DRIVER_LINUX_WCN: 1177 wcn_config_ap_ldpc(dut, ifname); 1178 break; 1179 default: 1180 break; 1181 } 1182 } 1183 1184 val = get_param(cmd, "BW_SGNL"); 1185 if (val) { 1186 /* 1187 * With dynamic bandwidth signaling enabled we should see 1188 * RTS if the threshold is met. 1189 */ 1190 if (strcasecmp(val, "enable") == 0) { 1191 dut->ap_sig_rts = VALUE_ENABLED; 1192 } else if (strcasecmp(val, "disable") == 0) { 1193 dut->ap_sig_rts = VALUE_DISABLED; 1194 } else { 1195 send_resp(dut, conn, SIGMA_INVALID, 1196 "errorCode,Unsupported BW_SGNL"); 1197 return STATUS_SENT; 1198 } 1199 } 1200 1201 val = get_param(cmd, "RTS_FORCE"); 1202 if (val) { 1203 switch (get_driver_type(dut)) { 1204 case DRIVER_OPENWRT: 1205 switch (get_openwrt_driver_type()) { 1206 case OPENWRT_DRIVER_ATHEROS: 1207 ath_config_rts_force(dut, ifname, val); 1208 break; 1209 default: 1210 send_resp(dut, conn, SIGMA_ERROR, 1211 "errorCode,Unsupported RTS_FORCE with OpenWrt driver"); 1212 return STATUS_SENT; 1213 } 1214 break; 1215 case DRIVER_MAC80211: 1216 mac80211_config_rts_force(dut, ifname, val); 1217 break; 1218 default: 1219 sigma_dut_print(dut, DUT_MSG_ERROR, 1220 "Unsupported RTS_FORCE with the current driver"); 1221 break; 1222 } 1223 } 1224 1225 val = get_param(cmd, "Zero_crc"); 1226 if (val) { 1227 switch (get_driver_type(dut)) { 1228 case DRIVER_ATHEROS: 1229 ath_set_zero_crc(dut, val); 1230 break; 1231 case DRIVER_OPENWRT: 1232 switch (get_openwrt_driver_type()) { 1233 case OPENWRT_DRIVER_ATHEROS: 1234 ath_set_zero_crc(dut, val); 1235 break; 1236 default: 1237 send_resp(dut, conn, SIGMA_ERROR, 1238 "errorCode,Unsupported zero_crc with the current driver"); 1239 return STATUS_SENT; 1240 } 1241 break; 1242 default: 1243 send_resp(dut, conn, SIGMA_ERROR, 1244 "errorCode,Unsupported zero_crc with the current driver"); 1245 return STATUS_SENT; 1246 } 1247 } 1248 1249 val = get_param(cmd, "TxBF"); 1250 if (val) { 1251 dut->ap_txBF = strcasecmp(val, "enable") == 0; 1252 dut->he_sounding = VALUE_DISABLED; 1253 dut->he_set_sta_1x1 = VALUE_ENABLED; 1254 } 1255 1256 val = get_param(cmd, "MU_TxBF"); 1257 if (val) { 1258 if (strcasecmp(val, "enable") == 0) { 1259 dut->ap_txBF = 1; 1260 dut->ap_mu_txBF = 1; 1261 dut->he_sounding = VALUE_DISABLED; 1262 } else if (strcasecmp(val, "disable") == 0) { 1263 dut->ap_txBF = 0; 1264 dut->ap_mu_txBF = 0; 1265 } else { 1266 sigma_dut_print(dut, DUT_MSG_ERROR, 1267 "Unsupported MU_TxBF"); 1268 } 1269 } 1270 1271 /* UNSUPPORTED: tx_lgi_rate */ 1272 1273 val = get_param(cmd, "wpsnfc"); 1274 if (val) 1275 dut->ap_wpsnfc = atoi(val); 1276 1277 val = get_param(cmd, "GROUP_ID"); 1278 if (val) { 1279 switch (get_driver_type(dut)) { 1280 case DRIVER_OPENWRT: 1281 switch (get_openwrt_driver_type()) { 1282 case OPENWRT_DRIVER_ATHEROS: 1283 ath_ap_set_group_id(dut, ifname, val); 1284 break; 1285 default: 1286 send_resp(dut, conn, SIGMA_ERROR, 1287 "errorCode,Unsupported group_id with the current driver"); 1288 return STATUS_SENT; 1289 } 1290 break; 1291 default: 1292 send_resp(dut, conn, SIGMA_ERROR, 1293 "errorCode,Unsupported group_id with the current driver"); 1294 return STATUS_SENT; 1295 } 1296 } 1297 1298 val = get_param(cmd, "CTS_WIDTH"); 1299 if (val) { 1300 switch (get_driver_type(dut)) { 1301 case DRIVER_OPENWRT: 1302 switch (get_openwrt_driver_type()) { 1303 case OPENWRT_DRIVER_ATHEROS: 1304 ath_set_cts_width(dut, ifname, val); 1305 break; 1306 default: 1307 send_resp(dut, conn, SIGMA_ERROR, 1308 "errorCode,Unsupported cts_width with the current driver"); 1309 return STATUS_SENT; 1310 } 1311 break; 1312 default: 1313 send_resp(dut, conn, SIGMA_ERROR, 1314 "errorCode,Unsupported cts_width with the current driver"); 1315 return STATUS_SENT; 1316 } 1317 } 1318 1319 val = get_param(cmd, "MU_NDPA_FrameFormat"); 1320 if (val) 1321 dut->ap_ndpa_frame = atoi(val); 1322 1323 val = get_param(cmd, "interworking"); 1324 if (val && strcmp(val, "1") == 0) 1325 dut->ap_interworking = 1; 1326 1327 val = get_param(cmd, "GAS_CB_DELAY"); 1328 if (val) 1329 dut->ap_gas_cb_delay = atoi(val); 1330 1331 val = get_param(cmd, "LCI"); 1332 if (val) { 1333 if (strlen(val) > sizeof(dut->ap_val_lci) - 1) 1334 return INVALID_SEND_STATUS; 1335 dut->ap_lci = 1; 1336 snprintf(dut->ap_val_lci, sizeof(dut->ap_val_lci), "%s", val); 1337 ath_set_lci_config(dut, val, cmd); 1338 } 1339 1340 val = get_param(cmd, "InfoZ"); 1341 if (val) { 1342 if (strlen(val) > sizeof(dut->ap_infoz) - 1) 1343 return INVALID_SEND_STATUS; 1344 snprintf(dut->ap_infoz, sizeof(dut->ap_infoz), "%s", val); 1345 } 1346 1347 val = get_param(cmd, "LocCivicAddr"); 1348 if (val) { 1349 if (strlen(val) > sizeof(dut->ap_val_lcr) - 1) 1350 return INVALID_SEND_STATUS; 1351 dut->ap_lcr = 1; 1352 snprintf(dut->ap_val_lcr, sizeof(dut->ap_val_lcr), "%s", val); 1353 if (dut->ap_lci == 0) 1354 ath_set_lci_config(dut, val, cmd); 1355 } 1356 1357 val = get_param(cmd, "NeighAPBSSID"); 1358 if (val) { 1359 if (dut->ap_neighap < 3) { 1360 if (parse_mac_address( 1361 dut, val, 1362 dut->ap_val_neighap[dut->ap_neighap]) < 0) { 1363 send_resp(dut, conn, SIGMA_INVALID, 1364 "Failed to parse MAC address"); 1365 return STATUS_SENT; 1366 } 1367 dut->ap_neighap++; 1368 if (dut->ap_lci == 1) 1369 dut->ap_scan = 1; 1370 } 1371 } 1372 1373 val = get_param(cmd, "OpChannel"); 1374 if (val) { 1375 if (dut->ap_opchannel < 3) { 1376 dut->ap_val_opchannel[dut->ap_opchannel] = atoi(val); 1377 dut->ap_opchannel++; 1378 } 1379 } 1380 1381 val = get_param(cmd, "URI-FQDNdescriptor"); 1382 if (val) { 1383 if (strcasecmp(val, "HELD") == 0) { 1384 dut->ap_fqdn_held = 1; 1385 } else if (strcasecmp(val, "SUPL") == 0) { 1386 dut->ap_fqdn_supl = 1; 1387 } else { 1388 send_resp(dut, conn, SIGMA_INVALID, 1389 "errorCode,Unsupported URI-FQDNdescriptor"); 1390 return STATUS_SENT; 1391 } 1392 } 1393 1394 val = get_param(cmd, "Reg_Domain"); 1395 if (val) { 1396 if (strcasecmp(val, "Local") == 0) { 1397 dut->ap_reg_domain = REG_DOMAIN_LOCAL; 1398 } else if (strcasecmp(val, "Global") == 0) { 1399 dut->ap_reg_domain = REG_DOMAIN_GLOBAL; 1400 } else { 1401 send_resp(dut, conn, SIGMA_ERROR, 1402 "errorCode,Wrong value for Reg_Domain"); 1403 return STATUS_SENT; 1404 } 1405 } 1406 1407 val = get_param(cmd, "NAME"); 1408 if (val) { 1409 if (strcasecmp(val, "ap1mbo") == 0) 1410 dut->ap_name = 1; 1411 else if (strcasecmp(val, "ap2mbo") == 0) 1412 dut->ap_name = 2; 1413 else 1414 dut->ap_name = 0; 1415 } 1416 1417 val = get_param(cmd, "FT_OA"); 1418 if (val) { 1419 if (strcasecmp(val, "Enable") == 0) { 1420 dut->ap_ft_oa = 1; 1421 } else if (strcasecmp(val, "Disable") == 0) { 1422 dut->ap_ft_oa = 0; 1423 } else { 1424 send_resp(dut, conn, SIGMA_ERROR, 1425 "errorCode,Wrong value for FT_OA"); 1426 return STATUS_SENT; 1427 } 1428 } 1429 1430 val = get_param(cmd, "FT_DS"); 1431 if (val) { 1432 if (strcasecmp(val, "Enable") == 0) { 1433 dut->ap_ft_ds = VALUE_ENABLED; 1434 } else if (strcasecmp(val, "Disable") == 0) { 1435 dut->ap_ft_ds = VALUE_DISABLED; 1436 } else { 1437 send_resp(dut, conn, SIGMA_ERROR, 1438 "errorCode,Unsupported value for FT_DS"); 1439 return STATUS_SENT_ERROR; 1440 } 1441 } 1442 1443 val = get_param(cmd, "Cellular_Cap_Pref"); 1444 if (val) 1445 dut->ap_cell_cap_pref = atoi(val); 1446 1447 val = get_param(cmd, "DOMAIN"); 1448 if (val) { 1449 if (strlen(val) >= sizeof(dut->ap_mobility_domain)) { 1450 send_resp(dut, conn, SIGMA_ERROR, 1451 "errorCode,Too long DOMAIN"); 1452 return STATUS_SENT; 1453 } 1454 snprintf(dut->ap_mobility_domain, 1455 sizeof(dut->ap_mobility_domain), "%s", val); 1456 } 1457 1458 val = get_param(cmd, "ft_bss_list"); 1459 if (val) { 1460 char *mac_str; 1461 int i; 1462 char *saveptr; 1463 char *mac_list_str; 1464 1465 mac_list_str = strdup(val); 1466 if (!mac_list_str) 1467 return INVALID_SEND_STATUS; 1468 mac_str = strtok_r(mac_list_str, " ", &saveptr); 1469 for (i = 0; mac_str && i < MAX_FT_BSS_LIST; i++) { 1470 if (parse_mac_address(dut, mac_str, 1471 dut->ft_bss_mac_list[i]) < 0) { 1472 sigma_dut_print(dut, DUT_MSG_ERROR, 1473 "MAC Address not in proper format"); 1474 break; 1475 } 1476 dut->ft_bss_mac_cnt++; 1477 mac_str = strtok_r(NULL, " ", &saveptr); 1478 } 1479 sigma_dut_print(dut, DUT_MSG_DEBUG, 1480 "Storing the following FT BSS MAC List"); 1481 for (i = 0; i < dut->ft_bss_mac_cnt; i++) { 1482 sigma_dut_print(dut, DUT_MSG_DEBUG, 1483 "MAC[%d] %02x:%02x:%02x:%02x:%02x:%02x", 1484 i, 1485 dut->ft_bss_mac_list[i][0], 1486 dut->ft_bss_mac_list[i][1], 1487 dut->ft_bss_mac_list[i][2], 1488 dut->ft_bss_mac_list[i][3], 1489 dut->ft_bss_mac_list[i][4], 1490 dut->ft_bss_mac_list[i][5]); 1491 } 1492 free(mac_list_str); 1493 } 1494 1495 val = get_param(cmd, "OCESupport"); 1496 if (val) { 1497 if (strcasecmp(val, "enable") == 0) { 1498 dut->ap_oce = VALUE_ENABLED; 1499 } else if (strcasecmp(val, "disable") == 0) { 1500 dut->ap_oce = VALUE_DISABLED; 1501 dut->ap_filsdscv = VALUE_DISABLED; 1502 } else { 1503 send_resp(dut, conn, SIGMA_INVALID, 1504 "errorCode,Unsupported OCE"); 1505 return STATUS_SENT; 1506 } 1507 } 1508 1509 val = get_param(cmd, "FILSDscvInterval"); 1510 if (val) 1511 dut->ap_fils_dscv_int = atoi(val); 1512 1513 val = get_param(cmd, "BroadcastSSID"); 1514 if (val) { 1515 if (strcasecmp(val, "enable") == 0) { 1516 dut->ap_broadcast_ssid = VALUE_ENABLED; 1517 } else if (strcasecmp(val, "disable") == 0) { 1518 dut->ap_broadcast_ssid = VALUE_DISABLED; 1519 } else { 1520 send_resp(dut, conn, SIGMA_INVALID, 1521 "errorCode,Unsupported hidden SSID"); 1522 return STATUS_SENT; 1523 } 1524 } 1525 1526 val = get_param(cmd, "FILSDscv"); 1527 if (val) { 1528 if (strcasecmp(val, "enable") == 0) { 1529 dut->ap_filsdscv = VALUE_ENABLED; 1530 } else if (strcasecmp(val, "disable") == 0) { 1531 dut->ap_filsdscv = VALUE_DISABLED; 1532 } else { 1533 send_resp(dut, conn, SIGMA_INVALID, 1534 "errorCode,Unsupported FILSDscv"); 1535 return STATUS_SENT; 1536 } 1537 } 1538 1539 val = get_param(cmd, "FILSHLP"); 1540 if (val) { 1541 if (strcasecmp(val, "enable") == 0) { 1542 dut->ap_filshlp = VALUE_ENABLED; 1543 } else if (strcasecmp(val, "disable") == 0) { 1544 dut->ap_filshlp = VALUE_DISABLED; 1545 } else { 1546 send_resp(dut, conn, SIGMA_INVALID, 1547 "errorCode,Unsupported FILSHLP"); 1548 return STATUS_SENT; 1549 } 1550 } 1551 1552 val = get_param(cmd, "NAIRealm"); 1553 if (val) { 1554 dut->ap_nairealm_int = 1; 1555 if (strlen(val) > sizeof(dut->ap_nairealm) - 1) 1556 return INVALID_SEND_STATUS; 1557 snprintf(dut->ap_nairealm, sizeof(dut->ap_nairealm), "%s", val); 1558 } 1559 1560 val = get_param(cmd, "DeauthDisassocTx"); 1561 if (val) { 1562 if (strcasecmp(val, "disable") == 0) { 1563 deauth_disassoc(dut, ifname, val); 1564 } else { 1565 send_resp(dut, conn, SIGMA_INVALID, 1566 "errorCode,Unsupported DeauthDisassocTx"); 1567 return STATUS_SENT; 1568 } 1569 } 1570 1571 val = get_param(cmd, "RNR"); 1572 if (val) { 1573 if (strcasecmp(val, "enable") == 0) { 1574 dut->ap_rnr = VALUE_ENABLED; 1575 } else if (strcasecmp(val, "disable") == 0) { 1576 dut->ap_rnr = VALUE_DISABLED; 1577 } else { 1578 send_resp(dut, conn, SIGMA_INVALID, 1579 "errorCode,Unsupported RNR"); 1580 return STATUS_SENT; 1581 } 1582 } 1583 1584 val = get_param(cmd, "BLEChannelUtil"); 1585 if (val) 1586 dut->ap_blechanutil = atoi(val); 1587 1588 val = get_param(cmd, "BLEAvailAdminCap"); 1589 if (val) 1590 dut->ap_ble_admit_cap = atoi(val); 1591 1592 val = get_param(cmd, "DataPPDUDuration"); 1593 if (val) 1594 dut->ap_datappdudura = atoi(val); 1595 1596 val = get_param(cmd, "AirTimeFract"); 1597 if (val) 1598 dut->ap_airtimefract = atoi(val); 1599 1600 val = get_param(cmd, "dhcpServIPADDR"); 1601 if (val) { 1602 if (strlen(val) > sizeof(dut->ap_dhcpserv_ipaddr) - 1) 1603 return INVALID_SEND_STATUS; 1604 snprintf(dut->ap_dhcpserv_ipaddr, 1605 sizeof(dut->ap_dhcpserv_ipaddr), "%s", val); 1606 dut->ap_dhcp_stop = 1; 1607 } 1608 1609 val = get_param(cmd, "ESP_IE"); 1610 if (val) { 1611 if (strcasecmp(val, "enable") == 0) { 1612 dut->ap_esp = VALUE_ENABLED; 1613 } else if (strcasecmp(val, "disable") == 0) { 1614 dut->ap_esp = VALUE_DISABLED; 1615 } else { 1616 send_resp(dut, conn, SIGMA_INVALID, 1617 "errorCode,Unsupported ESP_IE"); 1618 return STATUS_SENT; 1619 } 1620 } 1621 1622 val = get_param(cmd, "BAWinSize"); 1623 if (val) 1624 dut->ap_bawinsize = atoi(val); 1625 1626 val = get_param(cmd, "BLEStaCount"); 1627 if (val) 1628 dut->ap_blestacnt = atoi(val); 1629 1630 val = get_param(cmd, "PPDUTxType"); 1631 if (val) { 1632 if (strcasecmp(val, "MU") == 0) { 1633 dut->ap_he_ppdu = PPDU_MU; 1634 } else if (strcasecmp(val, "HE-SU") == 0) { 1635 /* Do nothing */ 1636 } else if (strcasecmp(val, "SU") == 0) { 1637 /* Do nothing */ 1638 } else if (strcasecmp(val, "legacy") == 0) { 1639 /* Do nothing */ 1640 } else if (strcasecmp(val, "ER") == 0) { 1641 /* Do nothing */ 1642 } else if (strcasecmp(val, "TB") == 0) { 1643 /* Do nothing */ 1644 } else { 1645 send_resp(dut, conn, SIGMA_ERROR, 1646 "errorCode,Unsupported PPDUTxType"); 1647 return STATUS_SENT_ERROR; 1648 } 1649 } 1650 1651 val = get_param(cmd, "WscIEFragment"); 1652 if (val && strcasecmp(val, "enable") == 0) { 1653 sigma_dut_print(dut, DUT_MSG_DEBUG, 1654 "Enable WSC IE fragmentation"); 1655 dut->wsc_fragment = 1; 1656 } 1657 1658 val = get_param(cmd, "WpsVersion"); 1659 if (val) 1660 dut->wps_forced_version = get_wps_forced_version(dut, val); 1661 1662 val = get_param(cmd, "WscEAPFragment"); 1663 if (val && strcasecmp(val, "enable") == 0) 1664 dut->eap_fragment = 1; 1665 1666 val = get_param(cmd, "MSDUSize"); 1667 if (val) { 1668 int mtu; 1669 1670 dut->amsdu_size = atoi(val); 1671 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG || 1672 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) { 1673 sigma_dut_print(dut, DUT_MSG_ERROR, 1674 "MSDUSize %d is above max %d or below min %d", 1675 dut->amsdu_size, 1676 IEEE80211_MAX_DATA_LEN_DMG, 1677 IEEE80211_SNAP_LEN_DMG); 1678 dut->amsdu_size = 0; 1679 return ERROR_SEND_STATUS; 1680 } 1681 1682 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG; 1683 sigma_dut_print(dut, DUT_MSG_DEBUG, 1684 "Setting amsdu_size to %d", mtu); 1685 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d", 1686 get_station_ifname(dut), mtu); 1687 1688 if (system(buf) != 0) { 1689 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s", 1690 buf); 1691 return ERROR_SEND_STATUS; 1692 } 1693 } 1694 1695 val = get_param(cmd, "BAckRcvBuf"); 1696 if (val) { 1697 dut->back_rcv_buf = atoi(val); 1698 if (dut->back_rcv_buf == 0) { 1699 sigma_dut_print(dut, DUT_MSG_ERROR, 1700 "Failed to convert %s or value is 0", 1701 val); 1702 return ERROR_SEND_STATUS; 1703 } 1704 1705 sigma_dut_print(dut, DUT_MSG_DEBUG, 1706 "Setting BAckRcvBuf to %s", val); 1707 } 1708 1709 val = get_param(cmd, "ExtSchIE"); 1710 if (val && !strcasecmp(val, "Enable")) { 1711 int num_allocs = MAX_ESE_ALLOCS; 1712 1713 if (sta_extract_60g_ese(dut, cmd, dut->ap_ese_allocs, 1714 &num_allocs)) { 1715 send_resp(dut, conn, SIGMA_INVALID, 1716 "errorCode,Invalid ExtSchIE"); 1717 return STATUS_SENT; 1718 } 1719 dut->ap_num_ese_allocs = num_allocs; 1720 } 1721 1722 if (is_60g_sigma_dut(dut)) { 1723 unsigned int abft_len = 1; /* default is one slot */ 1724 1725 val = get_param(cmd, "ABFTLRang"); 1726 if (val) { 1727 sigma_dut_print(dut, DUT_MSG_DEBUG, 1728 "ABFTLRang parameter %s", val); 1729 if (strcasecmp(val, "Gt1") == 0) 1730 abft_len = 2; /* 2 slots in this case */ 1731 } 1732 1733 if (sta_set_60g_abft_len(dut, conn, abft_len)) { 1734 send_resp(dut, conn, SIGMA_ERROR, 1735 "ErrorCode,Can't set ABFT length"); 1736 return STATUS_SENT; 1737 } 1738 } 1739 1740 val = get_param(cmd, "OFDMA"); 1741 if (val) { 1742 if (strcasecmp(val, "UL") == 0) { 1743 dut->ap_he_ulofdma = VALUE_ENABLED; 1744 } else if (strcasecmp(val, "DL") == 0) { 1745 dut->ap_he_dlofdma = VALUE_ENABLED; 1746 } else if (strcasecmp(val, "DL-20and80") == 0) { 1747 dut->ap_he_dlofdma = VALUE_ENABLED; 1748 } else { 1749 send_resp(dut, conn, SIGMA_ERROR, 1750 "errorCode,Unsupported OFDMA value"); 1751 return STATUS_SENT_ERROR; 1752 } 1753 } 1754 1755 val = get_param(cmd, "NumSoundDim"); 1756 if (val) 1757 dut->ap_numsounddim = atoi(val); 1758 1759 val = get_param(cmd, "BCC"); 1760 if (val) { 1761 if (strcasecmp(val, "enable") == 0) { 1762 dut->ap_bcc = VALUE_ENABLED; 1763 dut->ap_ldpc = VALUE_DISABLED; 1764 } else if (strcasecmp(val, "disable") == 0) { 1765 dut->ap_ldpc = VALUE_ENABLED; 1766 dut->ap_bcc = VALUE_DISABLED; 1767 } else { 1768 send_resp(dut, conn, SIGMA_ERROR, 1769 "errorCode,Unsupported BCC value"); 1770 return STATUS_SENT_ERROR; 1771 } 1772 switch (get_driver_type(dut)) { 1773 case DRIVER_WCN: 1774 case DRIVER_LINUX_WCN: 1775 wcn_config_ap_ldpc(dut, ifname); 1776 break; 1777 default: 1778 break; 1779 } 1780 } 1781 1782 val = get_param(cmd, "FrgmntSupport"); 1783 if (val) { 1784 if (strcasecmp(val, "enable") == 0) { 1785 dut->ap_he_frag = VALUE_ENABLED; 1786 } else if (strcasecmp(val, "disable") == 0) { 1787 dut->ap_he_frag = VALUE_DISABLED; 1788 } else { 1789 send_resp(dut, conn, SIGMA_ERROR, 1790 "errorCode,Unsupported FrgmntSupport value"); 1791 return STATUS_SENT_ERROR; 1792 } 1793 } 1794 1795 val = get_param(cmd, "ADDBAReq_BufSize"); 1796 if (val) { 1797 if (strcasecmp(val, "le64") == 0) { 1798 dut->ap_ba_bufsize = BA_BUFSIZE_64; 1799 } else if (strcasecmp(val, "gt64") == 0) { 1800 dut->ap_ba_bufsize = BA_BUFSIZE_256; 1801 } else { 1802 send_resp(dut, conn, SIGMA_ERROR, 1803 "errorCode,Unsupported ADDBAReq Buffer Size"); 1804 return STATUS_SENT_ERROR; 1805 } 1806 } 1807 1808 val = get_param(cmd, "ADDBAResp_BufSize"); 1809 if (val) { 1810 if (strcasecmp(val, "gt64") == 0) { 1811 dut->ap_ba_bufsize = BA_BUFSIZE_256; 1812 } else { 1813 send_resp(dut, conn, SIGMA_ERROR, 1814 "errorCode,Unsupported ADDBAResp Buffer Size"); 1815 return STATUS_SENT_ERROR; 1816 } 1817 } 1818 1819 val = get_param(cmd, "MU_EDCA"); 1820 if (val) { 1821 if (strcasecmp(val, "override") == 0) { 1822 dut->ap_mu_edca = VALUE_ENABLED; 1823 } else if (strcasecmp(val, "disable") == 0) { 1824 dut->ap_mu_edca = VALUE_DISABLED; 1825 } else { 1826 send_resp(dut, conn, SIGMA_ERROR, 1827 "errorCode,Unsupported mu_edca param value"); 1828 return STATUS_SENT_ERROR; 1829 } 1830 } 1831 1832 val = get_param(cmd, "MIMO"); 1833 if (val) { 1834 if (strcasecmp(val, "DL") == 0) { 1835 dut->ap_he_mimo = MIMO_DL; 1836 dut->he_sounding = VALUE_DISABLED; 1837 } else if (strcasecmp(val, "UL") == 0) { 1838 dut->ap_he_mimo = MIMO_UL; 1839 } else { 1840 send_resp(dut, conn, SIGMA_ERROR, 1841 "errorCode,Unsupported mimo param value"); 1842 return STATUS_SENT_ERROR; 1843 } 1844 } 1845 1846 val = get_param(cmd, "HE_TXOPDurRTSThr"); 1847 if (val) { 1848 if (strcasecmp(val, "enable") == 0) { 1849 dut->ap_he_rtsthrshld = VALUE_ENABLED; 1850 } else if (strcasecmp(val, "disable") == 0) { 1851 dut->ap_he_rtsthrshld = VALUE_DISABLED; 1852 } else { 1853 send_resp(dut, conn, SIGMA_ERROR, 1854 "errorCode,Unsupported HE_TXOPDurRTSThr value"); 1855 return STATUS_SENT_ERROR; 1856 } 1857 } 1858 1859 val = get_param(cmd, "MBSSID"); 1860 if (val) { 1861 if (strcasecmp(val, "enable") == 0) { 1862 dut->ap_mbssid = VALUE_ENABLED; 1863 } else if (strcasecmp(val, "disable") == 0) { 1864 dut->ap_mbssid = VALUE_DISABLED; 1865 } else { 1866 send_resp(dut, conn, SIGMA_ERROR, 1867 "errorCode,Unsupported MBSSID Value"); 1868 return STATUS_SENT_ERROR; 1869 } 1870 } 1871 1872 val = get_param(cmd, "TWT_RespSupport"); 1873 if (val) { 1874 if (strcasecmp(val, "enable") == 0) { 1875 dut->ap_twtresp = VALUE_ENABLED; 1876 } else if (strcasecmp(val, "disable") == 0) { 1877 dut->ap_twtresp = VALUE_DISABLED; 1878 } else { 1879 send_resp(dut, conn, SIGMA_ERROR, 1880 "errorCode,Unsupported TWT_RespSupport value"); 1881 return STATUS_SENT_ERROR; 1882 } 1883 } 1884 1885 val = get_param(cmd, "MinMPDUStartSpacing"); 1886 if (val) 1887 dut->he_mmss = atoi(val); 1888 1889 val = get_param(cmd, "SRCtrl_SRValue15Allowed"); 1890 if (val) 1891 dut->he_srctrl_allow = atoi(val); 1892 1893 val = get_param(cmd, "ocvc"); 1894 if (val) 1895 dut->ap_ocvc = atoi(val); 1896 1897 return SUCCESS_SEND_STATUS; 1898 } 1899 1900 1901 static void ath_inject_frame(struct sigma_dut *dut, const char *ifname, int tid) 1902 { 1903 char buf[256]; 1904 int tid_to_dscp[] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 }; 1905 1906 if (tid < 0 || 1907 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) { 1908 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid); 1909 return; 1910 } 1911 1912 snprintf(buf, sizeof(buf), 1913 "wlanconfig %s list sta | grep : | cut -b 1-17 > %s", 1914 ifname, VI_QOS_TMP_FILE); 1915 if (system(buf) != 0) 1916 return; 1917 1918 snprintf(buf, sizeof(buf), 1919 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s", 1920 ifname, VI_QOS_TMP_FILE); 1921 if (system(buf) != 0) 1922 sigma_dut_print(dut, DUT_MSG_ERROR, "Retrieve HWaddr failed"); 1923 1924 snprintf(buf, sizeof(buf), "sed -n '3,$p' %s >> %s", 1925 VI_QOS_REFFILE, VI_QOS_TMP_FILE); 1926 if (system(buf) != 0) { 1927 sigma_dut_print(dut, DUT_MSG_ERROR, 1928 "Output redirection to VI_QOS_TMP_FILE failed"); 1929 } 1930 1931 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s", 1932 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE); 1933 if (system(buf) != 0) { 1934 sigma_dut_print(dut, DUT_MSG_ERROR, 1935 "Append TID to VI_QOS_FILE failed "); 1936 } 1937 1938 snprintf(buf, sizeof(buf), "ethinject %s %s", ifname, VI_QOS_FILE); 1939 if (system(buf) != 0) 1940 sigma_dut_print(dut, DUT_MSG_ERROR, "Ethinject frame failed"); 1941 } 1942 1943 1944 static int ath_ap_send_addba_req(struct sigma_dut *dut, struct sigma_conn *conn, 1945 struct sigma_cmd *cmd) 1946 { 1947 const char *val; 1948 const char *ifname; 1949 char buf[256]; 1950 int tid = 0; 1951 1952 ifname = get_main_ifname(dut); 1953 val = get_param(cmd, "TID"); 1954 if (val) { 1955 tid = atoi(val); 1956 if (tid) 1957 ath_inject_frame(dut, ifname, tid); 1958 } 1959 1960 /* NOTE: This is the command sequence on Peregrine for ADDBA */ 1961 run_iwpriv(dut, ifname, "setaddbaoper 1"); 1962 1963 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", 1964 ifname, tid); 1965 if (system(buf) != 0) { 1966 sigma_dut_print(dut, DUT_MSG_ERROR, 1967 "wifitool senddelba failed"); 1968 } 1969 1970 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", 1971 ifname, tid); 1972 if (system(buf) != 0) { 1973 sigma_dut_print(dut, DUT_MSG_ERROR, 1974 "wifitool sendaddba failed"); 1975 } 1976 1977 return 1; 1978 } 1979 1980 1981 static int ath10k_debug_enable_addba_req(struct sigma_dut *dut, int tid, 1982 const char *sta_mac, 1983 const char *dir_path) 1984 { 1985 DIR *dir; 1986 struct dirent *entry; 1987 char buf[128], path[128]; 1988 int ret = 0, res; 1989 1990 dir = opendir(dir_path); 1991 if (!dir) 1992 return 0; 1993 1994 while ((entry = readdir(dir))) { 1995 ret = 1; 1996 1997 if (strcmp(entry->d_name, ".") == 0 || 1998 strcmp(entry->d_name, "..") == 0) 1999 continue; 2000 2001 res = snprintf(path, sizeof(path) - 1, "%s/%s", 2002 dir_path, entry->d_name); 2003 if (res < 0 || res >= sizeof(path)) 2004 continue; 2005 2006 if (strcmp(entry->d_name, sta_mac) == 0) { 2007 res = snprintf(buf, sizeof(buf), 2008 "echo 1 > %s/aggr_mode", path); 2009 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 2010 sigma_dut_print(dut, DUT_MSG_ERROR, 2011 "Failed to set aggr mode for ath10k"); 2012 } 2013 2014 res = snprintf(buf, sizeof(buf), 2015 "echo %d 32 > %s/addba", tid, path); 2016 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) { 2017 sigma_dut_print(dut, DUT_MSG_ERROR, 2018 "Failed to set addbareq for ath10k"); 2019 } 2020 2021 break; 2022 } 2023 2024 /* Recursively search subdirectories */ 2025 ath10k_debug_enable_addba_req(dut, tid, sta_mac, path); 2026 } 2027 2028 closedir(dir); 2029 2030 return ret; 2031 } 2032 2033 2034 static int ath10k_ap_send_addba_req(struct sigma_dut *dut, 2035 struct sigma_cmd *cmd) 2036 { 2037 const char *val; 2038 int tid = 0; 2039 2040 val = get_param(cmd, "TID"); 2041 if (val) 2042 tid = atoi(val); 2043 2044 val = get_param(cmd, "sta_mac_address"); 2045 if (!val) { 2046 sigma_dut_print(dut, DUT_MSG_ERROR, 2047 "Failed to parse station MAC address"); 2048 return 0; 2049 } 2050 2051 return ath10k_debug_enable_addba_req(dut, tid, val, 2052 "/sys/kernel/debug/ieee80211"); 2053 } 2054 2055 2056 static enum sigma_cmd_result cmd_ap_send_addba_req(struct sigma_dut *dut, 2057 struct sigma_conn *conn, 2058 struct sigma_cmd *cmd) 2059 { 2060 /* const char *name = get_param(cmd, "NAME"); */ 2061 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 2062 struct stat s; 2063 2064 switch (get_driver_type(dut)) { 2065 case DRIVER_ATHEROS: 2066 return ath_ap_send_addba_req(dut, conn, cmd); 2067 #ifdef __linux__ 2068 case DRIVER_WIL6210: 2069 return send_addba_60g(dut, conn, cmd, "sta_mac_address"); 2070 #endif /* __linux__ */ 2071 case DRIVER_OPENWRT: 2072 switch (get_openwrt_driver_type()) { 2073 case OPENWRT_DRIVER_ATHEROS: 2074 return ath_ap_send_addba_req(dut, conn, cmd); 2075 default: 2076 send_resp(dut, conn, SIGMA_ERROR, 2077 "errorCode,ap_send_addba_req not supported with this driver"); 2078 return 0; 2079 } 2080 case DRIVER_WCN: 2081 case DRIVER_LINUX_WCN: 2082 /* AP automatically sends ADDBA request after association. */ 2083 sigma_dut_print(dut, DUT_MSG_INFO, 2084 "ap_send_addba_req command ignored"); 2085 return 1; 2086 case DRIVER_MAC80211: 2087 if (stat("/sys/module/ath10k_core", &s) == 0) 2088 return ath10k_ap_send_addba_req(dut, cmd); 2089 /* fall through */ 2090 default: 2091 send_resp(dut, conn, SIGMA_ERROR, 2092 "errorCode,ap_send_addba_req not supported with this driver"); 2093 return 0; 2094 } 2095 } 2096 2097 2098 static enum sigma_cmd_result cmd_ap_set_security(struct sigma_dut *dut, 2099 struct sigma_conn *conn, 2100 struct sigma_cmd *cmd) 2101 { 2102 /* const char *name = get_param(cmd, "NAME"); */ 2103 const char *val; 2104 unsigned int wlan_tag = 1; 2105 const char *security; 2106 2107 val = get_param(cmd, "WLAN_TAG"); 2108 if (val) 2109 wlan_tag = atoi(val); 2110 2111 security = get_param(cmd, "Security"); 2112 2113 if (wlan_tag > 1) { 2114 val = get_param(cmd, "KEYMGNT"); 2115 if (!val) 2116 val = get_param(cmd, "KeyMgmtType"); 2117 if (val) { 2118 if (strcasecmp(val, "NONE") == 0) { 2119 dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OPEN; 2120 } else if (strcasecmp(val, "OSEN") == 0 && 2121 wlan_tag == 2) { 2122 /* 2123 * OSEN only supported on WLAN_TAG = 2 for now 2124 */ 2125 dut->ap_tag_key_mgmt[wlan_tag - 2] = AP2_OSEN; 2126 } else if (strcasecmp(val, "WPA2-PSK") == 0 || 2127 (security && 2128 strcasecmp(security, "PSK") == 0 && 2129 strcasecmp(val, "WPA2") == 0)) { 2130 dut->ap_tag_key_mgmt[wlan_tag - 2] = 2131 AP2_WPA2_PSK; 2132 } else if (strcasecmp(val, "OWE") == 0 && 2133 wlan_tag == 2) { 2134 dut->ap_tag_key_mgmt[wlan_tag - 2] = 2135 AP2_WPA2_OWE; 2136 } else { 2137 send_resp(dut, conn, SIGMA_INVALID, 2138 "errorCode,Unsupported KEYMGNT"); 2139 return 0; 2140 } 2141 return 1; 2142 } 2143 } 2144 2145 val = get_param(cmd, "KEYMGNT"); 2146 if (!val) 2147 val = get_param(cmd,"KeyMgmtType"); 2148 if (val) { 2149 if (strcasecmp(val, "WPA2-PSK") == 0 || 2150 (security && strcasecmp(security, "PSK") == 0 && 2151 strcasecmp(val, "WPA2") == 0)) { 2152 dut->ap_key_mgmt = AP_WPA2_PSK; 2153 dut->ap_cipher = AP_CCMP; 2154 } else if (strcasecmp(val, "WPA2-EAP") == 0 || 2155 strcasecmp(val, "WPA2-Ent") == 0) { 2156 dut->ap_key_mgmt = AP_WPA2_EAP; 2157 dut->ap_cipher = AP_CCMP; 2158 } else if (strcasecmp(val, "SuiteB") == 0) { 2159 dut->ap_key_mgmt = AP_SUITEB; 2160 dut->ap_cipher = AP_GCMP_256; 2161 dut->ap_pmf = AP_PMF_REQUIRED; 2162 } else if (strcasecmp(val, "WPA-PSK") == 0) { 2163 dut->ap_key_mgmt = AP_WPA_PSK; 2164 dut->ap_cipher = AP_TKIP; 2165 } else if (strcasecmp(val, "WPA-EAP") == 0 || 2166 strcasecmp(val, "WPA-Ent") == 0) { 2167 dut->ap_key_mgmt = AP_WPA_EAP; 2168 dut->ap_cipher = AP_TKIP; 2169 } else if (strcasecmp(val, "WPA2-Mixed") == 0) { 2170 dut->ap_key_mgmt = AP_WPA2_EAP_MIXED; 2171 dut->ap_cipher = AP_CCMP_TKIP; 2172 } else if (strcasecmp(val, "WPA2-PSK-Mixed") == 0) { 2173 dut->ap_key_mgmt = AP_WPA2_PSK_MIXED; 2174 dut->ap_cipher = AP_CCMP_TKIP; 2175 } else if (strcasecmp(val, "WPA2-SAE") == 0 || 2176 strcasecmp(val, "SAE") == 0) { 2177 dut->ap_key_mgmt = AP_WPA2_SAE; 2178 dut->ap_cipher = AP_CCMP; 2179 dut->ap_pmf = AP_PMF_REQUIRED; 2180 } else if (strcasecmp(val, "WPA2-PSK-SAE") == 0) { 2181 dut->ap_key_mgmt = AP_WPA2_PSK_SAE; 2182 dut->ap_cipher = AP_CCMP; 2183 dut->ap_pmf = AP_PMF_OPTIONAL; 2184 } else if (strcasecmp(val, "OWE") == 0) { 2185 dut->ap_key_mgmt = AP_WPA2_OWE; 2186 dut->ap_cipher = AP_CCMP; 2187 dut->ap_pmf = AP_PMF_REQUIRED; 2188 } else if (strcasecmp(val, "WPA2-ENT-OSEN") == 0) { 2189 dut->ap_key_mgmt = AP_WPA2_EAP_OSEN; 2190 dut->ap_cipher = AP_CCMP; 2191 dut->ap_pmf = AP_PMF_OPTIONAL; 2192 } else if (strcasecmp(val, "OSEN") == 0) { 2193 dut->ap_key_mgmt = AP_OSEN; 2194 dut->ap_cipher = AP_CCMP; 2195 } else if (strcasecmp(val, "FT-EAP") == 0) { 2196 dut->ap_key_mgmt = AP_WPA2_FT_EAP; 2197 dut->ap_cipher = AP_CCMP; 2198 dut->ap_pmf = AP_PMF_OPTIONAL; 2199 } else if (strcasecmp(val, "FT-PSK") == 0) { 2200 dut->ap_key_mgmt = AP_WPA2_FT_PSK; 2201 dut->ap_cipher = AP_CCMP; 2202 dut->ap_pmf = AP_PMF_OPTIONAL; 2203 } else if (strcasecmp(val, "WPA2-ENT-256") == 0) { 2204 dut->ap_key_mgmt = AP_WPA2_EAP_SHA256; 2205 dut->ap_cipher = AP_CCMP; 2206 dut->ap_pmf = AP_PMF_OPTIONAL; 2207 } else if (strcasecmp(val, "WPA2-PSK-256") == 0) { 2208 dut->ap_key_mgmt = AP_WPA2_PSK_SHA256; 2209 dut->ap_cipher = AP_CCMP; 2210 dut->ap_pmf = AP_PMF_OPTIONAL; 2211 } else if (strcasecmp(val, "WPA2-ENT-FT-EAP") == 0) { 2212 dut->ap_key_mgmt = AP_WPA2_ENT_FT_EAP; 2213 dut->ap_cipher = AP_CCMP; 2214 dut->ap_pmf = AP_PMF_OPTIONAL; 2215 } else if (strcasecmp(val, "NONE") == 0) { 2216 dut->ap_key_mgmt = AP_OPEN; 2217 dut->ap_cipher = AP_PLAIN; 2218 } else { 2219 send_resp(dut, conn, SIGMA_INVALID, 2220 "errorCode,Unsupported KEYMGNT"); 2221 return 0; 2222 } 2223 } 2224 2225 val = get_param(cmd, "ECGroupID"); 2226 if (val) { 2227 free(dut->ap_sae_groups); 2228 dut->ap_sae_groups = strdup(val); 2229 } 2230 2231 val = get_param(cmd, "AntiCloggingThreshold"); 2232 if (val) 2233 dut->sae_anti_clogging_threshold = atoi(val); 2234 2235 val = get_param(cmd, "Reflection"); 2236 if (val) 2237 dut->sae_reflection = strcasecmp(val, "SAE") == 0; 2238 2239 val = get_param(cmd, "InvalidSAEElement"); 2240 if (val) { 2241 free(dut->sae_commit_override); 2242 dut->sae_commit_override = strdup(val); 2243 } 2244 2245 val = get_param(cmd, "SAEPasswords"); 2246 if (val) { 2247 free(dut->ap_sae_passwords); 2248 dut->ap_sae_passwords = strdup(val); 2249 } 2250 2251 val = get_param(cmd, "SAE_Confirm_Immediate"); 2252 if (val) 2253 dut->sae_confirm_immediate = get_enable_disable(val); 2254 2255 val = get_param(cmd, "sae_pwe"); 2256 if (val) { 2257 if (strcasecmp(val, "h2e") == 0) { 2258 dut->sae_pwe = SAE_PWE_H2E; 2259 } else if (strcasecmp(val, "loop") == 0 || 2260 strcasecmp(val, "looping") == 0) { 2261 dut->sae_pwe = SAE_PWE_LOOP; 2262 } else { 2263 send_resp(dut, conn, SIGMA_ERROR, 2264 "errorCode,Unsupported sae_pwe value"); 2265 return STATUS_SENT_ERROR; 2266 } 2267 } 2268 2269 val = get_param(cmd, "RSNXE_Content"); 2270 if (val) { 2271 if (strncasecmp(val, "EapolM3:", 8) != 0) { 2272 send_resp(dut, conn, SIGMA_ERROR, 2273 "errorCode,Unsupported RSNXE_Content value"); 2274 return STATUS_SENT_ERROR; 2275 } 2276 val += 8; 2277 free(dut->rsnxe_override_eapol); 2278 dut->rsnxe_override_eapol = strdup(val); 2279 } 2280 2281 val = get_param(cmd, "ENCRYPT"); 2282 if (!val) 2283 val = get_param(cmd, "EncpType"); 2284 if (val) { 2285 if (strcasecmp(val, "WEP") == 0) { 2286 dut->ap_cipher = AP_WEP; 2287 } else if (strcasecmp(val, "TKIP") == 0) { 2288 dut->ap_cipher = AP_TKIP; 2289 } else if (strcasecmp(val, "AES") == 0 || 2290 strcasecmp(val, "AES-CCMP") == 0) { 2291 dut->ap_cipher = AP_CCMP; 2292 } else if (strcasecmp(val, "AES-GCMP") == 0) { 2293 dut->ap_cipher = AP_GCMP_128; 2294 } else { 2295 send_resp(dut, conn, SIGMA_INVALID, 2296 "errorCode,Unsupported ENCRYPT"); 2297 return 0; 2298 } 2299 } 2300 2301 val = get_param(cmd, "PairwiseCipher"); 2302 if (val) { 2303 if (strcasecmp(val, "AES-GCMP-256") == 0) { 2304 dut->ap_cipher = AP_GCMP_256; 2305 } else if (strcasecmp(val, "AES-CCMP-256") == 0) { 2306 dut->ap_cipher = AP_CCMP_256; 2307 } else if (strcasecmp(val, "AES-GCMP-128") == 0) { 2308 dut->ap_cipher = AP_GCMP_128; 2309 } else if (strcasecmp(val, "AES-CCMP-128") == 0) { 2310 dut->ap_cipher = AP_CCMP; 2311 } else if (strcasecmp(val, "AES-CCMP-128 AES-GCMP-256") == 0 || 2312 strcasecmp(val, "AES-GCMP-256 AES-CCMP-128") == 0) { 2313 dut->ap_cipher = AP_CCMP_128_GCMP_256; 2314 } else { 2315 send_resp(dut, conn, SIGMA_INVALID, 2316 "errorCode,Unsupported PairwiseCipher"); 2317 return 0; 2318 } 2319 } 2320 2321 val = get_param(cmd, "GroupCipher"); 2322 if (val) { 2323 if (strcasecmp(val, "AES-GCMP-256") == 0) { 2324 dut->ap_group_cipher = AP_GCMP_256; 2325 } else if (strcasecmp(val, "AES-CCMP-256") == 0) { 2326 dut->ap_group_cipher = AP_CCMP_256; 2327 } else if (strcasecmp(val, "AES-GCMP-128") == 0) { 2328 dut->ap_group_cipher = AP_GCMP_128; 2329 } else if (strcasecmp(val, "AES-CCMP-128") == 0) { 2330 dut->ap_group_cipher = AP_CCMP; 2331 } else { 2332 send_resp(dut, conn, SIGMA_INVALID, 2333 "errorCode,Unsupported GroupCipher"); 2334 return 0; 2335 } 2336 } 2337 2338 val = get_param(cmd, "GroupMgntCipher"); 2339 if (val) { 2340 if (strcasecmp(val, "BIP-GMAC-256") == 0) { 2341 dut->ap_group_mgmt_cipher = AP_BIP_GMAC_256; 2342 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) { 2343 dut->ap_group_mgmt_cipher = AP_BIP_CMAC_256; 2344 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) { 2345 dut->ap_group_mgmt_cipher = AP_BIP_GMAC_128; 2346 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) { 2347 dut->ap_group_mgmt_cipher = AP_BIP_CMAC_128; 2348 } else { 2349 send_resp(dut, conn, SIGMA_INVALID, 2350 "errorCode,Unsupported GroupMgntCipher"); 2351 return 0; 2352 } 2353 } 2354 2355 val = get_param(cmd, "WEPKEY"); 2356 if (val) { 2357 size_t len; 2358 if (dut->ap_cipher != AP_WEP) { 2359 send_resp(dut, conn, SIGMA_INVALID, 2360 "errorCode,Unexpected WEPKEY without WEP " 2361 "configuration"); 2362 return 0; 2363 } 2364 len = strlen(val); 2365 if (len != 10 && len != 26) { 2366 send_resp(dut, conn, SIGMA_INVALID, 2367 "errorCode,Unexpected WEPKEY length"); 2368 return 0; 2369 } 2370 snprintf(dut->ap_wepkey, sizeof(dut->ap_wepkey), "%s", val); 2371 } 2372 2373 val = get_param(cmd, "PSK"); 2374 if (!val) 2375 val = get_param(cmd, "passphrase"); 2376 if (val) { 2377 if (dut->ap_key_mgmt != AP_WPA2_SAE && 2378 (dut->ap_akm_values & (AKM_WPA_PSK | AKM_SAE)) != 2379 AKM_SAE && 2380 strlen(val) > 64) { 2381 sigma_dut_print(dut, DUT_MSG_ERROR, 2382 "Too long PSK/passphtase"); 2383 return -1; 2384 } 2385 if (strlen(val) > sizeof(dut->ap_passphrase) - 1) 2386 return -1; 2387 snprintf(dut->ap_passphrase, sizeof(dut->ap_passphrase), 2388 "%s", val); 2389 } 2390 2391 val = get_param(cmd, "PSKHEX"); 2392 if (val) { 2393 if (strlen(val) != 64) 2394 return -1; 2395 strlcpy(dut->ap_psk, val, sizeof(dut->ap_psk)); 2396 } 2397 2398 if (dut->program == PROGRAM_OCE && dut->dev_role == DEVROLE_STA_CFON) 2399 dut->ap_pmf = AP_PMF_OPTIONAL; 2400 2401 val = get_param(cmd, "PMF"); 2402 if (val) { 2403 if (strcasecmp(val, "Disabled") == 0) { 2404 dut->ap_pmf = AP_PMF_DISABLED; 2405 } else if (strcasecmp(val, "Optional") == 0) { 2406 dut->ap_pmf = AP_PMF_OPTIONAL; 2407 } else if (strcasecmp(val, "Required") == 0) { 2408 dut->ap_pmf = AP_PMF_REQUIRED; 2409 } else { 2410 send_resp(dut, conn, SIGMA_INVALID, 2411 "errorCode,Unsupported PMF"); 2412 return 0; 2413 } 2414 } 2415 2416 dut->ap_add_sha256 = 0; 2417 val = get_param(cmd, "SHA256AD"); 2418 if (val == NULL) 2419 val = get_param(cmd, "SHA256"); 2420 if (val) { 2421 if (strcasecmp(val, "Disabled") == 0) { 2422 } else if (strcasecmp(val, "Enabled") == 0) { 2423 dut->ap_add_sha256 = 1; 2424 } else { 2425 send_resp(dut, conn, SIGMA_INVALID, 2426 "errorCode,Unsupported SHA256"); 2427 return 0; 2428 } 2429 } 2430 2431 val = get_param(cmd, "PreAuthentication"); 2432 if (val) { 2433 if (strcasecmp(val, "disabled") == 0) { 2434 dut->ap_rsn_preauth = 0; 2435 } else if (strcasecmp(val, "enabled") == 0) { 2436 dut->ap_rsn_preauth = 1; 2437 } else { 2438 send_resp(dut, conn, SIGMA_INVALID, 2439 "errorCode,Unsupported PreAuthentication value"); 2440 return 0; 2441 } 2442 } 2443 2444 val = get_param(cmd, "AKMSuiteType"); 2445 if (val) { 2446 const char *in_pos = val; 2447 2448 dut->ap_akm_values = 0; 2449 while (*in_pos) { 2450 int akm = atoi(in_pos); 2451 2452 if (akm < 0 || akm >= 32) { 2453 send_resp(dut, conn, SIGMA_ERROR, 2454 "errorCode,Unsupported AKMSuiteType value"); 2455 return STATUS_SENT; 2456 } 2457 2458 dut->ap_akm_values |= 1 << akm; 2459 2460 in_pos = strchr(in_pos, ';'); 2461 if (!in_pos) 2462 break; 2463 while (*in_pos == ';') 2464 in_pos++; 2465 } 2466 dut->ap_akm = 1; 2467 if (dut->ap_akm_values & (1 << 14)) 2468 dut->ap_add_sha384 = 1; 2469 if (dut->ap_akm_values & (1 << 15)) 2470 dut->ap_add_sha384 = 1; 2471 } 2472 2473 if (dut->ap_key_mgmt == AP_OPEN && !dut->ap_akm_values) { 2474 dut->ap_hs2 = 0; 2475 dut->ap_pmf = AP_PMF_DISABLED; 2476 } 2477 2478 val = get_param(cmd, "PMKSACaching"); 2479 if (val) { 2480 dut->ap_pmksa = 1; 2481 if (strcasecmp(val, "disabled") == 0) { 2482 dut->ap_pmksa_caching = 1; 2483 } else if (strcasecmp(val, "enabled") == 0) { 2484 dut->ap_pmksa_caching = 0; 2485 } else { 2486 send_resp(dut, conn, SIGMA_INVALID, 2487 "errorCode,Unsupported PMKSACaching value"); 2488 return 0; 2489 } 2490 } 2491 2492 val = get_param(cmd, "BeaconProtection"); 2493 if (val) 2494 dut->ap_beacon_prot = atoi(val); 2495 2496 val = get_param(cmd, "Transition_Disable"); 2497 if (val) { 2498 if (atoi(val)) { 2499 val = get_param(cmd, "Transition_Disable_Index"); 2500 if (!val) { 2501 send_resp(dut, conn, SIGMA_INVALID, 2502 "errorCode,Transition_Disable without Transition_Disable_Index"); 2503 return STATUS_SENT; 2504 } 2505 dut->ap_transition_disable = 1 << atoi(val); 2506 } else { 2507 dut->ap_transition_disable = 0; 2508 } 2509 } 2510 2511 return 1; 2512 } 2513 2514 2515 int sta_cfon_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn, 2516 struct sigma_cmd *cmd) 2517 { 2518 int status; 2519 2520 status = cmd_ap_set_wireless(dut, conn, cmd); 2521 if (status != 1) 2522 return status; 2523 status = cmd_ap_set_security(dut, conn, cmd); 2524 if (status != 1) 2525 return status; 2526 return cmd_ap_config_commit(dut, conn, cmd); 2527 } 2528 2529 2530 static enum sigma_cmd_result cmd_ap_set_radius(struct sigma_dut *dut, 2531 struct sigma_conn *conn, 2532 struct sigma_cmd *cmd) 2533 { 2534 /* const char *name = get_param(cmd, "NAME"); */ 2535 const char *val; 2536 unsigned int wlan_tag = 1, radius_port = 0; 2537 char *radius_ipaddr = NULL, *radius_password = NULL; 2538 2539 val = get_param(cmd, "WLAN_TAG"); 2540 if (val) { 2541 wlan_tag = atoi(val); 2542 if (wlan_tag != 1 && wlan_tag != 2) { 2543 send_resp(dut, conn, SIGMA_INVALID, 2544 "errorCode,Invalid WLAN_TAG"); 2545 return 0; 2546 } 2547 } 2548 2549 val = get_param(cmd, "PORT"); 2550 if (val) 2551 radius_port = atoi(val); 2552 2553 if (wlan_tag == 1) { 2554 if (radius_port) 2555 dut->ap_radius_port = radius_port; 2556 radius_ipaddr = dut->ap_radius_ipaddr; 2557 radius_password = dut->ap_radius_password; 2558 } else if (wlan_tag == 2) { 2559 if (radius_port) 2560 dut->ap2_radius_port = radius_port; 2561 radius_ipaddr = dut->ap2_radius_ipaddr; 2562 radius_password = dut->ap2_radius_password; 2563 } 2564 2565 val = get_param(cmd, "IPADDR"); 2566 if (val) { 2567 if (strlen(val) > sizeof(dut->ap_radius_ipaddr) - 1) 2568 return -1; 2569 snprintf(radius_ipaddr, sizeof(dut->ap_radius_ipaddr), 2570 "%s", val); 2571 } 2572 2573 val = get_param(cmd, "PASSWORD"); 2574 if (val) { 2575 if (strlen(val) > sizeof(dut->ap_radius_password) - 1) 2576 return -1; 2577 snprintf(radius_password, 2578 sizeof(dut->ap_radius_password), "%s", val); 2579 } 2580 2581 return 1; 2582 } 2583 2584 2585 static void owrt_ap_set_qcawifi(struct sigma_dut *dut, const char *key, 2586 const char *val) 2587 { 2588 if (!val) { 2589 run_system_wrapper(dut, "uci delete wireless.qcawifi.%s", key); 2590 return; 2591 } 2592 2593 run_system(dut, "uci set wireless.qcawifi=qcawifi"); 2594 run_system_wrapper(dut, "uci set wireless.qcawifi.%s=%s", key, val); 2595 } 2596 2597 2598 static void owrt_ap_set_radio(struct sigma_dut *dut, int id, 2599 const char *key, const char *val) 2600 { 2601 char buf[100]; 2602 2603 if (val == NULL) { 2604 snprintf(buf, sizeof(buf), 2605 "uci delete wireless.wifi%d.%s", id, key); 2606 run_system(dut, buf); 2607 return; 2608 } 2609 2610 snprintf(buf, sizeof(buf), "uci set wireless.wifi%d.%s=%s", 2611 id, key, val); 2612 run_system(dut, buf); 2613 } 2614 2615 2616 static void owrt_ap_set_list_radio(struct sigma_dut *dut, int id, 2617 const char *key, const char *val) 2618 { 2619 char buf[256]; 2620 2621 if (val == NULL) { 2622 snprintf(buf, sizeof(buf), 2623 "uci del_list wireless.wifi%d.%s", id, key); 2624 run_system(dut, buf); 2625 return; 2626 } 2627 2628 snprintf(buf, sizeof(buf), "uci add_list wireless.wifi%d.%s=%s", 2629 id, key, val); 2630 run_system(dut, buf); 2631 } 2632 2633 2634 static void owrt_ap_set_vap(struct sigma_dut *dut, int id, const char *key, 2635 const char *val) 2636 { 2637 char buf[256]; 2638 2639 if (val == NULL) { 2640 snprintf(buf, sizeof(buf), 2641 "uci delete wireless.@wifi-iface[%d].%s", id, key); 2642 run_system(dut, buf); 2643 return; 2644 } 2645 2646 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2647 id, key, val); 2648 run_system(dut, buf); 2649 } 2650 2651 2652 static void owrt_ap_set_list_vap(struct sigma_dut *dut, int id, 2653 const char *key, const char *val) 2654 { 2655 char buf[1024]; 2656 2657 if (val == NULL) { 2658 snprintf(buf, sizeof(buf), 2659 "uci del_list wireless.@wifi-iface[%d].%s", id, key); 2660 run_system(dut, buf); 2661 return; 2662 } 2663 2664 snprintf(buf, sizeof(buf), 2665 "uci add_list wireless.@wifi-iface[%d].%s=%s", 2666 id, key, val); 2667 run_system(dut, buf); 2668 } 2669 2670 2671 static void owrt_ap_add_vap(struct sigma_dut *dut, int id, const char *key, 2672 const char *val) 2673 { 2674 char buf[256]; 2675 int res; 2676 2677 if (val == NULL) { 2678 res = snprintf(buf, sizeof(buf), 2679 "uci delete wireless.@wifi-iface[%d].%s", 2680 id, key); 2681 if (res >= 0 && res < sizeof(buf)) 2682 run_system(dut, buf); 2683 return; 2684 } 2685 2686 run_system(dut, "uci add wireless wifi-iface"); 2687 res = snprintf(buf, sizeof(buf), 2688 "uci set wireless.@wifi-iface[%d].%s=%s", 2689 id, key, val); 2690 if (res >= 0 && res < sizeof(buf)) 2691 run_system(dut, buf); 2692 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2693 id, "network", "lan"); 2694 run_system(dut, buf); 2695 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2696 id, "mode", "ap"); 2697 run_system(dut, buf); 2698 snprintf(buf, sizeof(buf), "uci set wireless.@wifi-iface[%d].%s=%s", 2699 id, "encryption", "none"); 2700 run_system(dut, buf); 2701 } 2702 2703 2704 #define OPENWRT_MAX_NUM_RADIOS (MAX_RADIO + 1) 2705 static int owrt_ap_config_radio(struct sigma_dut *dut) 2706 { 2707 int radio_id[MAX_RADIO] = { 0, 1, 2 }; 2708 int radio_count, radio_no; 2709 char buf[64]; 2710 2711 for (radio_count = 0; radio_count < OPENWRT_MAX_NUM_RADIOS; 2712 radio_count++) { 2713 snprintf(buf, sizeof(buf), "%s%d", "wifi", radio_count); 2714 for (radio_no = 0; radio_no < MAX_RADIO; radio_no++) { 2715 if (!sigma_radio_ifname[radio_no] || 2716 strcmp(sigma_radio_ifname[radio_no], buf) != 0) 2717 continue; 2718 owrt_ap_set_radio(dut, radio_count, "disabled", "0"); 2719 owrt_ap_set_vap(dut, radio_count, "device", buf); 2720 radio_id[radio_no] = radio_count; 2721 } 2722 } 2723 2724 /* Hardware mode (11a/b/g/n/ac) & HT mode selection */ 2725 switch (dut->ap_mode) { 2726 case AP_11g: 2727 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11g"); 2728 break; 2729 case AP_11b: 2730 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11b"); 2731 break; 2732 case AP_11ng: 2733 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng"); 2734 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2735 break; 2736 case AP_11a: 2737 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11a"); 2738 break; 2739 case AP_11na: 2740 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11na"); 2741 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2742 break; 2743 case AP_11ac: 2744 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ac"); 2745 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80"); 2746 break; 2747 case AP_11ax: 2748 if (dut->ap_channel >= 36) { 2749 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axa"); 2750 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80"); 2751 } else { 2752 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11axg"); 2753 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2754 } 2755 break; 2756 case AP_inval: 2757 sigma_dut_print(dut, DUT_MSG_ERROR, 2758 "MODE NOT SPECIFIED!"); 2759 return -1; 2760 default: 2761 owrt_ap_set_radio(dut, radio_id[0], "hwmode", "11ng"); 2762 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2763 break; 2764 } 2765 2766 if (dut->ap_is_dual) { 2767 /* Hardware mode (11a/b/g/n/ac) & HT mode selection */ 2768 switch (dut->ap_mode_1) { 2769 case AP_11g: 2770 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11g"); 2771 break; 2772 case AP_11b: 2773 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11b"); 2774 break; 2775 case AP_11ng: 2776 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng"); 2777 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20"); 2778 break; 2779 case AP_11a: 2780 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11a"); 2781 break; 2782 case AP_11na: 2783 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11na"); 2784 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20"); 2785 break; 2786 case AP_11ac: 2787 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ac"); 2788 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT80"); 2789 break; 2790 case AP_11ax: 2791 if (dut->ap_channel >= 36) { 2792 owrt_ap_set_radio(dut, radio_id[1], 2793 "hwmode", "11axa"); 2794 owrt_ap_set_radio(dut, radio_id[1], 2795 "htmode", "HT80"); 2796 } else { 2797 owrt_ap_set_radio(dut, radio_id[1], 2798 "hwmode", "11axg"); 2799 owrt_ap_set_radio(dut, radio_id[1], 2800 "htmode", "HT20"); 2801 } 2802 break; 2803 case AP_inval: 2804 sigma_dut_print(dut, DUT_MSG_ERROR, 2805 "MODE NOT SPECIFIED!"); 2806 return -1; 2807 default: 2808 owrt_ap_set_radio(dut, radio_id[1], "hwmode", "11ng"); 2809 owrt_ap_set_radio(dut, radio_id[1], "htmode", "HT20"); 2810 break; 2811 } 2812 2813 } 2814 2815 /* Channel */ 2816 snprintf(buf, sizeof(buf), "%d", dut->ap_channel); 2817 owrt_ap_set_radio(dut, radio_id[0], "channel", buf); 2818 2819 switch (dut->ap_chwidth) { 2820 case AP_20: 2821 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT20"); 2822 break; 2823 case AP_40: 2824 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT40"); 2825 break; 2826 case AP_80: 2827 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80"); 2828 break; 2829 case AP_160: 2830 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT160"); 2831 break; 2832 case AP_80_80: 2833 owrt_ap_set_radio(dut, radio_id[0], "htmode", "HT80_80"); 2834 break; 2835 case AP_AUTO: 2836 default: 2837 break; 2838 } 2839 2840 if (dut->ap_channel == 140 || dut->ap_channel == 144) { 2841 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 2842 owrt_ap_set_radio(dut, radio_id[0], "set_ch_144", "3"); 2843 } 2844 2845 if (dut->ap_is_dual) { 2846 snprintf(buf, sizeof(buf), "%d", dut->ap_channel_1); 2847 owrt_ap_set_radio(dut, radio_id[1], "channel", buf); 2848 } 2849 2850 /* Country Code */ 2851 if (dut->ap_reg_domain == REG_DOMAIN_GLOBAL) { 2852 const char *country; 2853 2854 country = dut->ap_countrycode[0] ? dut->ap_countrycode : "US"; 2855 snprintf(buf, sizeof(buf), "%s4", country); 2856 owrt_ap_set_radio(dut, radio_id[0], "country", buf); 2857 if (dut->ap_is_dual) 2858 owrt_ap_set_radio(dut, radio_id[1], "country", buf); 2859 } else if (dut->ap_countrycode[0]) { 2860 owrt_ap_set_radio(dut, radio_id[0], "country", 2861 dut->ap_countrycode); 2862 } 2863 2864 if (dut->ap_disable_protection == 1) { 2865 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'0 0'"); 2866 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'1 0'"); 2867 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'2 0'"); 2868 owrt_ap_set_list_radio(dut, radio_id[0], "aggr_burst", "'3 0'"); 2869 } 2870 2871 if (dut->ap_oce == VALUE_ENABLED && 2872 get_driver_type(dut) == DRIVER_OPENWRT) 2873 owrt_ap_set_radio(dut, radio_id[0], "bcnburst", "1"); 2874 2875 if (dut->ap_mbssid == VALUE_ENABLED) 2876 owrt_ap_set_qcawifi(dut, "mbss_ie_enable", "1"); 2877 2878 if (dut->program == PROGRAM_HE) { 2879 owrt_ap_set_radio(dut, radio_id[0], "he_bsscolor", "'1 1'"); 2880 if (dut->ap_is_dual) 2881 owrt_ap_set_radio(dut, radio_id[1], "he_bsscolor", 2882 "'2 1'"); 2883 owrt_ap_set_qcawifi(dut, "ap_bss_color_collision_detection", 2884 "1"); 2885 } 2886 2887 return 1; 2888 } 2889 2890 2891 static int owrt_ap_config_vap_hs2(struct sigma_dut *dut, int vap_id) 2892 { 2893 char buf[256]; 2894 2895 snprintf(buf, sizeof(buf), "%d", dut->ap_hs2); 2896 owrt_ap_set_vap(dut, vap_id, "hs20", buf); 2897 owrt_ap_set_vap(dut, vap_id, "qbssload", "1"); 2898 owrt_ap_set_vap(dut, vap_id, "hs20_deauth_req_timeout","3"); 2899 2900 owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name", 2901 "'eng:Wi-Fi Alliance'"); 2902 2903 owrt_ap_set_list_vap(dut, vap_id, "hs20_oper_friendly_name", 2904 "'chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f'"); 2905 2906 if (dut->ap_wan_metrics == 1) 2907 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2908 "'01:2500:384:0:0:10'"); 2909 else if (dut->ap_wan_metrics == 1) 2910 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2911 "'01:1500:384:20:20:10'"); 2912 else if (dut->ap_wan_metrics == 2) 2913 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2914 "'01:1500:384:20:20:10'"); 2915 else if (dut->ap_wan_metrics == 3) 2916 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2917 "'01:2000:1000:20:20:10'"); 2918 else if (dut->ap_wan_metrics == 4) 2919 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2920 "'01:8000:1000:20:20:10'"); 2921 else if (dut->ap_wan_metrics == 5) 2922 owrt_ap_set_vap(dut, vap_id, "hs20_wan_metrics", 2923 "'01:9000:5000:20:20:10'"); 2924 2925 if (dut->ap_conn_capab == 1) { 2926 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", "'1:0:0'"); 2927 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2928 "'6:20:1'"); 2929 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2930 "'6:22:0'"); 2931 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2932 "'6:80:1'"); 2933 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2934 "'6:443:1'"); 2935 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2936 "'6:1723:0'"); 2937 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2938 "'6:5060:0'"); 2939 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2940 "'17:500:1'"); 2941 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2942 "'17:5060:0'"); 2943 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2944 "'17:4500:1'"); 2945 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2946 "'50:0:1'"); 2947 } else if (dut->ap_conn_capab == 2) { 2948 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2949 "'6:80:1'"); 2950 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2951 "'6:443:1'"); 2952 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2953 "'17:5060:1'"); 2954 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2955 "'6:5060:1'"); 2956 } else if (dut->ap_conn_capab == 3) { 2957 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2958 "'6:80:1'"); 2959 owrt_ap_set_list_vap(dut, vap_id, "hs20_conn_capab", 2960 "'6:443:1'"); 2961 } 2962 2963 if (dut->ap_oper_class == 1) 2964 snprintf(buf, sizeof(buf), "%s", "51"); 2965 else if (dut->ap_oper_class == 2) 2966 snprintf(buf, sizeof(buf), "%s", "73"); 2967 else if (dut->ap_oper_class == 3) 2968 snprintf(buf, sizeof(buf), "%s", "5173"); 2969 2970 if (dut->ap_oper_class) 2971 owrt_ap_set_vap(dut, vap_id, "hs20_operating_class", buf); 2972 2973 if (dut->ap_osu_provider_list) { 2974 char *osu_friendly_name = NULL; 2975 char *osu_icon = NULL; 2976 char *osu_ssid = NULL; 2977 char *osu_nai = NULL; 2978 char *osu_service_desc = NULL; 2979 char *hs20_icon_filename = NULL; 2980 char hs20_icon[150]; 2981 int osu_method; 2982 2983 hs20_icon_filename = "icon_red_zxx.png"; 2984 if (dut->ap_osu_icon_tag == 2) 2985 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 2986 snprintf(hs20_icon, sizeof(hs20_icon), 2987 "'128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s'", 2988 hs20_icon_filename); 2989 osu_icon = "icon_red_zxx.png"; 2990 osu_ssid = "OSU"; 2991 osu_friendly_name = "'kor:SP 빨강 테스트 전용'"; 2992 osu_service_desc = "'kor:테스트 목적으로 무료 서비스'"; 2993 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : 2994 dut->ap_osu_method[0]; 2995 2996 if (strlen(dut->ap_osu_server_uri[0])) 2997 owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri", 2998 dut->ap_osu_server_uri[0]); 2999 else 3000 owrt_ap_set_list_vap(dut, vap_id, "osu_server_uri", 3001 "'https://osu-server.r2-testbed.wi-fi.org/'"); 3002 switch (dut->ap_osu_provider_list) { 3003 case 1: 3004 case 101: 3005 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3006 "'eng:SP Red Test Only'"); 3007 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3008 "'eng:Free service for test purpose'"); 3009 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3010 hs20_icon); 3011 3012 hs20_icon_filename = "icon_red_eng.png"; 3013 if (dut->ap_osu_icon_tag == 2) 3014 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3015 3016 snprintf(hs20_icon, sizeof(hs20_icon), 3017 "'160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s'", 3018 hs20_icon_filename); 3019 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3020 "icon_red_eng.png"); 3021 break; 3022 case 2: 3023 case 102: 3024 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3025 "'eng:Wireless Broadband Alliance'"); 3026 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3027 "'eng:Free service for test purpose'"); 3028 hs20_icon_filename = "icon_orange_zxx.png"; 3029 if (dut->ap_osu_icon_tag == 2) 3030 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3031 3032 snprintf(hs20_icon, sizeof(hs20_icon), 3033 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3034 hs20_icon_filename); 3035 osu_icon = "icon_orange_zxx.png"; 3036 osu_friendly_name = "'kor:와이어리스 브로드밴드 얼라이언스'"; 3037 break; 3038 case 3: 3039 case 103: 3040 osu_friendly_name = "'spa:SP Red Test Only'"; 3041 osu_service_desc = "'spa:Free service for test purpose'"; 3042 break; 3043 case 4: 3044 case 104: 3045 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3046 "'eng:SP Orange Test Only'"); 3047 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3048 "'eng:Free service for test purpose'"); 3049 hs20_icon_filename = "icon_orange_eng.png"; 3050 if (dut->ap_osu_icon_tag == 2) 3051 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3052 3053 snprintf(hs20_icon, sizeof(hs20_icon), 3054 "'160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s'", 3055 hs20_icon_filename); 3056 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3057 hs20_icon); 3058 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'"; 3059 3060 hs20_icon_filename = "icon_orange_zxx.png"; 3061 if (dut->ap_osu_icon_tag == 2) 3062 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3063 3064 snprintf(hs20_icon, sizeof(hs20_icon), 3065 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3066 hs20_icon_filename); 3067 osu_icon = "icon_orange_zxx.png"; 3068 break; 3069 case 5: 3070 case 105: 3071 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3072 "'eng:SP Orange Test Only'"); 3073 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3074 "'eng:Free service for test purpose'"); 3075 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'"; 3076 3077 hs20_icon_filename = "icon_orange_zxx.png"; 3078 if (dut->ap_osu_icon_tag == 2) 3079 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3080 3081 snprintf(hs20_icon, sizeof(hs20_icon), 3082 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3083 hs20_icon_filename); 3084 osu_icon = "icon_orange_zxx.png"; 3085 break; 3086 case 6: 3087 case 106: 3088 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3089 "'eng:SP Green Test Only'"); 3090 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3091 "'kor:SP 초록 테스트 전용'"); 3092 3093 hs20_icon_filename = "icon_green_zxx.png"; 3094 if (dut->ap_osu_icon_tag == 2) 3095 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3096 3097 snprintf(hs20_icon, sizeof(hs20_icon), 3098 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'", 3099 hs20_icon_filename); 3100 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3101 hs20_icon); 3102 3103 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3104 "'icon_green_zxx.png'"); 3105 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : 3106 dut->ap_osu_method[0]; 3107 3108 snprintf(buf, sizeof(buf), "%d", osu_method); 3109 owrt_ap_set_vap(dut, vap_id, "osu_method_list", buf); 3110 3111 if (strlen(dut->ap_osu_server_uri[1])) 3112 owrt_ap_set_list_vap(dut, vap_id, 3113 "osu_server_uri", 3114 dut->ap_osu_server_uri[1]); 3115 else 3116 owrt_ap_set_list_vap(dut, vap_id, 3117 "osu_server_uri", 3118 "'https://osu-server.r2-testbed.wi-fi.org/'"); 3119 3120 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3121 "'eng:SP Orange Test Only'"); 3122 3123 hs20_icon_filename = "icon_orange_zxx.png"; 3124 if (dut->ap_osu_icon_tag == 2) 3125 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3126 3127 snprintf(hs20_icon, sizeof(hs20_icon), 3128 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3129 hs20_icon_filename); 3130 3131 osu_icon = "icon_orange_zxx.png"; 3132 osu_friendly_name = "'kor:SP 오렌지 테스트 전용'"; 3133 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : 3134 dut->ap_osu_method[1]; 3135 osu_service_desc = NULL; 3136 break; 3137 case 7: 3138 case 107: 3139 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3140 "'eng:SP Green Test Only'"); 3141 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3142 "'eng:Free service for test purpose'"); 3143 3144 hs20_icon_filename = "icon_green_eng.png"; 3145 if (dut->ap_osu_icon_tag == 2) 3146 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3147 3148 snprintf(hs20_icon, sizeof(hs20_icon), 3149 "'160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s'", 3150 hs20_icon_filename); 3151 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", 3152 hs20_icon); 3153 3154 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3155 "'icon_green_eng.png'"); 3156 osu_friendly_name = "'kor:SP 초록 테스트 전용'"; 3157 3158 hs20_icon_filename = "icon_green_zxx.png"; 3159 if (dut->ap_osu_icon_tag == 2) 3160 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3161 3162 snprintf(hs20_icon, sizeof(hs20_icon), 3163 "'128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s'", 3164 hs20_icon_filename); 3165 osu_icon = "icon_green_zxx.png"; 3166 break; 3167 case 8: 3168 case 108: 3169 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3170 "'eng:SP Red Test Only'"); 3171 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3172 "'eng:Free service for test purpose'"); 3173 osu_ssid = "OSU-Encrypted"; 3174 osu_nai = "'anonymous@hotspot.net'"; 3175 break; 3176 case 9: 3177 case 109: 3178 osu_ssid = "OSU-OSEN"; 3179 osu_nai = "'test-anonymous@wi-fi.org'"; 3180 osu_friendly_name = "'eng:SP Orange Test Only'"; 3181 hs20_icon_filename = "icon_orange_zxx.png"; 3182 if (dut->ap_osu_icon_tag == 2) 3183 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 3184 3185 snprintf(hs20_icon, sizeof(hs20_icon), 3186 "'128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s'", 3187 hs20_icon_filename); 3188 osu_icon = "icon_orange_zxx.png"; 3189 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : 3190 dut->ap_osu_method[0]; 3191 osu_service_desc = NULL; 3192 break; 3193 default: 3194 break; 3195 } 3196 3197 if (strlen(dut->ap_osu_ssid)) { 3198 if (dut->ap_tag_ssid[0][0] && 3199 strcmp(dut->ap_tag_ssid[0], 3200 dut->ap_osu_ssid) != 0 && 3201 strcmp(dut->ap_tag_ssid[0], osu_ssid) != 0) { 3202 sigma_dut_print(dut, DUT_MSG_ERROR, 3203 "OSU_SSID and WLAN_TAG2 SSID differ"); 3204 return -2; 3205 } 3206 3207 snprintf(buf, sizeof(buf), "'\"%s\"'", 3208 dut->ap_osu_ssid); 3209 } else { 3210 snprintf(buf, sizeof(buf), "'\"%s\"'", osu_ssid); 3211 } 3212 3213 owrt_ap_set_vap(dut, vap_id, "osu_ssid", buf); 3214 3215 3216 if (osu_friendly_name) 3217 owrt_ap_set_list_vap(dut, vap_id, "osu_friendly_name", 3218 osu_friendly_name); 3219 if (osu_service_desc) 3220 owrt_ap_set_list_vap(dut, vap_id, "osu_service_desc", 3221 osu_service_desc); 3222 if (osu_nai) 3223 owrt_ap_set_vap(dut, vap_id, "osu_nai", osu_nai); 3224 3225 owrt_ap_set_list_vap(dut, vap_id, "hs20_icon", hs20_icon); 3226 3227 if (osu_icon) 3228 owrt_ap_set_list_vap(dut, vap_id, "osu_icon", 3229 osu_icon); 3230 3231 if (dut->ap_osu_provider_list > 100) { 3232 owrt_ap_set_list_vap(dut, vap_id, "osu_method_list", 3233 "0"); 3234 } else { 3235 snprintf(buf, sizeof(buf), "%d", osu_method); 3236 owrt_ap_set_list_vap(dut, vap_id, "osu_method_list", 3237 buf); 3238 } 3239 } 3240 3241 return 0; 3242 } 3243 3244 3245 static int set_anqp_elem_value(struct sigma_dut *dut, const char *ifname, 3246 char *anqp_string, size_t str_size) 3247 { 3248 unsigned char bssid[ETH_ALEN]; 3249 unsigned char dummy_mac[] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50 }; 3250 int preference = 0xff; 3251 3252 if (get_hwaddr(ifname, bssid) < 0) 3253 return -1; 3254 snprintf(anqp_string, str_size, 3255 "272:3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x3410%02x%02x%02x%02x%02x%02xf70000007330000301%02x", 3256 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], 3257 preference, 3258 dummy_mac[0], dummy_mac[1], dummy_mac[2], 3259 dummy_mac[3], dummy_mac[4], dummy_mac[5], 3260 preference - 1); 3261 return 0; 3262 } 3263 3264 3265 static const char * get_hostapd_ifname(struct sigma_dut *dut) 3266 { 3267 enum driver_type drv; 3268 3269 /* Use the configured hostapd ifname */ 3270 if (dut->hostapd_ifname && if_nametoindex(dut->hostapd_ifname) > 0) 3271 return dut->hostapd_ifname; 3272 3273 /* Use configured main ifname */ 3274 if (dut->main_ifname) { 3275 if (dut->use_5g && dut->main_ifname_5g && 3276 if_nametoindex(dut->main_ifname_5g) > 0) 3277 return dut->main_ifname_5g; 3278 if (!dut->use_5g && dut->main_ifname_2g && 3279 if_nametoindex(dut->main_ifname_2g) > 0) 3280 return dut->main_ifname_2g; 3281 if (if_nametoindex(dut->main_ifname) > 0) 3282 return dut->main_ifname; 3283 } 3284 3285 /* Return based on driver type (indirectly started hostapd) */ 3286 drv = get_driver_type(dut); 3287 if (drv == DRIVER_ATHEROS) { 3288 if (dut->use_5g && if_nametoindex("ath1") > 0) 3289 return "ath1"; 3290 return "ath0"; 3291 } 3292 3293 if (drv == DRIVER_OPENWRT) { 3294 if (sigma_radio_ifname[0] && 3295 strcmp(sigma_radio_ifname[0], "wifi2") == 0) 3296 return "ath2"; 3297 if (sigma_radio_ifname[0] && 3298 strcmp(sigma_radio_ifname[0], "wifi1") == 0) 3299 return "ath1"; 3300 return "ath0"; 3301 } 3302 3303 /* wlan1-is-likely-5-GHz design */ 3304 if (dut->use_5g && if_nametoindex("wlan1") > 0) 3305 return "wlan1"; 3306 3307 /* If nothing else matches, hope for the best and guess this is wlan0 */ 3308 return "wlan0"; 3309 } 3310 3311 3312 static void get_if_name(struct sigma_dut *dut, char *ifname_str, 3313 size_t str_size, int wlan_tag) 3314 { 3315 const char *ifname; 3316 enum driver_type drv; 3317 3318 ifname = get_hostapd_ifname(dut); 3319 drv = get_driver_type(dut); 3320 3321 if (drv == DRIVER_OPENWRT && wlan_tag > 1) { 3322 /* Handle tagged-ifname only on OPENWRT for now */ 3323 snprintf(ifname_str, str_size, "%s%d", ifname, wlan_tag - 1); 3324 } else if ((drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) && 3325 wlan_tag == 2) { 3326 snprintf(ifname_str, str_size, "%s_1", ifname); 3327 } else { 3328 snprintf(ifname_str, str_size, "%s", ifname); 3329 } 3330 } 3331 3332 3333 static int sae_pw_id_used(struct sigma_dut *dut) 3334 { 3335 return dut->ap_sae_passwords && 3336 strchr(dut->ap_sae_passwords, ':'); 3337 } 3338 3339 3340 static int owrt_ap_config_vap(struct sigma_dut *dut) 3341 { 3342 char buf[256], *temp; 3343 int vap_id = 0, vap_count, i, j, res; 3344 const char *ifname; 3345 char ifname2[50]; 3346 3347 if (sigma_radio_ifname[0] && 3348 strcmp(sigma_radio_ifname[0], "wifi2") == 0) 3349 ifname = "ath2"; 3350 else if (sigma_radio_ifname[0] && 3351 strcmp(sigma_radio_ifname[0], "wifi1") == 0) 3352 ifname = "ath1"; 3353 else 3354 ifname = "ath0"; 3355 3356 for (vap_count = 0; vap_count < OPENWRT_MAX_NUM_RADIOS; vap_count++) { 3357 snprintf(buf, sizeof(buf), "wifi%d", vap_count); 3358 3359 for (vap_id = 0; vap_id < MAX_RADIO; vap_id++) { 3360 if (sigma_radio_ifname[vap_id] && 3361 strcmp(sigma_radio_ifname[vap_id], buf) == 0) 3362 break; 3363 } 3364 if (vap_id == MAX_RADIO) 3365 continue; 3366 3367 /* Single VAP configuration */ 3368 if (!dut->ap_is_dual) 3369 vap_id = vap_count; 3370 3371 for (j = 0; j < MAX_WLAN_TAGS - 1; j++) { 3372 /* 3373 * We keep a separate array of ap_tag_ssid and 3374 * ap_tag_key_mgmt for tags starting from WLAN_TAG=2. 3375 * So j=0 => WLAN_TAG = 2 3376 */ 3377 int wlan_tag = j + 2; 3378 3379 if (wlan_tag == 2 && dut->program == PROGRAM_WPA3 && 3380 (dut->ap_interface_5g || dut->ap_interface_2g)) { 3381 res = snprintf( 3382 dut->ap_tag_ssid[wlan_tag - 2], 3383 sizeof(dut->ap_tag_ssid[wlan_tag - 2]), 3384 "%s-owe", dut->ap_ssid); 3385 if (res < 0 || 3386 res >= sizeof(dut->ap_tag_ssid[wlan_tag - 3387 2])) 3388 dut->ap_tag_ssid[wlan_tag - 2][0] = 3389 '\0'; 3390 } 3391 3392 if (dut->ap_tag_ssid[j][0] == '\0') 3393 continue; 3394 3395 snprintf(buf, sizeof(buf), "%s%d", "wifi", vap_count); 3396 owrt_ap_add_vap(dut, vap_count + (wlan_tag - 1), 3397 "device", buf); 3398 /* SSID */ 3399 snprintf(buf, sizeof(buf), "\"%s\"", 3400 dut->ap_tag_ssid[j]); 3401 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3402 "ssid", buf); 3403 3404 if (dut->ap_key_mgmt == AP_WPA2_OWE && 3405 dut->ap_tag_ssid[0][0] && 3406 dut->ap_tag_key_mgmt[0] == AP2_OPEN) { 3407 /* OWE transition mode */ 3408 snprintf(buf, sizeof(buf), "%s", ifname); 3409 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3410 "owe_transition_ifname", buf); 3411 } 3412 3413 if (dut->ap_key_mgmt == AP_OPEN && 3414 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 3415 /* OWE transition mode */ 3416 snprintf(buf, sizeof(buf), "%s", ifname); 3417 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3418 "owe_transition_ifname", buf); 3419 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3420 "hidden", "1"); 3421 } 3422 3423 if (ap_ft_enabled(dut)) { 3424 unsigned char self_mac[ETH_ALEN]; 3425 char mac_str[20]; 3426 3427 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3428 "mobility_domain", 3429 dut->ap_mobility_domain); 3430 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3431 "ft_over_ds", 3432 dut->ap_ft_ds == VALUE_ENABLED ? 3433 "1" : "0"); 3434 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3435 "ieee80211r", "1"); 3436 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3437 "nasid", "nas1.example.com"); 3438 if (get_hwaddr(sigma_radio_ifname[0], 3439 self_mac) < 0) 3440 return -1; 3441 snprintf(mac_str, sizeof(mac_str), 3442 "%02x:%02x:%02x:%02x:%02x:%02x", 3443 self_mac[0], self_mac[1], self_mac[2], 3444 self_mac[3], self_mac[4], self_mac[5]); 3445 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3446 "ap_macaddr", mac_str); 3447 snprintf(mac_str, sizeof(mac_str), 3448 "%02x%02x%02x%02x%02x%02x", 3449 self_mac[0], self_mac[1], self_mac[2], 3450 self_mac[3], self_mac[4], self_mac[5]); 3451 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3452 "r1_key_holder", mac_str); 3453 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3454 "ft_psk_generate_local", "1"); 3455 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3456 "kh_key_hex", 3457 "000102030405060708090a0b0c0d0e0f"); 3458 snprintf(mac_str, sizeof(mac_str), 3459 "%02x:%02x:%02x:%02x:%02x:%02x", 3460 dut->ft_bss_mac_list[0][0], 3461 dut->ft_bss_mac_list[0][1], 3462 dut->ft_bss_mac_list[0][2], 3463 dut->ft_bss_mac_list[0][3], 3464 dut->ft_bss_mac_list[0][4], 3465 dut->ft_bss_mac_list[0][5]); 3466 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3467 "ap2_macaddr", mac_str); 3468 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3469 "ap2_r1_key_holder", mac_str); 3470 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3471 "nasid2", "nas2.example.com"); 3472 } 3473 3474 if (dut->ap_tag_key_mgmt[j] == AP2_OSEN && 3475 wlan_tag == 2) { 3476 /* Only supported for WLAN_TAG=2 */ 3477 owrt_ap_set_vap(dut, vap_count + 1, "osen", 3478 "1"); 3479 snprintf(buf, sizeof(buf), "wpa2"); 3480 owrt_ap_set_vap(dut, vap_count + 1, 3481 "encryption", buf); 3482 snprintf(buf, sizeof(buf), "%s", 3483 dut->ap2_radius_ipaddr); 3484 owrt_ap_set_vap(dut, vap_count + 1, 3485 "auth_server", buf); 3486 snprintf(buf, sizeof(buf), "%d", 3487 dut->ap2_radius_port); 3488 owrt_ap_set_vap(dut, vap_count + 1, 3489 "auth_port", buf); 3490 snprintf(buf, sizeof(buf), "%s", 3491 dut->ap2_radius_password); 3492 owrt_ap_set_vap(dut, vap_count + 1, 3493 "auth_secret", buf); 3494 } else if (dut->ap_tag_key_mgmt[j] == AP2_WPA2_PSK) { 3495 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3496 "encryption", "psk2+ccmp"); 3497 snprintf(buf, sizeof(buf), "\"%s\"", 3498 dut->ap_passphrase); 3499 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3500 "key", buf); 3501 snprintf(buf, sizeof(buf), "%d", dut->ap_pmf); 3502 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3503 "ieee80211w", buf); 3504 } else if (dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 3505 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3506 "owe", "1"); 3507 snprintf(buf, sizeof(buf), "ccmp"); 3508 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3509 "encryption", buf); 3510 owrt_ap_set_vap(dut, vap_count + (wlan_tag - 1), 3511 "ieee80211w", "2"); 3512 if (dut->ap_sae_groups) { 3513 snprintf(buf, sizeof(buf), "\'%s\'", 3514 dut->ap_sae_groups); 3515 owrt_ap_set_list_vap(dut, vap_count + 3516 (wlan_tag - 1), 3517 "owe_groups", buf); 3518 if (dut->owe_ptk_workaround) 3519 owrt_ap_set_list_vap( 3520 dut, vap_count + 3521 (wlan_tag - 1), 3522 "owe_ptk_workaround", 3523 "1"); 3524 } 3525 } 3526 } 3527 3528 /* Now set anqp_elem and ft_oa for wlan_tag = 1 */ 3529 if (dut->program == PROGRAM_MBO && 3530 get_driver_type(dut) == DRIVER_OPENWRT) { 3531 unsigned char self_mac[ETH_ALEN]; 3532 char mac_str[20]; 3533 char anqp_string[200]; 3534 3535 if (set_anqp_elem_value(dut, sigma_radio_ifname[0], 3536 anqp_string, 3537 sizeof(anqp_string)) < 0) 3538 return -1; 3539 owrt_ap_set_list_vap(dut, vap_count, "anqp_elem", 3540 anqp_string); 3541 3542 if (ap_ft_enabled(dut)) { 3543 owrt_ap_set_vap(dut, vap_count, 3544 "mobility_domain", 3545 dut->ap_mobility_domain); 3546 owrt_ap_set_vap(dut, vap_count, 3547 "ft_over_ds", 3548 dut->ap_ft_ds == VALUE_ENABLED ? 3549 "1" : "0"); 3550 owrt_ap_set_vap(dut, vap_count, 3551 "ieee80211r", "1"); 3552 owrt_ap_set_vap(dut, vap_count, 3553 "nasid", "nas1.example.com"); 3554 get_hwaddr(sigma_radio_ifname[0], self_mac); 3555 snprintf(mac_str, sizeof(mac_str), 3556 "%02x:%02x:%02x:%02x:%02x:%02x", 3557 self_mac[0], self_mac[1], self_mac[2], 3558 self_mac[3], self_mac[4], self_mac[5]); 3559 owrt_ap_set_vap(dut, vap_count, 3560 "ap_macaddr", mac_str); 3561 snprintf(mac_str, sizeof(mac_str), 3562 "%02x%02x%02x%02x%02x%02x", 3563 self_mac[0], self_mac[1], self_mac[2], 3564 self_mac[3], self_mac[4], self_mac[5]); 3565 owrt_ap_set_vap(dut, vap_count, 3566 "r1_key_holder", mac_str); 3567 owrt_ap_set_vap(dut, vap_count, 3568 "ft_psk_generate_local", "1"); 3569 owrt_ap_set_vap(dut, vap_count, 3570 "kh_key_hex", 3571 "000102030405060708090a0b0c0d0e0f"); 3572 snprintf(mac_str, sizeof(mac_str), 3573 "%02x:%02x:%02x:%02x:%02x:%02x", 3574 dut->ft_bss_mac_list[0][0], 3575 dut->ft_bss_mac_list[0][1], 3576 dut->ft_bss_mac_list[0][2], 3577 dut->ft_bss_mac_list[0][3], 3578 dut->ft_bss_mac_list[0][4], 3579 dut->ft_bss_mac_list[0][5]); 3580 owrt_ap_set_vap(dut, vap_count, 3581 "ap2_macaddr", mac_str); 3582 owrt_ap_set_vap(dut, vap_count, 3583 "ap2_r1_key_holder", mac_str); 3584 owrt_ap_set_vap(dut, vap_count, 3585 "nasid2", "nas2.example.com"); 3586 } 3587 } 3588 3589 if (dut->ap_oce == VALUE_ENABLED && 3590 get_driver_type(dut) == DRIVER_OPENWRT) { 3591 owrt_ap_set_vap(dut, vap_id, "oce", "1"); 3592 owrt_ap_set_vap(dut, vap_id, "qbssload", "1"); 3593 owrt_ap_set_vap(dut, vap_id, "bpr_enable", "1"); 3594 3595 if (dut->ap_80plus80 == 1) 3596 owrt_ap_set_vap(dut, vap_id, "cfreq2", "5775"); 3597 3598 if (dut->ap_akm == 1) { 3599 owrt_ap_set_vap(dut, vap_id, "wpa_group_rekey", 3600 "3600"); 3601 owrt_ap_set_vap(dut, vap_id, "key", "12345678"); 3602 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", 3603 "1"); 3604 owrt_ap_set_vap(dut, vap_id, "fils_cache_id", 3605 "1234"); 3606 owrt_ap_set_vap(dut, vap_id, 3607 "erp_send_reauth_start", "1"); 3608 } 3609 3610 if (dut->ap_filshlp == VALUE_ENABLED) { 3611 struct ifreq ifr; 3612 char *ifname; 3613 int s; 3614 struct sockaddr_in *ipaddr; 3615 3616 s = socket(AF_INET, SOCK_DGRAM, 0); 3617 if (s < 0) { 3618 sigma_dut_print(dut, DUT_MSG_ERROR, 3619 "Failed to open socket"); 3620 return -1; 3621 } 3622 ifr.ifr_addr.sa_family = AF_INET; 3623 3624 memset(&ifr, 0, sizeof(ifr)); 3625 ifname = "br-lan"; 3626 strlcpy(ifr.ifr_name, ifname, 3627 sizeof(ifr.ifr_name)); 3628 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { 3629 perror("ioctl"); 3630 close(s); 3631 return -1; 3632 } 3633 3634 ipaddr = (struct sockaddr_in*)&ifr.ifr_addr; 3635 snprintf(buf, sizeof(buf), "%s", 3636 inet_ntoa(ipaddr->sin_addr)); 3637 owrt_ap_set_vap(dut, vap_id, "own_ip_addr", 3638 buf); 3639 snprintf(buf, sizeof(buf), "%s", 3640 dut->ap_dhcpserv_ipaddr); 3641 owrt_ap_set_vap(dut, vap_id, "dhcp_server", 3642 buf); 3643 owrt_ap_set_vap(dut, vap_id, 3644 "dhcp_rapid_commit_proxy", "1"); 3645 owrt_ap_set_vap(dut, vap_id, 3646 "fils_hlp_wait_time", "300"); 3647 } 3648 3649 if (dut->ap_filsdscv == VALUE_ENABLED) { 3650 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", 3651 "1"); 3652 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", 3653 "20"); 3654 } 3655 } 3656 3657 if (dut->ap_filsdscv == VALUE_DISABLED) { 3658 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", "0"); 3659 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", "0"); 3660 } 3661 3662 if (dut->ap_oce == VALUE_DISABLED && 3663 get_driver_type(dut) == DRIVER_OPENWRT) { 3664 owrt_ap_set_vap(dut, vap_id, "oce", "0"); 3665 owrt_ap_set_vap(dut, vap_id, "qbssload", "0"); 3666 owrt_ap_set_vap(dut, vap_id, "bpr_enable", "0"); 3667 3668 if (dut->ap_filsdscv == VALUE_DISABLED) { 3669 owrt_ap_set_vap(dut, vap_id, "ieee80211ai", 3670 "0"); 3671 owrt_ap_set_vap(dut, vap_id, "fils_fd_period", 3672 "0"); 3673 } 3674 3675 if (dut->device_type == AP_testbed) 3676 owrt_ap_set_vap(dut, vap_id, "mbo", "1"); 3677 } 3678 3679 /* NAIRealm */ 3680 if (dut->ap_nairealm_int == 1) { 3681 snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_nairealm); 3682 owrt_ap_set_vap(dut, vap_id, "fils_realm", buf); 3683 owrt_ap_set_vap(dut, vap_id, "erp_domain", buf); 3684 } 3685 3686 /* SSID */ 3687 snprintf(buf, sizeof(buf), "\"%s\"", dut->ap_ssid); 3688 owrt_ap_set_vap(dut, vap_count, "ssid", buf); 3689 3690 /* Encryption */ 3691 switch (dut->ap_key_mgmt) { 3692 case AP_OPEN: 3693 if (dut->ap_cipher == AP_WEP) { 3694 owrt_ap_set_vap(dut, vap_count, "encryption", 3695 "wep-mixed"); 3696 owrt_ap_set_vap(dut, vap_count, "key", 3697 dut->ap_wepkey); 3698 } else { 3699 owrt_ap_set_vap(dut, vap_count, "encryption", 3700 "none"); 3701 } 3702 if (dut->ap_key_mgmt == AP_OPEN && 3703 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 3704 /* OWE transition mode */ 3705 snprintf(ifname2, sizeof(ifname2), "%s1", 3706 ifname); 3707 owrt_ap_set_vap(dut, vap_count, 3708 "owe_transition_ifname", 3709 ifname2); 3710 } 3711 break; 3712 case AP_WPA2_PSK: 3713 case AP_WPA2_PSK_MIXED: 3714 case AP_WPA_PSK: 3715 case AP_WPA2_SAE: 3716 case AP_WPA2_PSK_SAE: 3717 if (dut->ap_key_mgmt == AP_WPA2_PSK || 3718 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) { 3719 snprintf(buf, sizeof(buf), "psk2"); 3720 } else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) { 3721 snprintf(buf, sizeof(buf), "psk-mixed"); 3722 } else if (dut->ap_key_mgmt == AP_WPA2_SAE) { 3723 snprintf(buf, sizeof(buf), "ccmp"); 3724 } else { 3725 snprintf(buf, sizeof(buf), "psk"); 3726 } 3727 3728 if (dut->ap_key_mgmt != AP_WPA2_SAE) { 3729 if (dut->ap_cipher == AP_CCMP_TKIP) 3730 strlcat(buf, "+ccmp+tkip", sizeof(buf)); 3731 else if (dut->ap_cipher == AP_TKIP) 3732 strlcat(buf, "+tkip", sizeof(buf)); 3733 else if (dut->ap_cipher == AP_GCMP_128) 3734 strlcat(buf, "+gcmp", sizeof(buf)); 3735 else 3736 strlcat(buf, "+ccmp", sizeof(buf)); 3737 } 3738 3739 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3740 3741 if (!dut->ap_passphrase[0] && dut->ap_psk[0]) { 3742 snprintf(buf, sizeof(buf), "\"%s\"", 3743 dut->ap_psk); 3744 owrt_ap_set_vap(dut, vap_count, "key", buf); 3745 } else { 3746 snprintf(buf, sizeof(buf), "\"%s\"", 3747 dut->ap_passphrase); 3748 owrt_ap_set_vap(dut, vap_count, "key", buf); 3749 } 3750 3751 if (dut->ap_key_mgmt == AP_WPA2_SAE || 3752 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 3753 owrt_ap_set_vap(dut, vap_count, "sae", "1"); 3754 else 3755 owrt_ap_set_vap(dut, vap_count, "sae", "0"); 3756 3757 if (dut->ap_key_mgmt == AP_WPA2_SAE) { 3758 snprintf(buf, sizeof(buf), "%s", 3759 dut->ap_passphrase); 3760 owrt_ap_set_vap(dut, vap_count, "sae_password", 3761 buf); 3762 } else { 3763 snprintf(buf, sizeof(buf), "%s", 3764 dut->ap_passphrase); 3765 owrt_ap_set_vap(dut, vap_count, 3766 "wpa_passphrase", buf); 3767 } 3768 break; 3769 case AP_WPA2_EAP: 3770 case AP_WPA2_EAP_MIXED: 3771 case AP_WPA_EAP: 3772 if (dut->ap_key_mgmt == AP_WPA2_EAP) { 3773 snprintf(buf, sizeof(buf), "wpa2"); 3774 } else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) { 3775 snprintf(buf, sizeof(buf), "wpa-mixed"); 3776 } else { 3777 snprintf(buf, sizeof(buf), "wpa"); 3778 } 3779 3780 if (dut->ap_cipher == AP_CCMP_TKIP) 3781 strlcat(buf, "+ccmp+tkip", sizeof(buf)); 3782 else if (dut->ap_cipher == AP_TKIP) 3783 strlcat(buf, "+tkip", sizeof(buf)); 3784 else 3785 strlcat(buf, "+ccmp", sizeof(buf)); 3786 3787 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3788 snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr); 3789 owrt_ap_set_vap(dut, vap_count, "auth_server", buf); 3790 snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port); 3791 owrt_ap_set_vap(dut, vap_count, "auth_port", buf); 3792 snprintf(buf, sizeof(buf), "%s", 3793 dut->ap_radius_password); 3794 owrt_ap_set_vap(dut, vap_count, "auth_secret", buf); 3795 break; 3796 case AP_WPA2_EAP_OSEN: 3797 case AP_OSEN: 3798 case AP_WPA2_FT_EAP: 3799 case AP_WPA2_FT_PSK: 3800 case AP_WPA2_EAP_SHA256: 3801 case AP_WPA2_PSK_SHA256: 3802 case AP_WPA2_ENT_FT_EAP: 3803 /* TODO */ 3804 break; 3805 case AP_SUITEB: 3806 owrt_ap_set_vap(dut, vap_count, "suite_b", "192"); 3807 snprintf(buf, sizeof(buf), "gcmp"); 3808 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3809 snprintf(buf, sizeof(buf), "%s", dut->ap_radius_ipaddr); 3810 owrt_ap_set_vap(dut, vap_count, "auth_server", buf); 3811 snprintf(buf, sizeof(buf), "%d", dut->ap_radius_port); 3812 owrt_ap_set_vap(dut, vap_count, "auth_port", buf); 3813 snprintf(buf, sizeof(buf), "%s", 3814 dut->ap_radius_password); 3815 owrt_ap_set_vap(dut, vap_count, "auth_secret", buf); 3816 snprintf(buf, sizeof(buf), "%d", 3817 dut->ap_group_mgmt_cipher); 3818 owrt_ap_set_vap(dut, vap_count, "group_mgmt_cipher", 3819 buf); 3820 break; 3821 case AP_WPA2_OWE: 3822 owrt_ap_set_vap(dut, vap_count, "owe", "1"); 3823 snprintf(buf, sizeof(buf), "ccmp"); 3824 owrt_ap_set_vap(dut, vap_count, "encryption", buf); 3825 if (dut->ap_sae_groups) { 3826 snprintf(buf, sizeof(buf), "\'%s\'", 3827 dut->ap_sae_groups); 3828 owrt_ap_set_list_vap(dut, vap_count, 3829 "owe_groups", buf); 3830 if (dut->owe_ptk_workaround) 3831 owrt_ap_set_list_vap( 3832 dut, vap_count, 3833 "owe_ptk_workaround", "1"); 3834 } 3835 3836 if (dut->ap_key_mgmt == AP_WPA2_OWE && 3837 dut->ap_tag_ssid[0][0] && 3838 dut->ap_tag_key_mgmt[0] == AP2_OPEN) { 3839 /* OWE transition mode */ 3840 snprintf(ifname2, sizeof(ifname2), "%s1", 3841 ifname); 3842 owrt_ap_set_vap(dut, vap_count, 3843 "owe_transition_ifname", 3844 ifname2); 3845 owrt_ap_set_vap(dut, vap_count, "hidden", "1"); 3846 } 3847 break; 3848 } 3849 3850 if (!dut->ap_is_dual) 3851 break; 3852 } 3853 3854 if (dut->ap_is_dual) 3855 return 1; 3856 3857 /* PMF */ 3858 snprintf(buf, sizeof(buf), "%d", dut->ap_pmf); 3859 owrt_ap_set_vap(dut, vap_id, "ieee80211w", buf); 3860 3861 /* Add SHA256 */ 3862 snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha256); 3863 owrt_ap_set_vap(dut, vap_id, "add_sha256", buf); 3864 3865 /* Add SHA384 for akmsuitetype 15 */ 3866 if (dut->ap_akm == 1) { 3867 snprintf(buf, sizeof(buf), "%d", dut->ap_add_sha384); 3868 owrt_ap_set_vap(dut, vap_id, "add_sha384", buf); 3869 } 3870 3871 /* Enable RSN preauthentication, if asked to */ 3872 snprintf(buf, sizeof(buf), "%d", dut->ap_rsn_preauth); 3873 owrt_ap_set_vap(dut, vap_id, "rsn_preauth", buf); 3874 3875 /* Hotspot 2.0 */ 3876 if (dut->ap_hs2) { 3877 int ret; 3878 3879 ret = owrt_ap_config_vap_hs2(dut, vap_id); 3880 if (ret) 3881 return ret; 3882 } 3883 3884 /* Interworking */ 3885 if (dut->ap_interworking) { 3886 snprintf(buf, sizeof(buf), "%d", dut->ap_access_net_type); 3887 owrt_ap_set_vap(dut, vap_id, "access_network_type", buf); 3888 snprintf(buf, sizeof(buf), "%d", dut->ap_internet); 3889 owrt_ap_set_vap(dut, vap_id, "internet", buf); 3890 snprintf(buf, sizeof(buf), "%d", dut->ap_venue_group); 3891 owrt_ap_set_vap(dut, vap_id, "venue_group", buf); 3892 snprintf(buf, sizeof(buf), "%d", dut->ap_venue_type); 3893 owrt_ap_set_vap(dut, vap_id, "venue_type", buf); 3894 snprintf(buf, sizeof(buf), "%s", dut->ap_hessid); 3895 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 3896 3897 if (dut->ap_gas_cb_delay > 0) { 3898 snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay); 3899 owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf); 3900 } 3901 3902 if (dut->ap_roaming_cons[0]) { 3903 char *rcons, *temp_ptr; 3904 3905 rcons = strdup(dut->ap_roaming_cons); 3906 if (rcons == NULL) 3907 return -1; 3908 3909 temp_ptr = strchr(rcons, ';'); 3910 3911 if (temp_ptr) 3912 *temp_ptr++ = '\0'; 3913 3914 owrt_ap_set_list_vap(dut, vap_id, "roaming_consortium", 3915 rcons); 3916 3917 if (temp_ptr) 3918 owrt_ap_set_list_vap(dut, vap_id, 3919 "roaming_consortium", 3920 temp_ptr); 3921 3922 free(rcons); 3923 } 3924 } 3925 3926 if (dut->ap_venue_name) { 3927 owrt_ap_set_list_vap(dut, vap_id, "venue_name", 3928 "'P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"'"); 3929 owrt_ap_set_list_vap(dut, vap_id, "venue_name", 3930 "\'"ANQP_VENUE_NAME_1_CHI"\'"); 3931 } 3932 3933 if (dut->ap_net_auth_type == 1) { 3934 owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", 3935 "'00https://tandc-server.wi-fi.org'"); 3936 } else if (dut->ap_net_auth_type == 2) { 3937 owrt_ap_set_list_vap(dut, vap_id, "network_auth_type", "'01'"); 3938 } 3939 3940 if (dut->ap_nai_realm_list == 1) { 3941 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3942 "'0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]'"); 3943 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3944 "'0,wi-fi.org;example.com,13[5:6]'"); 3945 3946 } else if (dut->ap_nai_realm_list == 2) { 3947 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3948 "'0,wi-fi.org,21[2:4][5:7]'"); 3949 } else if (dut->ap_nai_realm_list == 3) { 3950 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3951 "'0,cisco.com;wi-fi.org,21[2:4][5:7]'"); 3952 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3953 "'0,wi-fi.org;example.com,13[5:6]'"); 3954 } else if (dut->ap_nai_realm_list == 4) { 3955 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3956 "'0,mail.example.com,21[2:4][5:7],13[5:6]'"); 3957 } else if (dut->ap_nai_realm_list == 5) { 3958 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3959 "'0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]'"); 3960 } else if (dut->ap_nai_realm_list == 6) { 3961 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3962 "'0,wi-fi.org;mail.example.com,21[2:4][5:7]'"); 3963 } else if (dut->ap_nai_realm_list == 7) { 3964 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3965 "'0,wi-fi.org,13[5:6]'"); 3966 owrt_ap_set_list_vap(dut, vap_id, "nai_realm", 3967 "'0,wi-fi.org,21[2:4][5:7]'"); 3968 } 3969 3970 if (dut->ap_domain_name_list[0]) 3971 owrt_ap_set_list_vap(dut, vap_id, "domain_name", 3972 dut->ap_domain_name_list); 3973 3974 if (dut->ap_ip_addr_type_avail) 3975 owrt_ap_set_vap(dut, vap_id, "ipaddr_type_availability", 3976 "'0c'"); 3977 3978 temp = buf; 3979 3980 *temp++ = '\''; 3981 3982 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) { 3983 if (i) 3984 *temp++ = ';'; 3985 3986 snprintf(temp, 3987 sizeof(dut->ap_plmn_mcc[i]) + 3988 sizeof(dut->ap_plmn_mnc[i]) + 1, 3989 "%s,%s", 3990 dut->ap_plmn_mcc[i], 3991 dut->ap_plmn_mnc[i]); 3992 3993 temp += strlen(dut->ap_plmn_mcc[i]) + 3994 strlen(dut->ap_plmn_mnc[i]) + 1; 3995 } 3996 3997 *temp++ = '\''; 3998 *temp++ = '\0'; 3999 4000 if (i) 4001 owrt_ap_set_vap(dut, vap_id, "anqp_3gpp_cell_net", buf); 4002 4003 if (dut->ap_qos_map_set == 1) 4004 owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_1); 4005 else if (dut->ap_qos_map_set == 2) 4006 owrt_ap_set_vap(dut, vap_id, "qos_map_set", QOS_MAP_SET_2); 4007 4008 /* Proxy-ARP */ 4009 snprintf(buf, sizeof(buf), "%d", dut->ap_proxy_arp); 4010 owrt_ap_set_vap(dut, vap_id, "proxyarp", buf); 4011 4012 /* DGAF */ 4013 snprintf(buf, sizeof(buf), "%d", dut->ap_dgaf_disable); 4014 /* parse to hostapd */ 4015 owrt_ap_set_vap(dut, vap_id, "disable_dgaf", buf); 4016 /* parse to wifi driver */ 4017 owrt_ap_set_vap(dut, vap_id, "dgaf_disable", buf); 4018 4019 /* HCBSSLoad */ 4020 if (dut->ap_bss_load) { 4021 unsigned int bssload = 0; 4022 4023 if (dut->ap_bss_load == 1) { 4024 /* STA count: 1, CU: 50, AAC: 65535 */ 4025 bssload = 0x0132ffff; 4026 } else if (dut->ap_bss_load == 2) { 4027 /* STA count: 1, CU: 200, AAC: 65535 */ 4028 bssload = 0x01c8ffff; 4029 } else if (dut->ap_bss_load == 3) { 4030 /* STA count: 1, CU: 75, AAC: 65535 */ 4031 bssload = 0x014bffff; 4032 } 4033 4034 snprintf(buf, sizeof(buf), "%d", bssload); 4035 owrt_ap_set_vap(dut, vap_id, "hcbssload", buf); 4036 } 4037 4038 /* L2TIF */ 4039 if (dut->ap_l2tif) 4040 owrt_ap_set_vap(dut, vap_id, "l2tif", "1"); 4041 4042 if (dut->ap_disable_protection == 1) 4043 owrt_ap_set_vap(dut, vap_id, "enablertscts", "0"); 4044 4045 if (dut->ap_txBF) { 4046 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "1"); 4047 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "1"); 4048 if (dut->program == PROGRAM_HE) { 4049 owrt_ap_set_vap(dut, vap_id, "he_subfer", "1"); 4050 owrt_ap_set_vap(dut, vap_id, "cwmenable", "0"); 4051 } 4052 } else { 4053 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0"); 4054 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0"); 4055 if (dut->program == PROGRAM_HE) 4056 owrt_ap_set_vap(dut, vap_id, "he_subfer", "0"); 4057 } 4058 4059 if (dut->ap_mu_txBF) { 4060 owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "1"); 4061 if (dut->program == PROGRAM_HE) { 4062 owrt_ap_set_vap(dut, vap_id, "he_mubfer", "1"); 4063 owrt_ap_set_vap(dut, vap_id, "he_mubfee", "1"); 4064 } 4065 } else { 4066 owrt_ap_set_vap(dut, vap_id, "vhtmubfer", "0"); 4067 if (dut->program == PROGRAM_HE) { 4068 owrt_ap_set_vap(dut, vap_id, "he_mubfer", "0"); 4069 owrt_ap_set_vap(dut, vap_id, "he_mubfee", "0"); 4070 } 4071 } 4072 4073 if (dut->ap_tx_stbc) { 4074 /* STBC and beamforming are mutually exclusive features */ 4075 owrt_ap_set_vap(dut, vap_id, "implicitbf", "0"); 4076 } 4077 4078 /* enable dfsmode */ 4079 snprintf(buf, sizeof(buf), "%d", dut->ap_dfs_mode); 4080 owrt_ap_set_vap(dut, vap_id, "doth", buf); 4081 4082 if (dut->program == PROGRAM_LOC && dut->ap_interworking) { 4083 char anqpval[1024]; 4084 4085 owrt_ap_set_vap(dut, vap_id, "interworking", "1"); 4086 4087 if (dut->ap_lci == 1 && strlen(dut->ap_tag_ssid[0]) == 0) { 4088 snprintf(anqpval, sizeof(anqpval), 4089 "'265:0010%s%s060101'", 4090 dut->ap_val_lci, dut->ap_infoz); 4091 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval); 4092 } 4093 4094 if (dut->ap_lcr == 1) { 4095 snprintf(anqpval, sizeof(anqpval), 4096 "'266:0000b2555302ae%s'", 4097 dut->ap_val_lcr); 4098 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval); 4099 } 4100 4101 if (dut->ap_fqdn_held == 1 && dut->ap_fqdn_supl == 1) 4102 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", 4103 "'267:00110168656c642e6578616d706c652e636f6d0011027375706c2e6578616d706c652e636f6d'"); 4104 } 4105 4106 if (dut->program == PROGRAM_MBO) { 4107 owrt_ap_set_vap(dut, vap_id, "interworking", "1"); 4108 owrt_ap_set_vap(dut, vap_id, "mbo", "1"); 4109 owrt_ap_set_vap(dut, vap_id, "rrm", "1"); 4110 owrt_ap_set_vap(dut, vap_id, "mbo_cell_conn_pref", "1"); 4111 4112 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", 4113 "'272:34108cfdf0020df1f7000000733000030101'"); 4114 snprintf(buf, sizeof(buf), "%d", dut->ap_gas_cb_delay); 4115 owrt_ap_set_vap(dut, vap_id, "gas_comeback_delay", buf); 4116 } 4117 4118 if (ap_ft_enabled(dut)) { 4119 unsigned char self_mac[ETH_ALEN]; 4120 char mac_str[20]; 4121 4122 owrt_ap_set_vap(dut, vap_id, "ft_over_ds", 4123 dut->ap_ft_ds == VALUE_ENABLED ? "1" : "0"); 4124 owrt_ap_set_vap(dut, vap_id, "ieee80211r", "1"); 4125 if (get_hwaddr(sigma_radio_ifname[0], self_mac) < 0) 4126 return -1; 4127 snprintf(mac_str, sizeof(mac_str), 4128 "%02x:%02x:%02x:%02x:%02x:%02x", 4129 self_mac[0], self_mac[1], self_mac[2], 4130 self_mac[3], self_mac[4], self_mac[5]); 4131 owrt_ap_set_vap(dut, vap_id, "ap_macaddr", mac_str); 4132 snprintf(mac_str, sizeof(mac_str), 4133 "%02x:%02x:%02x:%02x:%02x:%02x", 4134 self_mac[0], self_mac[1], self_mac[2], 4135 self_mac[3], self_mac[4], self_mac[5]); 4136 owrt_ap_set_vap(dut, vap_id, "r1_key_holder", mac_str); 4137 owrt_ap_set_vap(dut, vap_id, "ft_psk_generate_local", "1"); 4138 owrt_ap_set_vap(dut, vap_id, "kh_key_hex", 4139 "000102030405060708090a0b0c0d0e0f"); 4140 snprintf(mac_str, sizeof(mac_str), 4141 "%02x:%02x:%02x:%02x:%02x:%02x", 4142 dut->ft_bss_mac_list[0][0], 4143 dut->ft_bss_mac_list[0][1], 4144 dut->ft_bss_mac_list[0][2], 4145 dut->ft_bss_mac_list[0][3], 4146 dut->ft_bss_mac_list[0][4], 4147 dut->ft_bss_mac_list[0][5]); 4148 owrt_ap_set_vap(dut, vap_id, "ap2_macaddr", mac_str); 4149 owrt_ap_set_vap(dut, vap_id, "mobility_domain", 4150 dut->ap_mobility_domain); 4151 owrt_ap_set_vap(dut, vap_id, "ap2_r1_key_holder", mac_str); 4152 } 4153 4154 if ((ap_ft_enabled(dut) && dut->ap_name == 0) || 4155 (ap_ft_enabled(dut) && dut->ap_name == 2)) { 4156 owrt_ap_set_vap(dut, vap_id, "nasid2", "nas2.example.com"); 4157 owrt_ap_set_vap(dut, vap_id, "nasid", "nas1.example.com"); 4158 } 4159 4160 if (ap_ft_enabled(dut) && dut->ap_name == 1) { 4161 owrt_ap_set_vap(dut, vap_id, "nasid2", "nas1.example.com"); 4162 owrt_ap_set_vap(dut, vap_id, "nasid", "nas2.example.com"); 4163 } 4164 4165 if (dut->ap_broadcast_ssid == VALUE_DISABLED) 4166 owrt_ap_set_vap(dut, vap_id, "hidden", "1"); 4167 4168 /* Enable/disable PMKSA caching, if asked to */ 4169 if (dut->ap_pmksa == 1) { 4170 snprintf(buf, sizeof(buf), "%d", dut->ap_pmksa_caching); 4171 owrt_ap_set_vap(dut, vap_id, "disable_pmksa_caching", buf); 4172 } 4173 4174 if (dut->ap_beacon_prot) 4175 owrt_ap_set_vap(dut, vap_id, "beacon_prot", "1"); 4176 4177 if (dut->ap_transition_disable) { 4178 snprintf(buf, sizeof(buf), "0x%02x", 4179 dut->ap_transition_disable); 4180 owrt_ap_set_vap(dut, vap_id, "transition_disable", buf); 4181 } 4182 4183 if (dut->rsne_override) { 4184 snprintf(buf, sizeof(buf), "%s", dut->rsne_override); 4185 owrt_ap_set_vap(dut, vap_count, "own_ie_override", buf); 4186 } 4187 4188 if (dut->rsnxe_override_eapol) 4189 owrt_ap_set_vap(dut, vap_count, "rsnxe_override_eapol", 4190 dut->rsnxe_override_eapol); 4191 4192 if (dut->sae_commit_override) { 4193 snprintf(buf, sizeof(buf), "%s", dut->sae_commit_override); 4194 owrt_ap_set_vap(dut, vap_count, "sae_commit_override", buf); 4195 } 4196 4197 if (dut->ap_sae_groups) { 4198 snprintf(buf, sizeof(buf), "\'%s\'", dut->ap_sae_groups); 4199 owrt_ap_set_list_vap(dut, vap_count, "sae_groups", buf); 4200 } 4201 4202 if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) { 4203 const char *sae_pwe = NULL; 4204 4205 if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut)) 4206 sae_pwe = "3"; 4207 else if (dut->sae_pwe == SAE_PWE_LOOP) 4208 sae_pwe = "0"; 4209 else if (dut->sae_pwe == SAE_PWE_H2E) 4210 sae_pwe = "1"; 4211 else if (dut->sae_h2e_default) 4212 sae_pwe = "2"; 4213 if (sae_pwe) 4214 owrt_ap_set_vap(dut, vap_count, "sae_pwe", sae_pwe); 4215 } 4216 4217 if (dut->sae_anti_clogging_threshold >= 0) { 4218 snprintf(buf, sizeof(buf), "%d", 4219 dut->sae_anti_clogging_threshold); 4220 owrt_ap_set_vap(dut, vap_count, "sae_anti_clogging_threshold", 4221 buf); 4222 } 4223 4224 if (dut->sae_reflection) 4225 owrt_ap_set_vap(dut, vap_count, "sae_reflection_attack", "1"); 4226 if (dut->sae_confirm_immediate) 4227 owrt_ap_set_vap(dut, vap_count, "sae_confirm_immediate", "2"); 4228 4229 if (dut->ap_he_dlofdma == VALUE_ENABLED && dut->ap_he_ppdu == PPDU_MU) { 4230 dut->ap_txBF = 0; 4231 dut->ap_mu_txBF = 0; 4232 owrt_ap_set_vap(dut, vap_id, "vhtsubfer", "0"); 4233 owrt_ap_set_vap(dut, vap_id, "vhtsubfee", "0"); 4234 owrt_ap_set_vap(dut, vap_id, "he_subfer", "0"); 4235 } 4236 4237 if (dut->program == PROGRAM_HE && 4238 (dut->ap_txBF || dut->ap_he_ulofdma == VALUE_ENABLED || 4239 dut->ap_he_mimo == MIMO_DL)) { 4240 switch (dut->ap_chwidth) { 4241 case AP_20: 4242 owrt_ap_set_vap(dut, vap_id, "chwidth", "0"); 4243 break; 4244 case AP_40: 4245 owrt_ap_set_vap(dut, vap_id, "chwidth", "1"); 4246 break; 4247 case AP_80: 4248 owrt_ap_set_vap(dut, vap_id, "chwidth", "2"); 4249 break; 4250 case AP_160: 4251 owrt_ap_set_vap(dut, vap_id, "chwidth", "3"); 4252 break; 4253 case AP_80_80: 4254 owrt_ap_set_vap(dut, vap_id, "chwidth", "3"); 4255 break; 4256 case AP_AUTO: 4257 default: 4258 break; 4259 } 4260 } 4261 4262 if (dut->ap_ocvc == 1) 4263 owrt_ap_set_vap(dut, vap_count, "ocv", "1"); 4264 else if (dut->ap_ocvc == 0) 4265 owrt_ap_set_vap(dut, vap_count, "ocv", "0"); 4266 4267 return 1; 4268 } 4269 4270 4271 static int owrt_ap_config_vap_anqp(struct sigma_dut *dut) 4272 { 4273 char anqpval[1024]; 4274 unsigned char addr[6]; 4275 unsigned char addr2[6]; 4276 struct ifreq ifr; 4277 char *ifname; 4278 int s; 4279 int vap_id = 0; 4280 4281 s = socket(AF_INET, SOCK_DGRAM, 0); 4282 if (s < 0) { 4283 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open socket"); 4284 return -1; 4285 } 4286 4287 memset(&ifr, 0, sizeof(ifr)); 4288 ifname = "ath0"; 4289 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4290 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 4291 perror("ioctl"); 4292 close(s); 4293 return -1; 4294 } 4295 memcpy(addr, ifr.ifr_hwaddr.sa_data, 6); 4296 4297 memset(&ifr, 0, sizeof(ifr)); 4298 ifname = "ath01"; 4299 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4300 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 4301 perror("ioctl"); 4302 close(s); 4303 return -1; 4304 } 4305 close(s); 4306 memcpy(addr2, ifr.ifr_hwaddr.sa_data, 6); 4307 4308 snprintf(anqpval, sizeof(anqpval), 4309 "'265:0010%s%s060101070d00%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'", 4310 dut->ap_val_lci, dut->ap_infoz, 4311 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], 4312 addr2[0], addr2[1], addr2[2], addr2[3], addr2[4], addr2[5]); 4313 4314 owrt_ap_set_list_vap(dut, vap_id, "anqp_elem", anqpval); 4315 return 0; 4316 } 4317 4318 4319 static int owrt_ap_post_config_commit(struct sigma_dut *dut, 4320 struct sigma_conn *conn, 4321 struct sigma_cmd *cmd) 4322 { 4323 int ap_security = 0; 4324 int i; 4325 4326 for (i = 0; i < MAX_WLAN_TAGS - 1; i++) { 4327 if (dut->ap_tag_key_mgmt[i] != AP2_OPEN) 4328 ap_security = 1; 4329 } 4330 if (dut->ap_key_mgmt != AP_OPEN) 4331 ap_security = 1; 4332 if (ap_security) { 4333 /* allow some time for hostapd to start before returning 4334 * success */ 4335 usleep(500000); 4336 4337 if (run_hostapd_cli(dut, "ping") != 0) { 4338 send_resp(dut, conn, SIGMA_ERROR, 4339 "errorCode,Failed to talk to hostapd"); 4340 return 0; 4341 } 4342 } 4343 4344 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 4345 ath_ap_set_params(dut); 4346 4347 /* Send response */ 4348 return 1; 4349 } 4350 4351 4352 static int cmd_owrt_ap_config_commit(struct sigma_dut *dut, 4353 struct sigma_conn *conn, 4354 struct sigma_cmd *cmd) 4355 { 4356 if (dut->program == PROGRAM_DPP && 4357 get_driver_type(dut) == DRIVER_OPENWRT) { 4358 wpa_command(dut->hostapd_ifname, "DPP_BOOTSTRAP_REMOVE *"); 4359 wpa_command(dut->hostapd_ifname, "DPP_PKEX_REMOVE *"); 4360 } 4361 4362 /* Stop the AP */ 4363 run_system(dut, "wifi down"); 4364 4365 /* Reset the wireless configuration */ 4366 run_system(dut, "rm -rf /etc/config/wireless"); 4367 switch (get_openwrt_driver_type()) { 4368 case OPENWRT_DRIVER_ATHEROS: 4369 run_system(dut, "wifi detect qcawifi > /etc/config/wireless"); 4370 break; 4371 default: 4372 run_system(dut, "wifi detect > /etc/config/wireless"); 4373 break; 4374 } 4375 4376 /* Configure Radio & VAP, commit the config */ 4377 if (owrt_ap_config_radio(dut) < 0) 4378 return ERROR_SEND_STATUS; 4379 if (owrt_ap_config_vap(dut) < 0) 4380 return ERROR_SEND_STATUS; 4381 run_system(dut, "uci commit"); 4382 4383 /* Start AP */ 4384 run_system(dut, "wifi up"); 4385 if (dut->program != PROGRAM_MBO && 4386 dut->ap_lci == 1 && dut->ap_interworking && 4387 strlen(dut->ap_tag_ssid[0]) > 0) { 4388 /* 4389 * MBO has a different ANQP element value which is set in 4390 * owrt_ap_config_vap(). 4391 */ 4392 owrt_ap_config_vap_anqp(dut); 4393 run_system(dut, "uci commit"); 4394 run_system(dut, "wifi"); 4395 } 4396 4397 return owrt_ap_post_config_commit(dut, conn, cmd); 4398 } 4399 4400 4401 static void cmd_owrt_ap_hs2_reset(struct sigma_dut *dut) 4402 { 4403 unsigned char bssid[6]; 4404 char buf[100]; 4405 char *ifname, *radio_name; 4406 int vap_id = 0; 4407 4408 if (sigma_radio_ifname[0] && 4409 strcmp(sigma_radio_ifname[0], "wifi2") == 0) { 4410 ifname = "ath2"; 4411 radio_name = "wifi2"; 4412 vap_id = 2; 4413 } else if (sigma_radio_ifname[0] && 4414 strcmp(sigma_radio_ifname[0], "wifi1") == 0) { 4415 ifname = "ath1"; 4416 radio_name = "wifi1"; 4417 vap_id = 1; 4418 } else { 4419 ifname = "ath0"; 4420 radio_name = "wifi0"; 4421 vap_id = 0; 4422 } 4423 4424 if (!get_hwaddr(ifname, bssid)) { 4425 snprintf(buf, sizeof(buf), "%s", bssid); 4426 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 4427 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 4428 "%02x:%02x:%02x:%02x:%02x:%02x", 4429 bssid[0], bssid[1], bssid[2], bssid[3], 4430 bssid[4], bssid[5]); 4431 } else { 4432 if (!get_hwaddr(radio_name, bssid)) { 4433 snprintf(buf, sizeof(buf), "%s", dut->ap_hessid); 4434 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 4435 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 4436 "%02x:%02x:%02x:%02x:%02x:%02x", 4437 bssid[0], bssid[1], bssid[2], bssid[3], 4438 bssid[4], bssid[5]); 4439 } else { 4440 /* Select & enable/disable radios */ 4441 if (sigma_radio_ifname[0] && 4442 strcmp(sigma_radio_ifname[0], "wifi2") == 0) { 4443 /* We want to use wifi2 */ 4444 owrt_ap_set_radio(dut, 0, "disabled", "1"); 4445 owrt_ap_set_radio(dut, 1, "disabled", "1"); 4446 owrt_ap_set_radio(dut, 2, "disabled", "0"); 4447 owrt_ap_set_vap(dut, vap_id, "device", "wifi2"); 4448 } else if (sigma_radio_ifname[0] && 4449 strcmp(sigma_radio_ifname[0], "wifi1") == 0) { 4450 /* We want to use wifi1 */ 4451 owrt_ap_set_radio(dut, 0, "disabled", "1"); 4452 owrt_ap_set_radio(dut, 1, "disabled", "0"); 4453 owrt_ap_set_vap(dut, vap_id, "device", "wifi1"); 4454 } else { 4455 /* We want to use wifi0 */ 4456 owrt_ap_set_radio(dut, 0, "disabled", "0"); 4457 owrt_ap_set_radio(dut, 1, "disabled", "1"); 4458 owrt_ap_set_vap(dut, vap_id, "device", "wifi0"); 4459 } 4460 4461 run_system(dut, "uci commit"); 4462 run_system(dut, "wifi up"); 4463 4464 if (!get_hwaddr(radio_name, bssid)) { 4465 snprintf(buf, sizeof(buf), "%s", 4466 dut->ap_hessid); 4467 owrt_ap_set_vap(dut, vap_id, "hessid", buf); 4468 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 4469 "%02x:%02x:%02x:%02x:%02x:%02x", 4470 bssid[0], bssid[1], bssid[2], bssid[3], 4471 bssid[4], bssid[5]); 4472 } 4473 } 4474 } 4475 } 4476 4477 4478 static enum sigma_cmd_result cmd_ap_reboot(struct sigma_dut *dut, 4479 struct sigma_conn *conn, 4480 struct sigma_cmd *cmd) 4481 { 4482 switch (get_driver_type(dut)) { 4483 case DRIVER_ATHEROS: 4484 run_system(dut, "apdown"); 4485 sleep(1); 4486 run_system(dut, "reboot"); 4487 break; 4488 case DRIVER_OPENWRT: 4489 run_system(dut, "wifi down"); 4490 sleep(1); 4491 run_system(dut, "reboot"); 4492 break; 4493 default: 4494 sigma_dut_print(dut, DUT_MSG_INFO, "Ignore ap_reboot command"); 4495 break; 4496 } 4497 4498 return 1; 4499 } 4500 4501 4502 int ascii2hexstr(const char *str, char *hex) 4503 { 4504 int i, length; 4505 4506 length = strlen(str); 4507 4508 for (i = 0; i < length; i++) 4509 snprintf(hex + i * 2, 3, "%X", str[i]); 4510 4511 hex[length * 2] = '\0'; 4512 return 1; 4513 } 4514 4515 4516 static int kill_process(struct sigma_dut *dut, char *proc_name, 4517 unsigned char is_proc_instance_one, int sig) 4518 { 4519 #ifdef __linux__ 4520 struct dirent *dp, *dp_in; 4521 const char *direc = "/proc/"; 4522 char buf[100]; 4523 DIR *dir = opendir(direc); 4524 DIR *dir_in; 4525 FILE *fp; 4526 char *pid, *temp; 4527 char *saveptr; 4528 int ret = -1, res; 4529 4530 if (dir == NULL) 4531 return ret; 4532 4533 while ((dp = readdir(dir)) != NULL) { 4534 if (dp->d_type != DT_DIR) 4535 continue; 4536 4537 res = snprintf(buf, sizeof(buf), "%s%s", direc, dp->d_name); 4538 if (res < 0 || res >= sizeof(buf)) 4539 continue; 4540 dir_in = opendir(buf); 4541 if (dir_in == NULL) 4542 continue; 4543 dp_in = readdir(dir_in); 4544 closedir(dir_in); 4545 if (dp_in == NULL) 4546 continue; 4547 res = snprintf(buf, sizeof(buf), "%s%s/stat", 4548 direc, dp->d_name); 4549 if (res < 0 || res >= sizeof(buf)) 4550 continue; 4551 fp = fopen(buf, "r"); 4552 if (fp == NULL) 4553 continue; 4554 if (fgets(buf, 100, fp) == NULL) 4555 buf[0] = '\0'; 4556 fclose(fp); 4557 pid = strtok_r(buf, " ", &saveptr); 4558 temp = strtok_r(NULL, " ", &saveptr); 4559 if (pid && temp && 4560 strncmp(temp, proc_name, strlen(proc_name)) == 0) { 4561 sigma_dut_print(dut, DUT_MSG_INFO, 4562 "killing %s process with PID %s", 4563 proc_name, pid); 4564 snprintf(buf, sizeof(buf), "kill -%d %d", sig, 4565 atoi(pid)); 4566 run_system(dut, buf); 4567 ret = 0; 4568 if (is_proc_instance_one) 4569 break; 4570 } 4571 } 4572 4573 closedir(dir); 4574 4575 return ret; 4576 #else /* __linux__ */ 4577 return -1; 4578 #endif /* __linux__ */ 4579 } 4580 4581 4582 static int run_ndc(struct sigma_dut *dut, char *buf) 4583 { 4584 sigma_dut_print(dut, DUT_MSG_INFO, "CMD NDC:: %s", buf); 4585 sleep(2); 4586 return run_system(dut, buf); 4587 } 4588 4589 4590 static int sigma_write_cfg(struct sigma_dut *dut, const char *pfile, 4591 const char *field, const char *value) 4592 { 4593 FILE *fcfg, *ftmp; 4594 char buf[MAX_CONF_LINE_LEN + 1]; 4595 int len, found = 0, res; 4596 4597 /* Open the configuration file */ 4598 fcfg = fopen(pfile, "r"); 4599 if (!fcfg) { 4600 sigma_dut_print(dut, DUT_MSG_ERROR, 4601 "Failed to open hostapd conf file"); 4602 return -1; 4603 } 4604 4605 snprintf(buf, sizeof(buf), "%s~", pfile); 4606 /* Open a temporary file */ 4607 ftmp = fopen(buf, "w+"); 4608 if (!ftmp) { 4609 fclose(fcfg); 4610 sigma_dut_print(dut, DUT_MSG_ERROR, 4611 "Failed to open temp buf"); 4612 return -1; 4613 } 4614 4615 /* Read the values from the configuration file */ 4616 len = strlen(field); 4617 while (fgets(buf, MAX_CONF_LINE_LEN, fcfg)) { 4618 char *pline = buf; 4619 4620 /* commented line */ 4621 if (buf[0] == '#') 4622 pline++; 4623 4624 /* Identify the configuration parameter to be updated */ 4625 if (!found && strncmp(pline, field, len) == 0 && 4626 pline[len] == '=') { 4627 snprintf(buf, sizeof(buf), "%s=%s\n", field, value); 4628 found = 1; 4629 sigma_dut_print(dut, DUT_MSG_INFO, 4630 "Updated hostapd conf file"); 4631 } 4632 4633 fprintf(ftmp, "%s", buf); 4634 } 4635 4636 if (!found) { 4637 /* Configuration line not found */ 4638 /* Add the new line at the end of file */ 4639 fprintf(ftmp, "%s=%s\n", field, value); 4640 sigma_dut_print(dut, DUT_MSG_INFO, 4641 "Adding a new line in hostapd conf file"); 4642 } 4643 4644 fclose(fcfg); 4645 fclose(ftmp); 4646 4647 snprintf(buf, sizeof(buf), "%s~", pfile); 4648 4649 /* Restore the updated configuration file */ 4650 res = rename(buf, pfile); 4651 4652 /* Remove the temporary file. Ignore the return value */ 4653 unlink(buf); 4654 4655 /* chmod is needed because open() may not set permissions properly 4656 * depending on the current umask */ 4657 if (chmod(pfile, 0660) < 0) { 4658 unlink(pfile); 4659 sigma_dut_print(dut, DUT_MSG_ERROR, 4660 "Error changing permissions"); 4661 return -1; 4662 } 4663 4664 if (res < 0) { 4665 sigma_dut_print(dut, DUT_MSG_ERROR, 4666 "Error restoring conf file"); 4667 return -1; 4668 } 4669 4670 return 0; 4671 } 4672 4673 4674 static int cmd_wcn_ap_config_commit(struct sigma_dut *dut, 4675 struct sigma_conn *conn, 4676 struct sigma_cmd *cmd) 4677 { 4678 char buf[100]; 4679 struct stat s; 4680 int num_tries = 0, ret; 4681 4682 if (kill_process(dut, "(netd)", 1, SIGKILL) == 0 || 4683 system("killall netd") == 0) { 4684 /* Avoid Error: Error connecting (Connection refused) 4685 * Wait some time to allow netd to reinitialize. 4686 */ 4687 usleep(1500000); 4688 } 4689 4690 while (num_tries < 10) { 4691 ret = run_ndc(dut, "ndc softap stopap"); 4692 num_tries++; 4693 if (WIFEXITED(ret)) 4694 ret = WEXITSTATUS(ret); 4695 /* On success, NDC exits with 0 */ 4696 if (ret == 0) 4697 break; 4698 sigma_dut_print(dut, DUT_MSG_INFO, 4699 "Try No. %d: ndc softap stopap failed, exit code %d", 4700 num_tries, ret); 4701 } 4702 4703 if (ret != 0) 4704 sigma_dut_print(dut, DUT_MSG_ERROR, 4705 "ndc softap stopap command failed for 10 times - giving up"); 4706 4707 #ifdef ANDROID 4708 /* Unload/Load driver to cleanup the state of the driver */ 4709 system("rmmod -f wlan"); 4710 usleep(500000); 4711 system("insmod /system/lib/modules/wlan.ko"); 4712 #else /* ANDROID */ 4713 run_ndc(dut, "ndc softap qccmd set enable_softap=0"); 4714 run_ndc(dut, "ndc softap qccmd set enable_softap=1"); 4715 #endif /* ANDROID */ 4716 4717 switch (dut->ap_mode) { 4718 case AP_11g: 4719 run_ndc(dut, "ndc softap qccmd set hw_mode=g-only"); 4720 break; 4721 case AP_11b: 4722 run_ndc(dut, "ndc softap qccmd set hw_mode=b-only"); 4723 break; 4724 case AP_11ng: 4725 run_ndc(dut, "ndc softap qccmd set hw_mode=n"); 4726 break; 4727 case AP_11a: 4728 run_ndc(dut, "ndc softap qccmd set hw_mode=a-only"); 4729 break; 4730 case AP_11na: 4731 run_ndc(dut, "ndc softap qccmd set hw_mode=n"); 4732 break; 4733 case AP_11ac: 4734 run_ndc(dut, "ndc softap qccmd set hw_mode=ac"); 4735 break; 4736 default: 4737 break; 4738 } 4739 4740 snprintf(buf, sizeof(buf), "ndc softap qccmd set channel=%d", 4741 dut->ap_channel); 4742 run_ndc(dut, buf); 4743 4744 /* 4745 * ndc doesn't support double quotes as SSID string, so re-write 4746 * hostapd configuration file to update SSID. 4747 */ 4748 if (dut->ap_ssid[0] != '\0') 4749 sigma_write_cfg(dut, ANDROID_CONFIG_FILE, "ssid", dut->ap_ssid); 4750 4751 switch (dut->ap_key_mgmt) { 4752 case AP_OPEN: 4753 if (dut->ap_cipher == AP_WEP) { 4754 run_ndc(dut, "ndc softap qccmd set security_mode=1"); 4755 snprintf(buf, sizeof(buf), 4756 "ndc softap qccmd set wep_key0=%s", 4757 dut->ap_wepkey); 4758 run_ndc(dut, buf); 4759 } else { 4760 run_ndc(dut, "ndc softap qccmd set security_mode=0"); 4761 } 4762 break; 4763 case AP_WPA2_PSK: 4764 case AP_WPA2_PSK_MIXED: 4765 case AP_WPA_PSK: 4766 if (dut->ap_key_mgmt == AP_WPA2_PSK) 4767 run_ndc(dut, "ndc softap qccmd set security_mode=3"); 4768 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 4769 run_ndc(dut, "ndc softap qccmd set security_mode=4"); 4770 else 4771 run_ndc(dut, "ndc softap qccmd set security_mode=2"); 4772 4773 /* 4774 * ndc doesn't support some special characters as passphrase, 4775 * so re-write hostapd configuration file to update Passphrase. 4776 */ 4777 if (dut->ap_passphrase[0] != '\0') 4778 sigma_write_cfg(dut, ANDROID_CONFIG_FILE, 4779 "wpa_passphrase", dut->ap_passphrase); 4780 4781 if (dut->ap_cipher == AP_CCMP_TKIP) 4782 run_ndc(dut, "ndc softap qccmd set wpa_pairwise=" 4783 "TKIP CCMP"); 4784 else if (dut->ap_cipher == AP_TKIP) 4785 run_ndc(dut, "ndc softap qccmd set wpa_pairwise=" 4786 "TKIP"); 4787 else 4788 run_ndc(dut, "ndc softap qccmd set wpa_pairwise=" 4789 "CCMP &"); 4790 break; 4791 case AP_WPA2_SAE: 4792 case AP_WPA2_PSK_SAE: 4793 case AP_WPA2_EAP: 4794 case AP_WPA2_EAP_MIXED: 4795 case AP_WPA_EAP: 4796 case AP_SUITEB: 4797 case AP_WPA2_OWE: 4798 case AP_WPA2_EAP_OSEN: 4799 case AP_OSEN: 4800 case AP_WPA2_FT_EAP: 4801 case AP_WPA2_FT_PSK: 4802 case AP_WPA2_EAP_SHA256: 4803 case AP_WPA2_PSK_SHA256: 4804 case AP_WPA2_ENT_FT_EAP: 4805 /* Not supported */ 4806 break; 4807 } 4808 4809 switch (dut->ap_pmf) { 4810 case AP_PMF_DISABLED: 4811 run_ndc(dut, "ndc softap qccmd set ieee80211w=0"); 4812 break; 4813 case AP_PMF_OPTIONAL: 4814 run_ndc(dut, "ndc softap qccmd set ieee80211w=1"); 4815 if (dut->ap_add_sha256) 4816 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256"); 4817 else 4818 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK"); 4819 break; 4820 case AP_PMF_REQUIRED: 4821 run_ndc(dut, "ndc softap qccmd set ieee80211w=2"); 4822 run_ndc(dut, "ndc softap qccmd set wpa_key_mgmt=WPA-PSK-SHA256"); 4823 break; 4824 } 4825 4826 if (dut->ap_countrycode[0]) { 4827 snprintf(buf, sizeof(buf), 4828 "ndc softap qccmd set country_code=%s", 4829 dut->ap_countrycode); 4830 run_ndc(dut, buf); 4831 } 4832 4833 if (dut->ap_regulatory_mode == AP_80211D_MODE_ENABLED) 4834 run_ndc(dut, "ndc softap qccmd set ieee80211d=1"); 4835 4836 if (dut->ap_dfs_mode == AP_DFS_MODE_ENABLED) 4837 run_ndc(dut, "ndc softap qccmd set ieee80211h=1"); 4838 4839 run_ndc(dut, "ndc softap startap"); 4840 4841 snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, 4842 get_main_ifname(dut)); 4843 num_tries = 0; 4844 while (num_tries < 10 && (ret = stat(buf, &s) != 0)) { 4845 run_ndc(dut, "ndc softap stopap"); 4846 run_ndc(dut, "ndc softap startap"); 4847 num_tries++; 4848 } 4849 4850 if (num_tries == 10) { 4851 sigma_dut_print(dut, DUT_MSG_INFO, "Tried 10 times with ctrl " 4852 "iface %s :: reboot the APDUT", buf); 4853 return ret; 4854 } 4855 4856 sigma_dut_print(dut, DUT_MSG_INFO, "setting ip addr %s mask %s", 4857 ap_inet_addr, ap_inet_mask); 4858 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up", 4859 get_main_ifname(dut), ap_inet_addr, ap_inet_mask); 4860 if (system(buf) != 0) { 4861 sigma_dut_print(dut, DUT_MSG_ERROR, 4862 "Failed to intialize the interface"); 4863 return -1; 4864 } 4865 4866 return 1; 4867 } 4868 4869 4870 static int append_hostapd_conf_hs2(struct sigma_dut *dut, FILE *f) 4871 { 4872 fprintf(f, "hs20=1\nhs20_deauth_req_timeout=3\n" 4873 "disable_dgaf=%d\n", dut->ap_dgaf_disable); 4874 4875 if (dut->ap_oper_name) { 4876 fprintf(f, "hs20_oper_friendly_name=eng:Wi-Fi Alliance\n"); 4877 fprintf(f, "hs20_oper_friendly_name=chi:Wi-Fi\xe8\x81\x94\xe7\x9b\x9f\n"); 4878 } 4879 4880 if (dut->ap_wan_metrics == 1) 4881 fprintf(f, "hs20_wan_metrics=01:2500:384:0:0:10\n"); 4882 else if (dut->ap_wan_metrics == 2) 4883 fprintf(f, "hs20_wan_metrics=01:1500:384:20:20:10\n"); 4884 else if (dut->ap_wan_metrics == 3) 4885 fprintf(f, "hs20_wan_metrics=01:2000:1000:20:20:10\n"); 4886 else if (dut->ap_wan_metrics == 4) 4887 fprintf(f, "hs20_wan_metrics=01:8000:1000:20:20:10\n"); 4888 else if (dut->ap_wan_metrics == 5) 4889 fprintf(f, "hs20_wan_metrics=01:9000:5000:20:20:10\n"); 4890 4891 if (dut->ap_conn_capab == 1) { 4892 fprintf(f, "hs20_conn_capab=1:0:0\n"); 4893 fprintf(f, "hs20_conn_capab=6:20:1\n"); 4894 fprintf(f, "hs20_conn_capab=6:22:0\n"); 4895 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4896 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4897 fprintf(f, "hs20_conn_capab=6:1723:0\n"); 4898 fprintf(f, "hs20_conn_capab=6:5060:0\n"); 4899 fprintf(f, "hs20_conn_capab=17:500:1\n"); 4900 fprintf(f, "hs20_conn_capab=17:5060:0\n"); 4901 fprintf(f, "hs20_conn_capab=17:4500:1\n"); 4902 fprintf(f, "hs20_conn_capab=50:0:1\n"); 4903 } else if (dut->ap_conn_capab == 2) { 4904 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4905 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4906 fprintf(f, "hs20_conn_capab=17:5060:1\n"); 4907 fprintf(f, "hs20_conn_capab=6:5060:1\n"); 4908 } else if (dut->ap_conn_capab == 3) { 4909 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4910 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4911 } else if (dut->ap_conn_capab == 4) { 4912 fprintf(f, "hs20_conn_capab=6:80:1\n"); 4913 fprintf(f, "hs20_conn_capab=6:443:1\n"); 4914 fprintf(f, "hs20_conn_capab=6:5060:1\n"); 4915 fprintf(f, "hs20_conn_capab=17:5060:1\n"); 4916 } 4917 4918 if (dut->ap_oper_class == 1) 4919 fprintf(f, "hs20_operating_class=51\n"); 4920 else if (dut->ap_oper_class == 2) 4921 fprintf(f, "hs20_operating_class=73\n"); 4922 else if (dut->ap_oper_class == 3) 4923 fprintf(f, "hs20_operating_class=5173\n"); 4924 4925 if (dut->ap_osu_provider_list) { 4926 char *osu_friendly_name = NULL; 4927 char *osu_icon = NULL; 4928 char *osu_ssid = NULL; 4929 char *osu_nai = NULL; 4930 char *osu_nai2 = NULL; 4931 char *osu_service_desc = NULL; 4932 char *hs20_icon_filename = NULL; 4933 char hs20_icon[150]; 4934 int osu_method; 4935 4936 hs20_icon_filename = "icon_red_zxx.png"; 4937 if (dut->ap_osu_icon_tag == 2) 4938 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4939 snprintf(hs20_icon, sizeof(hs20_icon), 4940 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/%s", 4941 hs20_icon_filename); 4942 osu_icon = "icon_red_zxx.png"; 4943 osu_ssid = "OSU"; 4944 osu_friendly_name = "kor:SP 빨강 테스트 전용"; 4945 osu_service_desc = "kor:테스트 목적으로 무료 서비스"; 4946 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0]; 4947 4948 if (strlen(dut->ap_osu_server_uri[0])) 4949 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[0]); 4950 else 4951 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n"); 4952 4953 switch (dut->ap_osu_provider_list) { 4954 case 1: 4955 case 101: 4956 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n"); 4957 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4958 hs20_icon_filename = "icon_red_eng.png"; 4959 if (dut->ap_osu_icon_tag == 2) 4960 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4961 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/%s\n", 4962 hs20_icon_filename); 4963 fprintf(f, "osu_icon=icon_red_eng.png\n"); 4964 break; 4965 case 2: 4966 case 102: 4967 fprintf(f, "osu_friendly_name=eng:Wireless Broadband Alliance\n"); 4968 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4969 hs20_icon_filename = "icon_orange_zxx.png"; 4970 if (dut->ap_osu_icon_tag == 2) 4971 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4972 snprintf(hs20_icon, sizeof(hs20_icon), 4973 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 4974 hs20_icon_filename); 4975 osu_icon = "icon_orange_zxx.png"; 4976 osu_friendly_name = "kor:와이어리스 브로드밴드 얼라이언스"; 4977 break; 4978 case 3: 4979 case 103: 4980 osu_friendly_name = "spa:SP Red Test Only"; 4981 osu_service_desc = "spa:Free service for test purpose"; 4982 break; 4983 case 4: 4984 case 104: 4985 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 4986 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 4987 hs20_icon_filename = "icon_orange_eng.png"; 4988 if (dut->ap_osu_icon_tag == 2) 4989 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4990 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_orange_eng.png:/etc/ath/%s\n", 4991 hs20_icon_filename); 4992 fprintf(f, "osu_icon=icon_orange_eng.png\n"); 4993 osu_friendly_name = "kor:SP 오렌지 테스트 전용"; 4994 4995 hs20_icon_filename = "icon_orange_zxx.png"; 4996 if (dut->ap_osu_icon_tag == 2) 4997 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 4998 snprintf(hs20_icon, sizeof(hs20_icon), 4999 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5000 hs20_icon_filename); 5001 osu_icon = "icon_orange_zxx.png"; 5002 break; 5003 case 5: 5004 case 105: 5005 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 5006 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 5007 osu_friendly_name = "kor:SP 오렌지 테스트 전용"; 5008 hs20_icon_filename = "icon_orange_zxx.png"; 5009 if (dut->ap_osu_icon_tag == 2) 5010 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5011 snprintf(hs20_icon, sizeof(hs20_icon), 5012 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5013 hs20_icon_filename); 5014 osu_icon = "icon_orange_zxx.png"; 5015 break; 5016 case 6: 5017 case 106: 5018 fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n"); 5019 fprintf(f, "osu_friendly_name=kor:SP 초록 테스트 전용\n"); 5020 hs20_icon_filename = "icon_green_zxx.png"; 5021 if (dut->ap_osu_icon_tag == 2) 5022 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5023 fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s\n", 5024 hs20_icon_filename); 5025 fprintf(f, "osu_icon=icon_green_zxx.png\n"); 5026 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 0 : dut->ap_osu_method[0]; 5027 fprintf(f, "osu_method_list=%d\n", osu_method); 5028 5029 if (strlen(dut->ap_osu_server_uri[1])) 5030 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]); 5031 else 5032 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n"); 5033 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 5034 hs20_icon_filename = "icon_orange_zxx.png"; 5035 if (dut->ap_osu_icon_tag == 2) 5036 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5037 snprintf(hs20_icon, sizeof(hs20_icon), 5038 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5039 hs20_icon_filename); 5040 osu_icon = "icon_orange_zxx.png"; 5041 osu_friendly_name = "kor:SP 오렌지 테스트 전용"; 5042 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 0 : dut->ap_osu_method[1]; 5043 osu_service_desc = NULL; 5044 break; 5045 case 7: 5046 case 107: 5047 fprintf(f, "osu_friendly_name=eng:SP Green Test Only\n"); 5048 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 5049 hs20_icon_filename = "icon_green_eng.png"; 5050 if (dut->ap_osu_icon_tag == 2) 5051 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5052 fprintf(f, "hs20_icon=160:76:eng:image/png:icon_green_eng.png:/etc/ath/%s\n", 5053 hs20_icon_filename); 5054 fprintf(f, "osu_icon=icon_green_eng.png\n"); 5055 osu_friendly_name = "kor:SP 초록 테스트 전용"; 5056 5057 hs20_icon_filename = "icon_green_zxx.png"; 5058 if (dut->ap_osu_icon_tag == 2) 5059 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5060 snprintf(hs20_icon, sizeof(hs20_icon), 5061 "128:61:zxx:image/png:icon_green_zxx.png:/etc/ath/%s", 5062 hs20_icon_filename); 5063 osu_icon = "icon_green_zxx.png"; 5064 break; 5065 case 8: 5066 case 108: 5067 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n"); 5068 fprintf(f, "osu_service_desc=eng:Free service for test purpose\n"); 5069 osu_ssid = "OSU-Encrypted"; 5070 osu_nai = "anonymous@hotspot.net"; 5071 break; 5072 case 9: 5073 case 109: 5074 osu_ssid = "OSU-OSEN"; 5075 osu_nai = "test-anonymous@wi-fi.org"; 5076 osu_friendly_name = "eng:SP Orange Test Only"; 5077 hs20_icon_filename = "icon_orange_zxx.png"; 5078 if (dut->ap_osu_icon_tag == 2) 5079 hs20_icon_filename = "wifi-abgn-logo_270x73.png"; 5080 snprintf(hs20_icon, sizeof(hs20_icon), 5081 "128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/%s", 5082 hs20_icon_filename); 5083 osu_icon = "icon_orange_zxx.png"; 5084 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 1 : dut->ap_osu_method[0]; 5085 osu_service_desc = NULL; 5086 break; 5087 case 10: 5088 case 110: 5089 /* OSU Provider #1 */ 5090 fprintf(f, "osu_friendly_name=eng:SP Orange Test Only\n"); 5091 fprintf(f, "osu_friendly_name=kor:SP 오렌지 테스트 전용\n"); 5092 fprintf(f, "hs20_icon=128:61:zxx:image/png:icon_orange_zxx.png:/etc/ath/icon_orange_zxx.png\n"); 5093 fprintf(f, "osu_icon=icon_orange_zxx.png\n"); 5094 osu_method = (dut->ap_osu_method[0] == 0xFF) ? 5095 1 : dut->ap_osu_method[0]; 5096 fprintf(f, "osu_method_list=%d\n", osu_method); 5097 fprintf(f, "osu_nai=test-anonymous@wi-fi.org\n"); 5098 switch (dut->ap_osu_provider_nai_list) { 5099 case 3: 5100 fprintf(f, 5101 "osu_nai2=test-anonymous@wi-fi.org\n"); 5102 break; 5103 case 4: 5104 fprintf(f, "osu_nai2=random@hotspot.net\n"); 5105 break; 5106 } 5107 5108 /* OSU Provider #2 */ 5109 /* SP Red from defaults */ 5110 if (strlen(dut->ap_osu_server_uri[1])) 5111 fprintf(f, "osu_server_uri=%s\n", dut->ap_osu_server_uri[1]); 5112 else 5113 fprintf(f, "osu_server_uri=https://osu-server.r2-testbed.wi-fi.org/\n"); 5114 fprintf(f, "osu_friendly_name=eng:SP Red Test Only\n"); 5115 snprintf(hs20_icon, sizeof(hs20_icon), 5116 "128:61:zxx:image/png:icon_red_zxx.png:/etc/ath/icon_red_zxx.png"); 5117 osu_method = (dut->ap_osu_method[1] == 0xFF) ? 5118 1 : dut->ap_osu_method[1]; 5119 osu_service_desc = NULL; 5120 osu_nai = "anonymous@hotspot.net"; 5121 break; 5122 default: 5123 break; 5124 } 5125 5126 switch (dut->ap_osu_provider_nai_list) { 5127 case 1: 5128 osu_nai2 = "anonymous@hotspot.net"; 5129 break; 5130 case 2: 5131 osu_nai2 = "test-anonymous@wi-fi.org"; 5132 break; 5133 case 3: 5134 /* OSU Provider NAI #1 written above */ 5135 /* OSU Provider NAI #2 */ 5136 osu_nai2 = "anonymous@hotspot.net"; 5137 break; 5138 case 4: 5139 /* OSU Provider NAI #1 written above */ 5140 /* OSU Provider NAI #2 */ 5141 osu_nai2 = "anonymous@hotspot.net"; 5142 break; 5143 } 5144 5145 if (strlen(dut->ap_osu_ssid)) { 5146 if (dut->ap_tag_ssid[0][0] && 5147 strcmp(dut->ap_tag_ssid[0], dut->ap_osu_ssid) && 5148 strcmp(dut->ap_tag_ssid[0], osu_ssid)) { 5149 sigma_dut_print(dut, DUT_MSG_ERROR, 5150 "OSU_SSID and " 5151 "WLAN_TAG2 SSID differ"); 5152 return -2; 5153 } 5154 fprintf(f, "osu_ssid=\"%s\"\n", dut->ap_osu_ssid); 5155 } else 5156 fprintf(f, "osu_ssid=\"%s\"\n", osu_ssid); 5157 5158 5159 if (osu_friendly_name) 5160 fprintf(f, "osu_friendly_name=%s\n", osu_friendly_name); 5161 5162 if (osu_service_desc) 5163 fprintf(f, "osu_service_desc=%s\n", osu_service_desc); 5164 5165 if (osu_nai) 5166 fprintf(f, "osu_nai=%s\n", osu_nai); 5167 if (osu_nai2) 5168 fprintf(f, "osu_nai2=%s\n", osu_nai2); 5169 5170 fprintf(f, "hs20_icon=%s\n", hs20_icon); 5171 5172 if (osu_icon) 5173 fprintf(f, "osu_icon=%s\n", osu_icon); 5174 5175 if (dut->ap_osu_provider_list > 100) 5176 fprintf(f, "osu_method_list=0\n"); 5177 else 5178 fprintf(f, "osu_method_list=%d\n", osu_method); 5179 } 5180 5181 switch (dut->ap_venue_url) { 5182 case 1: 5183 fprintf(f, 5184 "venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5185 "venue_url=1:https://venue-server.r2m-testbed.wi-fi.org/directory/index.html\n"); 5186 break; 5187 case 2: 5188 fprintf(f, 5189 "venue_url=1:https://the-great-mall.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5190 "venue_url=2:https://abercrombie.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5191 "venue_url=3:https://adidas.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5192 "venue_url=4:https://aeropostale.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5193 "venue_url=5:https://agaci.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5194 "venue_url=6:https://aldo-shoes.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5195 "venue_url=7:https://american-eagle-outfitters.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5196 "venue_url=8:https://anderson-bakery.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5197 "venue_url=9:https://banana-republic-factory-store.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5198 "venue_url=10:https://bed-bath-and-beyond.r2m-testbed.wi-fi.org/floorplans/index.html\n" 5199 ); 5200 break; 5201 } 5202 5203 switch (dut->ap_advice_of_charge) { 5204 case 1: 5205 fprintf(f, "anqp_elem=278:" ADV_OF_CHARGE_1 "\n"); 5206 break; 5207 } 5208 5209 switch (dut->ap_oper_icon_metadata) { 5210 case 1: 5211 fprintf(f, 5212 "hs20_icon=160:76:eng:image/png:icon_red_eng.png:/etc/ath/icon_red_eng.png\n" 5213 "operator_icon=icon_red_eng.png\n"); 5214 break; 5215 } 5216 5217 switch (dut->ap_tnc_file_name) { 5218 case 1: 5219 fprintf(f, "hs20_t_c_filename=tandc-id1-content.txt\n"); 5220 break; 5221 } 5222 5223 if (dut->ap_tnc_time_stamp) 5224 fprintf(f, "hs20_t_c_timestamp=%u\n", dut->ap_tnc_time_stamp); 5225 5226 return 0; 5227 } 5228 5229 5230 static void write_ap_roaming_cons(FILE *f, const char *list) 5231 { 5232 char *buf, *pos, *end; 5233 5234 if (list == NULL || list[0] == '\0') 5235 return; 5236 5237 buf = strdup(list); 5238 if (buf == NULL) 5239 return; 5240 5241 pos = buf; 5242 while (pos && *pos) { 5243 end = strchr(pos, ';'); 5244 if (end) 5245 *end++ = '\0'; 5246 fprintf(f, "roaming_consortium=%s\n", pos); 5247 pos = end; 5248 } 5249 5250 free(buf); 5251 } 5252 5253 5254 static int append_hostapd_conf_interworking(struct sigma_dut *dut, FILE *f) 5255 { 5256 int i; 5257 char buf[100], *temp; 5258 5259 if (dut->ap_gas_cb_delay > 0) 5260 fprintf(f, "gas_comeback_delay=%d\n", 5261 dut->ap_gas_cb_delay); 5262 5263 fprintf(f, "interworking=1\n" 5264 "access_network_type=%d\n" 5265 "internet=%d\n" 5266 "asra=0\n" 5267 "esr=0\n" 5268 "uesa=0\n" 5269 "venue_group=%d\n" 5270 "venue_type=%d\n", 5271 dut->ap_access_net_type, 5272 dut->ap_internet, 5273 dut->ap_venue_group, 5274 dut->ap_venue_type); 5275 if (dut->ap_hessid[0]) 5276 fprintf(f, "hessid=%s\n", dut->ap_hessid); 5277 5278 write_ap_roaming_cons(f, dut->ap_roaming_cons); 5279 5280 if (dut->ap_venue_name) { 5281 fprintf(f, "venue_name=P\"eng:Wi-Fi Alliance\\n2989 Copper Road\\nSanta Clara, CA 95051, USA\"\n"); 5282 fprintf(f, "venue_name=%s\n", ANQP_VENUE_NAME_1_CHI); 5283 } 5284 5285 if (dut->ap_net_auth_type == 1) 5286 fprintf(f, "network_auth_type=00https://tandc-server.wi-fi.org\n"); 5287 else if (dut->ap_net_auth_type == 2) 5288 fprintf(f, "network_auth_type=01\n"); 5289 5290 if (dut->ap_nai_realm_list == 1) { 5291 fprintf(f, "nai_realm=0,mail.example.com;cisco.com;wi-fi.org,21[2:4][5:7]\n"); 5292 fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n"); 5293 } else if (dut->ap_nai_realm_list == 2) { 5294 fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n"); 5295 } else if (dut->ap_nai_realm_list == 3) { 5296 fprintf(f, "nai_realm=0,cisco.com;wi-fi.org,21[2:4][5:7]\n"); 5297 fprintf(f, "nai_realm=0,wi-fi.org;example.com,13[5:6]\n"); 5298 } else if (dut->ap_nai_realm_list == 4) { 5299 fprintf(f, "nai_realm=0,mail.example.com,21[2:4][5:7],13[5:6]\n"); 5300 } else if (dut->ap_nai_realm_list == 5) { 5301 fprintf(f, "nai_realm=0,wi-fi.org;ruckuswireless.com,21[2:4][5:7]\n"); 5302 } else if (dut->ap_nai_realm_list == 6) { 5303 fprintf(f, "nai_realm=0,wi-fi.org;mail.example.com,21[2:4][5:7]\n"); 5304 } else if (dut->ap_nai_realm_list == 7) { 5305 fprintf(f, "nai_realm=0,wi-fi.org,13[5:6]\n"); 5306 fprintf(f, "nai_realm=0,wi-fi.org,21[2:4][5:7]\n"); 5307 } 5308 5309 if (dut->ap_domain_name_list[0]) { 5310 fprintf(f, "domain_name=%s\n", 5311 dut->ap_domain_name_list); 5312 } 5313 5314 if (dut->ap_ip_addr_type_avail == 1) { 5315 fprintf(f, "ipaddr_type_availability=0c\n"); 5316 } 5317 5318 temp = buf; 5319 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; 5320 i++) { 5321 if (i) 5322 *temp++ = ';'; 5323 5324 snprintf(temp, 5325 sizeof(dut->ap_plmn_mcc[i]) + 5326 sizeof(dut->ap_plmn_mnc[i]) + 1, 5327 "%s,%s", 5328 dut->ap_plmn_mcc[i], 5329 dut->ap_plmn_mnc[i]); 5330 5331 temp += strlen(dut->ap_plmn_mcc[i]) + 5332 strlen(dut->ap_plmn_mnc[i]) + 1; 5333 } 5334 if (i) 5335 fprintf(f, "anqp_3gpp_cell_net=%s\n", buf); 5336 5337 if (dut->ap_qos_map_set == 1) 5338 fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_1); 5339 else if (dut->ap_qos_map_set == 2) 5340 fprintf(f, "qos_map_set=%s\n", QOS_MAP_SET_2); 5341 5342 return 0; 5343 } 5344 5345 5346 static int ath_ap_append_hostapd_conf(struct sigma_dut *dut) 5347 { 5348 FILE *f; 5349 5350 if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 || 5351 system("killall hostapd") == 0) { 5352 int i; 5353 5354 /* Wait some time to allow hostapd to complete cleanup before 5355 * starting a new process */ 5356 for (i = 0; i < 10; i++) { 5357 usleep(500000); 5358 if (system("pidof hostapd") != 0) 5359 break; 5360 } 5361 } 5362 5363 f = fopen("/tmp/secath0", "a"); 5364 if (f == NULL) 5365 return -2; 5366 5367 if (dut->ap_hs2 && append_hostapd_conf_hs2(dut, f)) { 5368 fclose(f); 5369 return -2; 5370 } 5371 5372 if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) { 5373 fclose(f); 5374 return -2; 5375 } 5376 5377 fflush(f); 5378 fclose(f); 5379 return ath_ap_start_hostapd(dut); 5380 } 5381 5382 5383 static int ath_ap_start_hostapd(struct sigma_dut *dut) 5384 { 5385 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) 5386 run_system(dut, "hostapd -B /tmp/secath0 /tmp/secath1 -e /etc/wpa2/entropy"); 5387 else 5388 run_system(dut, "hostapd -B /tmp/secath0 -e /etc/wpa2/entropy"); 5389 5390 return 0; 5391 } 5392 5393 5394 #define LE16(a) ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff)) 5395 5396 static int cmd_ath_ap_anqpserver_start(struct sigma_dut *dut) 5397 { 5398 FILE *f; 5399 int nai_realm = 0, domain_name = 0, oper_name = 0, venue_name = 0, 5400 wan_metrics = 0, conn_cap = 0, ipaddr_avail = 0, cell_net = 0; 5401 char buf[100]; 5402 int i; 5403 5404 f = fopen("/root/anqpserver.conf", "w"); 5405 if (f == NULL) 5406 return -1; 5407 5408 if (dut->ap_nai_realm_list == 1) { 5409 nai_realm = 1; 5410 fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n"); 5411 } else if (dut->ap_nai_realm_list == 2) { 5412 nai_realm = 1; 5413 fprintf(f, "dyn_nai_home_realm=encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n"); 5414 } else if (dut->ap_nai_realm_list == 3) { 5415 nai_realm = 1; 5416 fprintf(f, "dyn_nai_home_realm=encoding=00realm=cisco.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=wi-fi.org;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=example.com;eap_method=0Dauth_id=05auth_val=06encoding=00realm=wi-fi.org;eap_method=0Dauth_id=05auth_val=06\n"); 5417 } else if (dut->ap_nai_realm_list == 4) { 5418 nai_realm = 1; 5419 fprintf(f, "dyn_nai_home_realm=encoding=00realm=mail.example.com;eap_method=15auth_id=02auth_val=04auth_id=05auth_val=07encoding=00realm=mail.example.com;eap_method=0Dauth_id=05auth_val=06\n"); 5420 } else 5421 sigma_dut_print(dut, DUT_MSG_INFO, "not setting nai_realm"); 5422 5423 if (dut->ap_domain_name_list[0]) { 5424 char *next, *start, *dnbuf, *dn1, *anqp_dn; 5425 int len, dn_len_max; 5426 dnbuf = strdup(dut->ap_domain_name_list); 5427 if (dnbuf == NULL) { 5428 fclose(f); 5429 return 0; 5430 } 5431 5432 len = strlen(dnbuf); 5433 dn_len_max = 50 + len*2; 5434 anqp_dn = malloc(dn_len_max); 5435 if (anqp_dn == NULL) { 5436 free(dnbuf); 5437 fclose(f); 5438 return -1; 5439 } 5440 start = dnbuf; 5441 dn1 = anqp_dn; 5442 while (start && *start) { 5443 char *hexstr; 5444 5445 next = strchr(start, ','); 5446 if (next) 5447 *next++ = '\0'; 5448 5449 len = strlen(start); 5450 hexstr = malloc(len * 2 + 1); 5451 if (hexstr == NULL) { 5452 free(dnbuf); 5453 free(anqp_dn); 5454 fclose(f); 5455 return -1; 5456 } 5457 ascii2hexstr(start, hexstr); 5458 snprintf(dn1, dn_len_max, "%02x%s", len, hexstr); 5459 free(hexstr); 5460 dn1 += 2 + len * 2; 5461 dn_len_max -= 2 + len * 2; 5462 start = next; 5463 } 5464 free(dnbuf); 5465 if (dut->ap_gas_cb_delay) { 5466 fprintf(f, "dyn_domain_name=0c01%04x%s", 5467 LE16((unsigned int) strlen(anqp_dn)), anqp_dn); 5468 domain_name = 1; 5469 } else 5470 fprintf(f, "domain_name=0c01%04x%s", 5471 LE16((unsigned int) strlen(anqp_dn)), anqp_dn); 5472 free(anqp_dn); 5473 } else 5474 sigma_dut_print(dut, DUT_MSG_INFO, "not setting domain_name"); 5475 5476 sigma_dut_print(dut, DUT_MSG_INFO, "not setting roaming_consortium"); 5477 5478 if (dut->ap_oper_name) { 5479 if (dut->ap_gas_cb_delay) { 5480 fprintf(f, "dyn_oper_friendly_name=" 5481 ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n"); 5482 oper_name = 1; 5483 } else 5484 fprintf(f, "oper_friendly_name=" 5485 ANQP_HS20_OPERATOR_FRIENDLY_NAME_1 "\n"); 5486 } else 5487 sigma_dut_print(dut, DUT_MSG_INFO, "not setting oper_name"); 5488 5489 if (dut->ap_venue_name) { 5490 if (dut->ap_gas_cb_delay) { 5491 fprintf(f, "dyn_venue_name=" ANQP_VENUE_NAME_1 "\n"); 5492 venue_name = 1; 5493 } else 5494 fprintf(f, "venue_name=" ANQP_VENUE_NAME_1 "\n"); 5495 } else 5496 sigma_dut_print(dut, DUT_MSG_ERROR, "not setting venue_name"); 5497 5498 if (dut->ap_wan_metrics) { 5499 if (dut->ap_gas_cb_delay) { 5500 fprintf(f, "dyn_wan_metrics=" ANQP_HS20_WAN_METRICS_1 "\n"); 5501 wan_metrics = 1; 5502 } else 5503 fprintf(f, "wan_metrics=" ANQP_HS20_WAN_METRICS_1 5504 "\n"); 5505 } else 5506 sigma_dut_print(dut, DUT_MSG_ERROR, "not setting wan_metrics"); 5507 5508 if (dut->ap_conn_capab) { 5509 if (dut->ap_gas_cb_delay) { 5510 fprintf(f, "dyn_conn_capability=" 5511 ANQP_HS20_CONNECTION_CAPABILITY_1 "\n"); 5512 conn_cap = 1; 5513 } else 5514 fprintf(f, "conn_capability=" 5515 ANQP_HS20_CONNECTION_CAPABILITY_1 "\n"); 5516 } else 5517 sigma_dut_print(dut, DUT_MSG_ERROR, 5518 "not setting conn_capability"); 5519 5520 if (dut->ap_ip_addr_type_avail) { 5521 if (dut->ap_gas_cb_delay) { 5522 fprintf(f, "dyn_ipaddr_type=" ANQP_IP_ADDR_TYPE_1 5523 "\n"); 5524 ipaddr_avail = 1; 5525 } else 5526 fprintf(f, "ipaddr_type=" ANQP_IP_ADDR_TYPE_1 "\n"); 5527 } else 5528 sigma_dut_print(dut, DUT_MSG_ERROR, 5529 "not setting ipaddr_type_avail"); 5530 5531 for (i = 0; dut->ap_plmn_mcc[i][0] && dut->ap_plmn_mnc[i][0]; i++) { 5532 snprintf(buf + i * 6, sizeof(buf) - i * 6, "%c%c%c%c%c%c", 5533 dut->ap_plmn_mcc[i][1], 5534 dut->ap_plmn_mcc[i][0], 5535 dut->ap_plmn_mnc[i][2] == '\0' ? 5536 'f' : dut->ap_plmn_mnc[i][2], 5537 dut->ap_plmn_mcc[i][2], 5538 dut->ap_plmn_mnc[i][1], 5539 dut->ap_plmn_mnc[i][0]); 5540 } 5541 if (i) { 5542 uint16_t ie_len = (i * 3) + 5; 5543 if (dut->ap_gas_cb_delay) { 5544 fprintf(f, "dyn_cell_net=0801"); 5545 cell_net = 1; 5546 } else 5547 fprintf(f, "cell_net=0801"); 5548 fprintf(f, "%04x", LE16(ie_len)); 5549 fprintf(f, "00"); /* version */ 5550 fprintf(f, "%02x", (i * 3) + 3); /* user data hdr length */ 5551 fprintf(f, "00"); /* plmn list */ 5552 fprintf(f, "%02x", (i * 3) + 1); /* length of plmn list */ 5553 fprintf(f, "%02x", i); /* number of plmns */ 5554 fprintf(f, "%s\n", buf); /* plmns */ 5555 } else 5556 sigma_dut_print(dut, DUT_MSG_ERROR, 5557 "not setting 3gpp_cellular_network"); 5558 5559 if (nai_realm || domain_name || oper_name || venue_name || 5560 wan_metrics || conn_cap || ipaddr_avail || cell_net) { 5561 fprintf(f, "anqp_attach="); 5562 if (venue_name) 5563 fprintf(f, "00000104%4.4x", dut->ap_gas_cb_delay); 5564 if (nai_realm) 5565 fprintf(f, "00000107%4.4x", dut->ap_gas_cb_delay); 5566 if (cell_net) 5567 fprintf(f, "00000108%4.4x", dut->ap_gas_cb_delay); 5568 if (domain_name) 5569 fprintf(f, "0000010c%4.4x", dut->ap_gas_cb_delay); 5570 if (oper_name) 5571 fprintf(f, "00010003%4.4x", dut->ap_gas_cb_delay); 5572 if (wan_metrics) 5573 fprintf(f, "00010004%4.4x", dut->ap_gas_cb_delay); 5574 if (conn_cap) 5575 fprintf(f, "00010005%4.4x", dut->ap_gas_cb_delay); 5576 fprintf(f, "00010006%4.4x", dut->ap_gas_cb_delay); 5577 fprintf(f, "\n"); 5578 } 5579 5580 fclose(f); 5581 5582 run_system(dut, "anqpserver -i ath0 &"); 5583 if (!dut->ap_anqpserver_on) 5584 run_system(dut, "killall anqpserver"); 5585 5586 return 1; 5587 } 5588 5589 5590 static void cmd_ath_ap_radio_config(struct sigma_dut *dut) 5591 { 5592 char buf[100]; 5593 5594 run_system(dut, "cfg -a AP_STARTMODE=standard"); 5595 5596 if (sigma_radio_ifname[0] && 5597 strcmp(sigma_radio_ifname[0], "wifi1") == 0) { 5598 run_system(dut, "cfg -a AP_RADIO_ID=1"); 5599 switch (dut->ap_mode) { 5600 case AP_11g: 5601 run_system(dut, "cfg -a AP_CHMODE_2=11G"); 5602 break; 5603 case AP_11b: 5604 run_system(dut, "cfg -a AP_CHMODE_2=11B"); 5605 break; 5606 case AP_11ng: 5607 run_system(dut, "cfg -a AP_CHMODE_2=11NGHT20"); 5608 break; 5609 case AP_11a: 5610 run_system(dut, "cfg -a AP_CHMODE_2=11A"); 5611 break; 5612 case AP_11na: 5613 run_system(dut, "cfg -a AP_CHMODE_2=11NAHT20"); 5614 break; 5615 case AP_11ac: 5616 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5617 break; 5618 default: 5619 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5620 break; 5621 } 5622 5623 switch (dut->ap_rx_streams) { 5624 case 1: 5625 run_system(dut, "cfg -a RX_CHAINMASK_2=1"); 5626 break; 5627 case 2: 5628 run_system(dut, "cfg -a RX_CHAINMASK_2=3"); 5629 break; 5630 case 3: 5631 run_system(dut, "cfg -a RX_CHAINMASK_2=7"); 5632 break; 5633 } 5634 5635 switch (dut->ap_tx_streams) { 5636 case 1: 5637 run_system(dut, "cfg -a TX_CHAINMASK_2=1"); 5638 break; 5639 case 2: 5640 run_system(dut, "cfg -a TX_CHAINMASK_2=3"); 5641 break; 5642 case 3: 5643 run_system(dut, "cfg -a TX_CHAINMASK_2=7"); 5644 break; 5645 } 5646 5647 switch (dut->ap_chwidth) { 5648 case AP_20: 5649 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT20"); 5650 break; 5651 case AP_40: 5652 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT40"); 5653 break; 5654 case AP_80: 5655 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5656 break; 5657 case AP_160: 5658 case AP_AUTO: 5659 default: 5660 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 5661 break; 5662 } 5663 5664 if (dut->ap_tx_stbc) { 5665 run_system(dut, "cfg -a TX_STBC_2=1"); 5666 } 5667 5668 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH_2=%d", 5669 dut->ap_channel); 5670 5671 if (dut->ap_is_dual) { 5672 switch (dut->ap_mode_1) { 5673 case AP_11g: 5674 run_system(dut, "cfg -a AP_CHMODE=11G"); 5675 break; 5676 case AP_11b: 5677 run_system(dut, "cfg -a AP_CHMODE=11B"); 5678 break; 5679 case AP_11ng: 5680 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5681 break; 5682 case AP_11a: 5683 run_system(dut, "cfg -a AP_CHMODE=11A"); 5684 break; 5685 case AP_11na: 5686 run_system(dut, "cfg -a AP_CHMODE=11NAHT20"); 5687 break; 5688 case AP_11ac: 5689 run_system(dut, "cfg -a AP_CHMODE=11ACVHT80"); 5690 break; 5691 default: 5692 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5693 break; 5694 } 5695 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d", 5696 dut->ap_channel_1); 5697 } 5698 run_system(dut, buf); 5699 } else { 5700 run_system(dut, "cfg -a AP_RADIO_ID=0"); 5701 switch (dut->ap_mode) { 5702 case AP_11g: 5703 run_system(dut, "cfg -a AP_CHMODE=11G"); 5704 break; 5705 case AP_11b: 5706 run_system(dut, "cfg -a AP_CHMODE=11B"); 5707 break; 5708 case AP_11ng: 5709 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5710 break; 5711 case AP_11a: 5712 run_system(dut, "cfg -a AP_CHMODE=11A"); 5713 break; 5714 case AP_11na: 5715 run_system(dut, "cfg -a AP_CHMODE=11NAHT20"); 5716 break; 5717 case AP_11ac: 5718 run_system(dut, "cfg -a AP_CHMODE=11ACVHT80"); 5719 break; 5720 default: 5721 run_system(dut, "cfg -a AP_CHMODE=11NGHT20"); 5722 break; 5723 } 5724 snprintf(buf, sizeof(buf), "cfg -a AP_PRIMARY_CH=%d", 5725 dut->ap_channel); 5726 run_system(dut, buf); 5727 } 5728 5729 if (dut->ap_sgi80 == 1) { 5730 run_system(dut, "cfg -a SHORTGI=1"); 5731 run_system(dut, "cfg -a SHORTGI_2=1"); 5732 } else if (dut->ap_sgi80 == 0) { 5733 run_system(dut, "cfg -a SHORTGI=0"); 5734 run_system(dut, "cfg -a SHORTGI_2=0"); 5735 } 5736 5737 if (dut->ap_ldpc == VALUE_ENABLED) 5738 run_system(dut, "cfg -a LDPC=1"); 5739 else if (dut->ap_ldpc == VALUE_DISABLED) 5740 run_system(dut, "cfg -a LDPC=0"); 5741 } 5742 5743 5744 void ath_disable_txbf(struct sigma_dut *dut, const char *intf) 5745 { 5746 run_iwpriv(dut, intf, "vhtsubfee 0"); 5747 run_iwpriv(dut, intf, "vhtsubfer 0"); 5748 run_iwpriv(dut, intf, "vhtmubfee 0"); 5749 run_iwpriv(dut, intf, "vhtmubfer 0"); 5750 } 5751 5752 5753 static void ath_set_assoc_disallow(struct sigma_dut *dut, const char *ifname, 5754 const char *val) 5755 { 5756 if (strcasecmp(val, "enable") == 0) { 5757 run_iwpriv(dut, ifname, "mbo_asoc_dis 1"); 5758 } else if (strcasecmp(val, "disable") == 0) { 5759 run_iwpriv(dut, ifname, "mbo_asoc_dis 0"); 5760 } else { 5761 sigma_dut_print(dut, DUT_MSG_ERROR, 5762 "Unsupported assoc_disallow"); 5763 } 5764 } 5765 5766 5767 static void apply_mbo_pref_ap_list(struct sigma_dut *dut) 5768 { 5769 int i; 5770 int least_pref = 1 << 8; 5771 char ifname[20]; 5772 uint8_t self_mac[ETH_ALEN]; 5773 char buf[200]; 5774 int ap_ne_class, ap_ne_pref, ap_ne_op_ch; 5775 5776 get_if_name(dut, ifname, sizeof(ifname), 1); 5777 get_hwaddr(ifname, self_mac); 5778 5779 /* Clear off */ 5780 snprintf(buf, sizeof(buf), 5781 "wifitool %s setbssidpref 00:00:00:00:00:00 0 0 0", 5782 ifname); 5783 run_system(dut, buf); 5784 5785 /* Find the least preference number */ 5786 for (i = 0; i < dut->mbo_pref_ap_cnt; i++) { 5787 unsigned char *mac_addr = dut->mbo_pref_aps[i].mac_addr; 5788 5789 ap_ne_class = 1; 5790 ap_ne_pref = 255; 5791 ap_ne_op_ch = 1; 5792 if (dut->mbo_pref_aps[i].ap_ne_pref != -1) 5793 ap_ne_pref = dut->mbo_pref_aps[i].ap_ne_pref; 5794 if (dut->mbo_pref_aps[i].ap_ne_class != -1) 5795 ap_ne_class = dut->mbo_pref_aps[i].ap_ne_class; 5796 if (dut->mbo_pref_aps[i].ap_ne_op_ch != -1) 5797 ap_ne_op_ch = dut->mbo_pref_aps[i].ap_ne_op_ch; 5798 5799 if (ap_ne_pref < least_pref) 5800 least_pref = ap_ne_pref; 5801 snprintf(buf, sizeof(buf), 5802 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d", 5803 ifname, mac_addr[0], mac_addr[1], mac_addr[2], 5804 mac_addr[3], mac_addr[4], mac_addr[5], 5805 ap_ne_pref, ap_ne_class, ap_ne_op_ch); 5806 run_system(dut, buf); 5807 } 5808 5809 /* Now add the self AP Address */ 5810 if (dut->mbo_self_ap_tuple.ap_ne_class == -1) { 5811 if (dut->ap_channel <= 11) 5812 ap_ne_class = 81; 5813 else 5814 ap_ne_class = 115; 5815 } else { 5816 ap_ne_class = dut->mbo_self_ap_tuple.ap_ne_class; 5817 } 5818 5819 if (dut->mbo_self_ap_tuple.ap_ne_op_ch == -1) 5820 ap_ne_op_ch = dut->ap_channel; 5821 else 5822 ap_ne_op_ch = dut->mbo_self_ap_tuple.ap_ne_op_ch; 5823 5824 if (dut->mbo_self_ap_tuple.ap_ne_pref == -1) 5825 ap_ne_pref = least_pref - 1; 5826 else 5827 ap_ne_pref = dut->mbo_self_ap_tuple.ap_ne_pref; 5828 5829 snprintf(buf, sizeof(buf), 5830 "wifitool %s setbssidpref %02x:%02x:%02x:%02x:%02x:%02x %d %d %d", 5831 ifname, self_mac[0], self_mac[1], self_mac[2], 5832 self_mac[3], self_mac[4], self_mac[5], 5833 ap_ne_pref, 5834 ap_ne_class, 5835 ap_ne_op_ch); 5836 run_system(dut, buf); 5837 } 5838 5839 5840 static void mubrp_commands(struct sigma_dut *dut, const char *ifname) 5841 { 5842 run_iwpriv(dut, ifname, "he_subfer 1"); 5843 run_iwpriv(dut, ifname, "he_mubfer 1"); 5844 /* To enable MU_AX with MU_BRP trigger */ 5845 run_iwpriv(dut, ifname, "he_sounding_mode 13"); 5846 /* Sets g_force_1x1_peer to 1 which should be reset to zero for non MU 5847 * test cases */ 5848 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 118 1", 5849 ifname); 5850 /* Disable DL OFDMA */ 5851 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 11 0", 5852 ifname); 5853 } 5854 5855 5856 static void ath_ap_set_params(struct sigma_dut *dut) 5857 { 5858 const char *basedev = "wifi0"; 5859 const char *basedev_radio = "wifi1"; 5860 const char *ifname = get_main_ifname(dut); 5861 char *ifname_dual = NULL; 5862 int i; 5863 char buf[300]; 5864 unsigned int he_mcsnssmap = dut->he_mcsnssmap; 5865 5866 if (sigma_radio_ifname[0]) 5867 basedev = sigma_radio_ifname[0]; 5868 5869 if (dut->ap_is_dual == 1) { 5870 basedev = sigma_radio_ifname[0]; 5871 basedev_radio = sigma_radio_ifname[1]; 5872 if (sigma_radio_ifname[0] && 5873 strcmp(sigma_radio_ifname[0], "wifi0") == 0) { 5874 ifname = "ath0"; 5875 ifname_dual = "ath1"; 5876 } else { 5877 ifname = "ath1"; 5878 ifname_dual = "ath0"; 5879 } 5880 } 5881 5882 if (dut->ap_countrycode[0]) { 5883 run_iwpriv(dut, basedev, "setCountry %s", dut->ap_countrycode); 5884 sigma_dut_print(dut, DUT_MSG_INFO, "Set countrycode"); 5885 } 5886 5887 for (i = 0; i < NUM_AP_AC; i++) { 5888 if (dut->ap_qos[i].ac) { 5889 run_iwpriv(dut, ifname, "cwmin %d 0 %d", i, 5890 dut->ap_qos[i].cwmin); 5891 run_iwpriv(dut, ifname, "cwmax %d 0 %d", i, 5892 dut->ap_qos[i].cwmax); 5893 run_iwpriv(dut, ifname, "aifs %d 0 %d", i, 5894 dut->ap_qos[i].aifs); 5895 run_iwpriv(dut, ifname, "txoplimit %d 0 %d", i, 5896 dut->ap_qos[i].txop); 5897 run_iwpriv(dut, ifname, "acm %d 0 %d", i, 5898 dut->ap_qos[i].acm); 5899 } 5900 } 5901 5902 for (i = 0; i < NUM_AP_AC; i++) { 5903 if (dut->ap_sta_qos[i].ac) { 5904 run_iwpriv(dut, ifname, "cwmin %d 1 %d", i, 5905 dut->ap_sta_qos[i].cwmin); 5906 run_iwpriv(dut, ifname, "cwmax %d 1 %d", i, 5907 dut->ap_sta_qos[i].cwmax); 5908 run_iwpriv(dut, ifname, "aifs %d 1 %d", i, 5909 dut->ap_sta_qos[i].aifs); 5910 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", i, 5911 dut->ap_sta_qos[i].txop); 5912 run_iwpriv(dut, ifname, "acm %d 1 %d", i, 5913 dut->ap_sta_qos[i].acm); 5914 } 5915 } 5916 5917 if (dut->ap_disable_protection == 1) { 5918 run_iwpriv(dut, ifname, "enablertscts 0"); 5919 sigma_dut_print(dut, DUT_MSG_INFO, "Disabled rtscts"); 5920 } 5921 5922 if (dut->ap_ldpc == VALUE_ENABLED) 5923 run_iwpriv(dut, ifname, "ldpc 3"); 5924 else if (dut->ap_ldpc == VALUE_DISABLED) 5925 run_iwpriv(dut, ifname, "ldpc 0"); 5926 5927 if (dut->ap_ampdu == VALUE_ENABLED) { 5928 run_iwpriv(dut, ifname, "ampdu 1"); 5929 } else if (dut->ap_ampdu == VALUE_DISABLED) { 5930 run_iwpriv(dut, ifname, "ampdu 0"); 5931 if (dut->program == PROGRAM_HE) { 5932 run_iwpriv(dut, ifname, "setaddbaoper 1"); 5933 run_system_wrapper(dut, "wifitool %s refusealladdbas 1", 5934 ifname); 5935 if (dut->ap_amsdu == VALUE_ENABLED) { 5936 /* disable the limit for A-MSDU */ 5937 run_system_wrapper(dut, 5938 "wifitool %s setUnitTestCmd 0x48 2 46 1", 5939 ifname); 5940 } 5941 } 5942 } 5943 5944 if (dut->ap_ampdu_exp) { 5945 if (dut->program == PROGRAM_VHT) { 5946 run_iwpriv(dut, ifname, "vhtmaxampdu %d", 5947 dut->ap_ampdu_exp); 5948 } else { 5949 /* 11N */ 5950 run_iwpriv(dut, ifname, "maxampdu %d", 5951 dut->ap_ampdu_exp); 5952 } 5953 } 5954 5955 if (dut->ap_noack == VALUE_ENABLED) { 5956 run_iwpriv(dut, ifname, "noackpolicy 0 0 1"); 5957 run_iwpriv(dut, ifname, "noackpolicy 1 0 1"); 5958 run_iwpriv(dut, ifname, "noackpolicy 2 0 1"); 5959 run_iwpriv(dut, ifname, "noackpolicy 3 0 1"); 5960 } else if (dut->ap_noack == VALUE_DISABLED) { 5961 run_iwpriv(dut, ifname, "noackpolicy 0 0 0"); 5962 run_iwpriv(dut, ifname, "noackpolicy 1 0 0"); 5963 run_iwpriv(dut, ifname, "noackpolicy 2 0 0"); 5964 run_iwpriv(dut, ifname, "noackpolicy 3 0 0"); 5965 } 5966 5967 if (dut->device_type == AP_testbed && dut->ap_vhtmcs_map) 5968 run_iwpriv(dut, ifname, "vht_mcsmap 0x%04x", 5969 dut->ap_vhtmcs_map); 5970 5971 if (dut->ap_amsdu == VALUE_ENABLED) 5972 run_iwpriv(dut, ifname, "amsdu 2"); 5973 else if (dut->ap_amsdu == VALUE_DISABLED) 5974 run_iwpriv(dut, ifname, "amsdu 1"); 5975 5976 if (dut->ap_rx_amsdu == VALUE_ENABLED) 5977 run_iwpriv(dut, basedev_radio, "rx_amsdu 1"); 5978 else if (dut->ap_rx_amsdu == VALUE_DISABLED) 5979 run_iwpriv(dut, basedev_radio, "rx_amsdu 0"); 5980 5981 /* Command sequence to generate single VHT AMSDU and MPDU */ 5982 if (dut->ap_addba_reject != VALUE_NOT_SET && 5983 dut->ap_ampdu == VALUE_DISABLED && 5984 dut->ap_amsdu == VALUE_ENABLED) { 5985 run_iwpriv(dut, ifname, "setaddbaoper 1"); 5986 5987 snprintf(buf, sizeof(buf), 5988 "wifitool %s senddelba 1 0 1 4", ifname); 5989 if (system(buf) != 0) { 5990 sigma_dut_print(dut, DUT_MSG_ERROR, 5991 "wifitool senddelba failed"); 5992 } 5993 5994 snprintf(buf, sizeof(buf), "wifitool %s sendsingleamsdu 1 0", 5995 ifname); 5996 if (system(buf) != 0) { 5997 sigma_dut_print(dut, DUT_MSG_ERROR, 5998 "wifitool sendsingleamsdu failed"); 5999 } 6000 6001 run_iwpriv(dut, ifname, "amsdu 10"); 6002 } 6003 6004 if (dut->ap_mode == AP_11ac) { 6005 int chwidth, nss; 6006 6007 switch (dut->ap_chwidth) { 6008 case AP_20: 6009 chwidth = 0; 6010 break; 6011 case AP_40: 6012 chwidth = 1; 6013 break; 6014 case AP_80: 6015 chwidth = 2; 6016 break; 6017 case AP_160: 6018 chwidth = 3; 6019 break; 6020 case AP_80_80: 6021 chwidth = 3; 6022 break; 6023 default: 6024 chwidth = 0; 6025 break; 6026 } 6027 6028 switch (dut->ap_tx_streams) { 6029 case 1: 6030 nss = 1; 6031 break; 6032 case 2: 6033 nss = 2; 6034 break; 6035 case 3: 6036 nss = 3; 6037 break; 6038 case 4: 6039 nss = 4; 6040 break; 6041 default: 6042 nss = 3; 6043 break; 6044 } 6045 6046 if (dut->ap_fixed_rate) { 6047 if (nss == 4) 6048 ath_disable_txbf(dut, ifname); 6049 6050 /* Set the nss */ 6051 run_iwpriv(dut, ifname, "nss %d", nss); 6052 6053 /* Set the channel width */ 6054 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 6055 6056 /* Set the VHT MCS */ 6057 run_iwpriv(dut, ifname, "vhtmcs %d", dut->ap_mcs); 6058 } 6059 } 6060 6061 if (dut->ap_dyn_bw_sig == VALUE_ENABLED) 6062 run_iwpriv(dut, ifname, "cwmenable 1"); 6063 else if (dut->ap_dyn_bw_sig == VALUE_DISABLED) 6064 run_iwpriv(dut, ifname, "cwmenable 0"); 6065 6066 if (dut->ap_sig_rts == VALUE_ENABLED) { 6067 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", ifname); 6068 if (system(buf) != 0) { 6069 sigma_dut_print(dut, DUT_MSG_ERROR, 6070 "iwconfig rts 64 failed"); 6071 } 6072 } else if (dut->ap_sig_rts == VALUE_DISABLED) { 6073 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", ifname); 6074 if (system(buf) != 0) { 6075 sigma_dut_print(dut, DUT_MSG_ERROR, 6076 "iwconfig rts 2347 failed"); 6077 } 6078 } 6079 6080 if (dut->ap_hs2) { 6081 run_iwpriv(dut, ifname, "qbssload 1"); 6082 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled qbssload"); 6083 } 6084 6085 if (dut->ap_bss_load && dut->ap_bss_load != -1) { 6086 unsigned int bssload = 0; 6087 6088 if (dut->ap_bss_load == 1) { 6089 /* STA count: 1, CU: 50, AAC: 65535 */ 6090 bssload = 0x0132ffff; 6091 } else if (dut->ap_bss_load == 2) { 6092 /* STA count: 1, CU: 200, AAC: 65535 */ 6093 bssload = 0x01c8ffff; 6094 } else if (dut->ap_bss_load == 3) { 6095 /* STA count: 1, CU: 75, AAC: 65535 */ 6096 bssload = 0x014bffff; 6097 } 6098 6099 run_iwpriv(dut, ifname, "hcbssload %u", bssload); 6100 } else if (dut->ap_bss_load == 0) { 6101 run_iwpriv(dut, ifname, "qbssload 0"); 6102 sigma_dut_print(dut, DUT_MSG_INFO, "Disabled qbssload"); 6103 } 6104 6105 if (dut->ap_dgaf_disable) { 6106 run_iwpriv(dut, ifname, "dgaf_disable 1"); 6107 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled dgaf_disable"); 6108 } 6109 6110 if (dut->ap_l2tif) { 6111 run_iwpriv(dut, ifname, "l2tif 1"); 6112 snprintf(buf, sizeof(buf), 6113 "echo 1 > /sys/class/net/br0/brif/ath0/hotspot_l2tif"); 6114 if (system(buf) != 0) 6115 sigma_dut_print(dut, DUT_MSG_ERROR, 6116 "l2tif br failed"); 6117 6118 snprintf(buf, sizeof(buf), 6119 "echo 1 > /sys/class/net/br0/brif/eth0/hotspot_wan"); 6120 if (system(buf) != 0) 6121 sigma_dut_print(dut, DUT_MSG_ERROR, 6122 "l2tif brif failed"); 6123 sigma_dut_print(dut, DUT_MSG_INFO, "Enabled l2tif"); 6124 } 6125 6126 if (dut->ap_ndpa_frame == 0) { 6127 snprintf(buf, sizeof(buf), 6128 "wifitool %s beeliner_fw_test 117 192", ifname); 6129 if (system(buf) != 0) { 6130 sigma_dut_print(dut, DUT_MSG_ERROR, 6131 "wifitool beeliner_fw_test 117 192 failed"); 6132 } 6133 snprintf(buf, sizeof(buf), 6134 "wifitool %s beeliner_fw_test 118 192", ifname); 6135 if (system(buf) != 0) { 6136 sigma_dut_print(dut, DUT_MSG_ERROR, 6137 "wifitool beeliner_fw_test 117 192 failed"); 6138 } 6139 } else if (dut->ap_ndpa_frame == 1) { 6140 /* Driver default - no changes needed */ 6141 } else if (dut->ap_ndpa_frame == 2) { 6142 snprintf(buf, sizeof(buf), 6143 "wifitool %s beeliner_fw_test 115 1", ifname); 6144 if (system(buf) != 0) { 6145 sigma_dut_print(dut, DUT_MSG_ERROR, 6146 "wifitool beeliner_fw_test 117 192 failed"); 6147 } 6148 snprintf(buf, sizeof(buf), 6149 "wifitool %s beeliner_fw_test 116 1", ifname); 6150 if (system(buf) != 0) { 6151 sigma_dut_print(dut, DUT_MSG_ERROR, 6152 "wifitool beeliner_fw_test 117 192 failed"); 6153 } 6154 } 6155 6156 if (dut->ap_rtt == 1) 6157 run_iwpriv(dut, ifname, "enable_rtt 1"); 6158 6159 if (dut->ap_lci == 1) 6160 run_iwpriv(dut, ifname, "enable_lci 1"); 6161 6162 if (dut->ap_lcr == 1) 6163 run_iwpriv(dut, ifname, "enable_lcr 1"); 6164 6165 if (dut->ap_rrm == 1) 6166 run_iwpriv(dut, ifname, "enable_rmm 1"); 6167 6168 if (dut->ap_lci == 1 || dut->ap_lcr == 1) { 6169 run_system(dut, "wpc -l /tmp/lci_cfg.txt"); 6170 } 6171 6172 if (dut->ap_neighap >= 1 && dut->ap_lci == 0) { 6173 FILE *f; 6174 6175 f = fopen("/tmp/nbr_report.txt", "w"); 6176 if (!f) { 6177 sigma_dut_print(dut, DUT_MSG_ERROR, 6178 "Failed to open /tmp/nbr_report.txt"); 6179 return; 6180 } 6181 6182 fprintf(f, 6183 "ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n", 6184 dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1], 6185 dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3], 6186 dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5], 6187 dut->ap_val_opchannel[0]); 6188 fclose(f); 6189 6190 f = fopen("/tmp/ftmrr.txt", "w"); 6191 if (!f) { 6192 sigma_dut_print(dut, DUT_MSG_ERROR, 6193 "Failed to open /tmp/ftmrr.txt"); 6194 return; 6195 } 6196 6197 fprintf(f, 6198 "ap_1 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x2a 0x00\n", 6199 dut->ap_val_neighap[0][0], dut->ap_val_neighap[0][1], 6200 dut->ap_val_neighap[0][2], dut->ap_val_neighap[0][3], 6201 dut->ap_val_neighap[0][4], dut->ap_val_neighap[0][5], 6202 dut->ap_val_opchannel[0]); 6203 fclose(f); 6204 } 6205 6206 if (dut->ap_neighap >= 2 && dut->ap_lci == 0) { 6207 FILE *f; 6208 6209 f = fopen("/tmp/nbr_report.txt", "a"); 6210 if (!f) { 6211 sigma_dut_print(dut, DUT_MSG_ERROR, 6212 "Failed to open /tmp/nbr_report.txt"); 6213 return; 6214 } 6215 fprintf(f, 6216 "ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n", 6217 dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1], 6218 dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3], 6219 dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5], 6220 dut->ap_val_opchannel[1]); 6221 fclose(f); 6222 6223 f = fopen("/tmp/ftmrr.txt", "a"); 6224 if (!f) { 6225 sigma_dut_print(dut, DUT_MSG_ERROR, 6226 "Failed to open /tmp/ftmrr.txt"); 6227 return; 6228 } 6229 fprintf(f, 6230 "ap_2 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x6a 0x00\n", 6231 dut->ap_val_neighap[1][0], dut->ap_val_neighap[1][1], 6232 dut->ap_val_neighap[1][2], dut->ap_val_neighap[1][3], 6233 dut->ap_val_neighap[1][4], dut->ap_val_neighap[1][5], 6234 dut->ap_val_opchannel[1]); 6235 fclose(f); 6236 } 6237 6238 if (dut->ap_neighap >= 3 && dut->ap_lci == 0) { 6239 FILE *f; 6240 6241 f = fopen("/tmp/nbr_report.txt", "a"); 6242 if (!f) { 6243 sigma_dut_print(dut, DUT_MSG_ERROR, 6244 "Failed to open /tmp/nbr_report.txt"); 6245 return; 6246 } 6247 6248 fprintf(f, 6249 "ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n", 6250 dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1], 6251 dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3], 6252 dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5], 6253 dut->ap_val_opchannel[2]); 6254 fclose(f); 6255 6256 f = fopen("/tmp/ftmrr.txt", "a"); 6257 if (!f) { 6258 sigma_dut_print(dut, DUT_MSG_ERROR, 6259 "Failed to open /tmp/ftmrr.txt"); 6260 return; 6261 } 6262 6263 fprintf(f, 6264 "ap_3 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x00 0x3c 0x00 0x00 0x80 0x%x 0x09 0x06 0x03 0x02 0x9b 0x00\n", 6265 dut->ap_val_neighap[2][0], dut->ap_val_neighap[2][1], 6266 dut->ap_val_neighap[2][2], dut->ap_val_neighap[2][3], 6267 dut->ap_val_neighap[2][4], dut->ap_val_neighap[2][5], 6268 dut->ap_val_opchannel[2]); 6269 fclose(f); 6270 } 6271 6272 if (dut->ap_neighap) { 6273 run_iwpriv(dut, ifname, "enable_rtt 1"); 6274 run_iwpriv(dut, ifname, "enable_lci 1"); 6275 run_iwpriv(dut, ifname, "enable_lcr 1"); 6276 run_iwpriv(dut, ifname, "enable_rrm 1"); 6277 } 6278 6279 if (dut->ap_scan == 1) { 6280 run_iwpriv(dut, ifname, "scanentryage 600"); 6281 snprintf(buf, sizeof(buf), "iwlist %s scan", ifname); 6282 run_system(dut, buf); 6283 } 6284 6285 if (dut->ap_set_bssidpref) { 6286 snprintf(buf, sizeof(buf), 6287 "wifitool %s setbssidpref 00:00:00:00:00:00 0 00 00", 6288 ifname); 6289 if (system(buf) != 0) { 6290 sigma_dut_print(dut, DUT_MSG_ERROR, 6291 "wifitool clear bssidpref failed"); 6292 } 6293 } 6294 6295 if (dut->wnm_bss_max_feature != VALUE_NOT_SET) { 6296 int feature_enable; 6297 6298 feature_enable = dut->wnm_bss_max_feature == VALUE_ENABLED; 6299 run_iwpriv(dut, ifname, "wnm %d", feature_enable); 6300 run_iwpriv(dut, ifname, "wnm_bss %d", feature_enable); 6301 if (feature_enable) { 6302 const char *extra = ""; 6303 6304 if (dut->wnm_bss_max_protection != VALUE_NOT_SET) { 6305 if (dut->wnm_bss_max_protection == 6306 VALUE_ENABLED) 6307 extra = " 1"; 6308 else 6309 extra = " 0"; 6310 } 6311 snprintf(buf, sizeof(buf), 6312 "wlanconfig %s wnm setbssmax %d%s", 6313 ifname, dut->wnm_bss_max_idle_time, extra); 6314 run_system(dut, buf); 6315 } 6316 } 6317 6318 if (dut->program == PROGRAM_MBO) { 6319 apply_mbo_pref_ap_list(dut); 6320 run_iwpriv(dut, ifname, "mbo_cel_pref %d", 6321 dut->ap_cell_cap_pref); 6322 run_iwpriv(dut, ifname, "mbocap 0x40"); 6323 ath_set_assoc_disallow(dut, ifname, "disable"); 6324 } 6325 6326 if (dut->ap_oce == VALUE_ENABLED) 6327 run_iwpriv(dut, ifname, "set_bpr_enable 1"); 6328 6329 if (dut->ap_oce == VALUE_ENABLED && dut->ap_channel <= 11) { 6330 run_iwpriv(dut, ifname, "prb_rate 5500"); 6331 run_iwpriv(dut, ifname, "set_bcn_rate 5500"); 6332 } 6333 6334 if (dut->ap_oce == VALUE_DISABLED) 6335 run_iwpriv(dut, ifname, "set_bpr_enable 0"); 6336 6337 if (dut->ap_oce == VALUE_DISABLED && dut->ap_channel <= 11) { 6338 run_iwpriv(dut, ifname, "mgmt_rate 1000"); 6339 run_iwpriv(dut, ifname, "set_bcn_rate 1000"); 6340 } 6341 6342 if (dut->ap_bcnint) 6343 run_iwpriv(dut, ifname, "bintval %d", dut->ap_bcnint); 6344 6345 if (dut->ap_filsdscv == VALUE_DISABLED) 6346 run_iwpriv(dut, ifname, "enable_fils 0 0"); 6347 6348 if (dut->ap_filshlp == VALUE_ENABLED) 6349 run_iwpriv(dut, ifname, "oce_hlp 1"); 6350 else if (dut->ap_filshlp == VALUE_DISABLED) 6351 run_iwpriv(dut, ifname, "oce_hlp 0"); 6352 6353 /* When RNR is enabled, also enable apchannelreport, background scan */ 6354 if (dut->ap_rnr == VALUE_ENABLED) { 6355 run_iwpriv(dut, ifname, "rnr 1"); 6356 run_iwpriv(dut, ifname, "rnr_tbtt 1"); 6357 run_iwpriv(dut, ifname, "apchanrpt 1"); 6358 run_iwpriv(dut, basedev, "acs_ctrlflags 0x4"); 6359 run_iwpriv(dut, basedev, "acs_scanintvl 60"); 6360 run_iwpriv(dut, basedev, "acs_bkscanen 1"); 6361 if (dut->ap_is_dual == 1) { 6362 run_iwpriv(dut, ifname_dual, "rnr 1"); 6363 run_iwpriv(dut, ifname_dual, "rnr_tbtt 1"); 6364 run_iwpriv(dut, ifname_dual, "apchanrpt 1"); 6365 run_iwpriv(dut, basedev_radio, "acs_ctrlflags 0x4"); 6366 run_iwpriv(dut, basedev_radio, "acs_scanintvl 60"); 6367 run_iwpriv(dut, basedev_radio, "acs_bkscanen 1"); 6368 } 6369 } 6370 6371 if (dut->ap_blechanutil || dut->ap_ble_admit_cap || dut->ap_blestacnt) { 6372 run_iwpriv(dut, ifname, "qbssload 0"); 6373 snprintf(buf, sizeof(buf), 6374 "wlanconfig %s addie ftype 0 len 7 data 0b05%02x%02x%02x%02x%02x ", 6375 ifname, dut->ap_blestacnt & 0xFF, 6376 dut->ap_blestacnt >> 8, dut->ap_blechanutil, 6377 dut->ap_ble_admit_cap & 0xFF, 6378 dut->ap_ble_admit_cap >> 8); 6379 run_system(dut, buf); 6380 snprintf(buf, sizeof(buf), 6381 "wlanconfig %s addie ftype 2 len 7 data 0b05%02x%02x%02x%02x%02x ", 6382 ifname, dut->ap_blestacnt & 0xFF, 6383 dut->ap_blestacnt >> 8, dut->ap_blechanutil, 6384 dut->ap_ble_admit_cap & 0xFF, 6385 dut->ap_ble_admit_cap >> 8); 6386 run_system(dut, buf); 6387 } 6388 6389 if (dut->ap_esp == VALUE_ENABLED) 6390 run_iwpriv(dut, basedev, "esp_period 5"); 6391 else if (dut->ap_esp == VALUE_DISABLED) 6392 run_iwpriv(dut, basedev, "esp_period 0"); 6393 6394 if (dut->ap_datappdudura) 6395 run_iwpriv(dut, basedev, "esp_ppdu_dur %d", 6396 dut->ap_datappdudura); 6397 6398 if (dut->ap_airtimefract) 6399 run_iwpriv(dut, basedev, "esp_airtime %d", 6400 dut->ap_airtimefract); 6401 6402 if (dut->ap_dhcp_stop) { 6403 snprintf(buf, sizeof(buf), "/etc/init.d/dnsmasq stop"); 6404 run_system(dut, buf); 6405 } 6406 6407 if (dut->ap_bawinsize) 6408 run_iwpriv(dut, basedev, "esp_ba_window %d", dut->ap_bawinsize); 6409 6410 if (dut->program == PROGRAM_DPP) { 6411 if (dut->ap_interface_2g == 1) { 6412 run_iwpriv(dut, ifname, "set_bcn_rate 5500"); 6413 run_iwpriv(dut, ifname, "prb_rate 5500"); 6414 run_iwpriv(dut, ifname, "mgmt_rate 5500"); 6415 } 6416 6417 run_iwpriv(dut, basedev, "set_rxfilter 0xffffffff"); 6418 dut->hostapd_running = 1; 6419 } 6420 6421 if (dut->program == PROGRAM_HE) { 6422 /* disable sending basic triggers */ 6423 run_system_wrapper(dut, 6424 "wifitool %s setUnitTestCmd 0x47 2 42 0", 6425 ifname); 6426 /* disable MU BAR */ 6427 run_system_wrapper(dut, 6428 "wifitool %s setUnitTestCmd 0x47 2 64 1", 6429 ifname); 6430 /* disable PSD Boost */ 6431 run_system_wrapper(dut, 6432 "wifitool %s setUnitTestCmd 0x48 2 142 1", 6433 ifname); 6434 /* Enable mix bw */ 6435 run_system_wrapper(dut, 6436 "wifitool %s setUnitTestCmd 0x47 2 141 1", 6437 ifname); 6438 /* Disable preferred AC */ 6439 run_system_wrapper(dut, 6440 "wifitool %s setUnitTestCmd 0x48 2 186 0", 6441 ifname); 6442 run_iwpriv(dut, basedev, "he_muedca_mode 0"); 6443 run_iwpriv(dut, ifname, "he_ul_ofdma 0"); 6444 run_iwpriv(dut, ifname, "he_dl_ofdma 0"); 6445 if (dut->he_set_sta_1x1 == VALUE_ENABLED) { 6446 /* sets g_force_1x1_peer to 1 */ 6447 run_system_wrapper(dut, 6448 "wifitool %s setUnitTestCmd 0x48 2 118 1", 6449 ifname); 6450 } 6451 if (dut->ap_txBF) { 6452 /* Enable SU_AX sounding */ 6453 run_iwpriv(dut, ifname, "he_sounding_mode 1"); 6454 /* Ignore TBTT for NDP */ 6455 run_system_wrapper(dut, 6456 "wifitool %s setUnitTestCmd 0x48 2 2 1", 6457 ifname); 6458 /* g_cv_query_enable=1, i.e., cv query enable */ 6459 run_system_wrapper(dut, 6460 "wifitool %s setUnitTestCmd 0x47 2 7 1", 6461 ifname); 6462 /* Override TPC calculations and set TxBF flag to True 6463 */ 6464 run_system_wrapper(dut, 6465 "wifitool %s setUnitTestCmd 0x47 2 47 1", 6466 ifname); 6467 } 6468 if (dut->device_type == AP_testbed) { 6469 run_iwpriv(dut, ifname, "tx_stbc 0"); 6470 run_iwpriv(dut, ifname, "he_txmcsmap 0x0"); 6471 run_iwpriv(dut, ifname, "he_rxmcsmap 0x0"); 6472 run_iwpriv(dut, ifname, "he_amsdu_in_ampdu_supp 0"); 6473 run_iwpriv(dut, ifname, "he_bfee_sts_supp 0 0"); 6474 run_iwpriv(dut, ifname, "he_4xltf_800nsgi_rx 0"); 6475 run_iwpriv(dut, ifname, "he_1xltf_800nsgi_rx 0"); 6476 run_iwpriv(dut, ifname, "he_max_nc 0"); 6477 run_iwpriv(dut, ifname, "he_bsr_supp 0"); 6478 run_iwpriv(dut, ifname, "rx_stbc 0"); 6479 if (dut->ap_he_dlofdma == VALUE_DISABLED) 6480 run_iwpriv(dut, ifname, "he_dlofdma 0"); 6481 if (dut->ap_channel <= 11) { 6482 dut->ap_bcc = VALUE_ENABLED; 6483 run_iwpriv(dut, ifname, "vht_11ng 0"); 6484 } 6485 if (!dut->ap_txBF) { 6486 run_iwpriv(dut, ifname, "he_subfer 0"); 6487 run_iwpriv(dut, ifname, "he_subfee 0"); 6488 } 6489 if (!dut->ap_mu_txBF) { 6490 run_iwpriv(dut, ifname, "he_mubfer 0"); 6491 run_iwpriv(dut, ifname, "he_mubfee 0"); 6492 } 6493 if (dut->ap_cipher == AP_WEP || 6494 dut->ap_cipher == AP_TKIP) 6495 run_iwpriv(dut, ifname, "htweptkip 1"); 6496 if (dut->ap_rx_streams || dut->ap_tx_streams) 6497 run_iwpriv(dut, ifname, "nss %d", 6498 dut->ap_rx_streams); 6499 } 6500 } 6501 6502 if (dut->ap_he_ulofdma == VALUE_ENABLED) { 6503 run_iwpriv(dut, ifname, "he_ul_ofdma 1"); 6504 run_iwpriv(dut, ifname, "he_mu_edca 1"); 6505 6506 /* Disable sounding for UL OFDMA */ 6507 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0", 6508 ifname); 6509 6510 if ((dut->ap_rx_streams || dut->ap_tx_streams) && 6511 dut->device_type == AP_testbed) { 6512 unsigned int txchainmask = 0x00; 6513 6514 switch (dut->ap_rx_streams) { 6515 case 1: 6516 txchainmask = 0x01; 6517 break; 6518 case 2: 6519 txchainmask = 0x03; 6520 break; 6521 case 3: 6522 txchainmask = 0x07; 6523 break; 6524 case 4: 6525 txchainmask = 0x0f; 6526 break; 6527 case 5: 6528 txchainmask = 0x1f; 6529 break; 6530 case 6: 6531 txchainmask = 0x3f; 6532 break; 6533 case 7: 6534 txchainmask = 0x7f; 6535 break; 6536 case 8: 6537 txchainmask = 0xff; 6538 break; 6539 } 6540 6541 run_iwpriv(dut, ifname, "he_ul_nss %d", 6542 dut->ap_rx_streams); 6543 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask); 6544 run_iwpriv(dut, basedev, "rxchainmask %d", txchainmask); 6545 } 6546 6547 if (dut->ap_channel == 100 && dut->device_type == AP_testbed) 6548 run_system_wrapper(dut, "iwpriv %s inact 1000", ifname); 6549 6550 if (dut->he_ul_mcs) 6551 run_iwpriv(dut, ifname, "he_ul_mcs %d", dut->he_ul_mcs); 6552 6553 run_iwpriv(dut, ifname, "he_ul_ltf 3"); 6554 run_iwpriv(dut, ifname, "he_ul_shortgi 3"); 6555 run_iwpriv(dut, basedev, "he_ul_trig_int 2"); 6556 6557 /* Disable efficiency check for UL OFDMA. We do not send TBPPDU 6558 * for one user. With this command, we would send UL OFDMA even 6559 * for one user to allow testing to be done without requiring 6560 * more than one station. */ 6561 run_system_wrapper(dut, 6562 "wifitool %s setUnitTestCmd 0x47 2 131 0", 6563 ifname); 6564 /* Set random RU allocation */ 6565 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 9 1", 6566 ifname); 6567 /* To set TBTT PPDU duration (us) */ 6568 run_system_wrapper(dut, 6569 "wifitool %s setUnitTestCmd 0x48 2 63 1908", 6570 ifname); 6571 } 6572 6573 if (dut->ap_he_dlofdma == VALUE_ENABLED) { 6574 run_iwpriv(dut, ifname, "he_dl_ofdma 1", ifname); 6575 6576 /* For fixed MCS */ 6577 novap_reset(dut, ifname, 0); 6578 run_iwpriv(dut, ifname, 6579 "cfg80211tool %s setratemask 3 0x80f80f80 0x0f80f80f 0xf80f80f8"); 6580 } 6581 6582 if (dut->ap_he_ppdu == PPDU_MU && dut->ap_he_dlofdma == VALUE_ENABLED) { 6583 /* Increase the min TX time limit for MU MIMO to disable MU MIMO 6584 * scheduling */ 6585 run_system_wrapper(dut, 6586 "wifitool %s setUnitTestCmd 0x47 2 11 1000000", 6587 ifname); 6588 /* Increase the max TX time limit for DL OFDMA to enable OFDMA 6589 * scheduling */ 6590 run_system_wrapper(dut, 6591 "wifitool %s setUnitTestCmd 0x47 2 17 1000000", 6592 ifname); 6593 /* Disable 'force SU schedule' to enable MU sch */ 6594 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 8 0", 6595 ifname); 6596 /* Enable MU 11ax support in sch algo */ 6597 run_system_wrapper(dut, 6598 "wifitool %s setUnitTestCmd 0x47 2 29 0", 6599 ifname); 6600 /* Enable to sort RU allocation */ 6601 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x4b 2 2 1", 6602 ifname); 6603 } 6604 6605 if (dut->ap_numsounddim) { 6606 unsigned int txchainmask = 0; 6607 6608 switch (dut->ap_numsounddim) { 6609 case 1: 6610 txchainmask = 0x01; 6611 break; 6612 case 2: 6613 txchainmask = 0x03; 6614 break; 6615 case 3: 6616 txchainmask = 0x07; 6617 break; 6618 case 4: 6619 txchainmask = 0x0f; 6620 break; 6621 case 5: 6622 txchainmask = 0x1f; 6623 break; 6624 case 6: 6625 txchainmask = 0x3f; 6626 break; 6627 case 7: 6628 txchainmask = 0x7f; 6629 break; 6630 case 8: 6631 txchainmask = 0xff; 6632 break; 6633 } 6634 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask); 6635 } 6636 6637 if (dut->ap_numsounddim && dut->device_type == AP_testbed) { 6638 /* Sets g_force_1x1_peer to 1 which should be reset to zero 6639 * for non-MU test cases */ 6640 run_system_wrapper(dut, 6641 "wifitool %s setUnitTestCmd 0x48 2 118 1", 6642 ifname); 6643 if (dut->ap_mu_txBF) { 6644 /* Disable DL OFDMA */ 6645 run_system_wrapper(dut, 6646 "wifitool %s setUnitTestCmd 0x47 2 11 0", 6647 ifname); 6648 } 6649 } 6650 6651 if (dut->ap_bcc == VALUE_ENABLED) { 6652 run_iwpriv(dut, ifname, "mode 11AHE20"); 6653 run_iwpriv(dut, ifname, "nss 2"); 6654 run_iwpriv(dut, ifname, "he_txmcsmap 0x0"); 6655 run_iwpriv(dut, ifname, "he_rxmcsmap 0x0"); 6656 } 6657 6658 if (dut->ap_he_frag == VALUE_ENABLED) 6659 run_iwpriv(dut, ifname, "he_frag 1"); 6660 else if (dut->ap_he_frag == VALUE_DISABLED) 6661 run_iwpriv(dut, ifname, "he_frag 0"); 6662 6663 if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) { 6664 if (dut->ap_ba_bufsize == BA_BUFSIZE_64) 6665 run_iwpriv(dut, ifname, "ba_bufsize 0"); 6666 else 6667 run_iwpriv(dut, ifname, "ba_bufsize 1"); 6668 } 6669 6670 if (dut->ap_mu_edca == VALUE_ENABLED) 6671 run_iwpriv(dut, ifname, "he_mu_edca 1"); 6672 6673 if (dut->ap_he_mimo == MIMO_DL) { 6674 mubrp_commands(dut, ifname); 6675 if (dut->device_type != AP_testbed) 6676 run_system_wrapper( 6677 dut, "wifitool %s setUnitTestCmd 0x48 2 100 2", 6678 ifname); 6679 } 6680 6681 if (dut->ap_he_mimo == MIMO_UL) 6682 run_iwpriv(dut, ifname, "he_mubfee 1"); 6683 6684 if (dut->ap_he_rtsthrshld == VALUE_ENABLED) 6685 run_iwpriv(dut, ifname, "he_rtsthrshld 512"); 6686 else if (dut->ap_he_rtsthrshld == VALUE_DISABLED) 6687 run_iwpriv(dut, ifname, "he_rtsthrshld 1024"); 6688 6689 if (dut->ap_mbssid == VALUE_ENABLED && 6690 (dut->ap_rx_streams || dut->ap_tx_streams) && 6691 dut->device_type == AP_testbed) { 6692 const char *ifname_1; 6693 6694 ifname_1= dut->ap_channel >= 36 ? "ath01" : "ath11"; 6695 6696 /* NSS is not set in Secondary VAP for MBSSID case, 6697 * hence it is explicitly set here. For primary VAP 6698 * NSS is set during AP configuration */ 6699 run_iwpriv(dut, ifname_1, "nss %d", dut->ap_rx_streams); 6700 } 6701 6702 if (dut->ap_twtresp == VALUE_ENABLED) 6703 run_iwpriv(dut, ifname, "twt_responder 1"); 6704 else if (dut->ap_twtresp == VALUE_DISABLED) 6705 run_iwpriv(dut, ifname, "twt_responder 0"); 6706 6707 if (dut->program == PROGRAM_HE && dut->ap_fixed_rate) { 6708 int nss = 0, mcs = 0; 6709 uint16_t mcsnssmap = 0; 6710 6711 /* MCS 7 is used - set only nss and he_mcs. 6712 * Do not set mcsnssmap unless MCS is 9 or 11. */ 6713 if (dut->ap_mcs >= 9) { 6714 if (dut->ap_mcs == 9) { 6715 if (dut->ap_tx_streams == 1) { 6716 nss = 1; 6717 mcs = dut->ap_mcs; 6718 } else if (dut->ap_tx_streams == 2) { 6719 nss = 2; 6720 mcs = dut->ap_mcs; 6721 } 6722 } else if (dut->ap_mcs == 11) { 6723 if (dut->ap_tx_streams == 1) { 6724 nss = 1; 6725 mcs = dut->ap_mcs; 6726 } else if (dut->ap_tx_streams == 2) { 6727 nss = 2; 6728 mcs = dut->ap_mcs; 6729 } 6730 } 6731 6732 get_he_mcs_nssmap((uint8_t *) &mcsnssmap, nss, mcs); 6733 he_mcsnssmap = (mcsnssmap << 16) | mcsnssmap; 6734 } 6735 6736 run_iwpriv(dut, ifname, "nss %d", dut->ap_tx_streams); 6737 run_iwpriv(dut, ifname, "he_mcs %d", dut->ap_mcs); 6738 } 6739 6740 if (he_mcsnssmap) { 6741 run_iwpriv(dut, ifname, "he_rxmcsmap %lu", he_mcsnssmap); 6742 run_iwpriv(dut, ifname, "he_txmcsmap %lu", he_mcsnssmap); 6743 } 6744 6745 if (dut->he_sounding == VALUE_ENABLED) 6746 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 0", 6747 ifname); 6748 6749 if (dut->he_mmss) 6750 run_iwpriv(dut, ifname, "ampduden_ovrd %d", dut->he_mmss); 6751 6752 if (dut->he_srctrl_allow == 0) { 6753 /* This is a special testbed AP case to enable SR for protocol 6754 * testing when SRCtrl_SRValue15Allowed is specified. 6755 */ 6756 run_iwpriv(dut, ifname, "he_sr_enable 1"); 6757 } 6758 } 6759 6760 6761 static int cmd_ath_ap_config_commit(struct sigma_dut *dut, 6762 struct sigma_conn *conn, 6763 struct sigma_cmd *cmd) 6764 { 6765 /* const char *name = get_param(cmd, "NAME"); */ 6766 char buf[100]; 6767 struct stat s; 6768 const char *ifname = dut->ap_is_dual ? "ath1" : "ath0"; 6769 int res; 6770 6771 if (stat("/proc/athversion", &s) == 0) { 6772 sigma_dut_print(dut, DUT_MSG_INFO, "Run apdown"); 6773 run_system(dut, "apdown"); 6774 } 6775 6776 cmd_ath_ap_radio_config(dut); 6777 6778 snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID=%s'", dut->ap_ssid); 6779 run_system(dut, buf); 6780 6781 switch (dut->ap_key_mgmt) { 6782 case AP_OPEN: 6783 if (dut->ap_cipher == AP_WEP) { 6784 run_system(dut, "cfg -a AP_SECMODE=WEP"); 6785 run_system(dut, "cfg -a AP_SECFILE=NONE"); 6786 /* shared auth mode not supported */ 6787 run_system(dut, "cfg -a AP_WEP_MODE_0=1"); 6788 run_system(dut, "cfg -a AP_WEP_MODE_1=1"); 6789 snprintf(buf, sizeof(buf), 6790 "cfg -a WEP_RADIO_NUM0_KEY_1=%s", 6791 dut->ap_wepkey); 6792 run_system(dut, buf); 6793 snprintf(buf, sizeof(buf), 6794 "cfg -a WEP_RADIO_NUM1_KEY_1=%s", 6795 dut->ap_wepkey); 6796 run_system(dut, buf); 6797 } else { 6798 run_system(dut, "cfg -a AP_SECMODE=None"); 6799 } 6800 break; 6801 case AP_WPA2_PSK: 6802 case AP_WPA2_PSK_MIXED: 6803 case AP_WPA_PSK: 6804 case AP_WPA2_SAE: 6805 case AP_WPA2_PSK_SAE: 6806 if (dut->ap_key_mgmt == AP_WPA2_PSK || 6807 dut->ap_key_mgmt == AP_WPA2_SAE || 6808 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 6809 run_system(dut, "cfg -a AP_WPA=2"); 6810 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 6811 run_system(dut, "cfg -a AP_WPA=3"); 6812 else 6813 run_system(dut, "cfg -a AP_WPA=1"); 6814 /* TODO: SAE configuration */ 6815 run_system(dut, "cfg -a AP_SECMODE=WPA"); 6816 run_system(dut, "cfg -a AP_SECFILE=PSK"); 6817 res = snprintf(buf, sizeof(buf), "cfg -a 'PSK_KEY=%s'", 6818 dut->ap_passphrase); 6819 if (res < 0 || res >= sizeof(buf)) 6820 return ERROR_SEND_STATUS; 6821 run_system(dut, buf); 6822 if (dut->ap_cipher == AP_CCMP_TKIP) 6823 run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\""); 6824 else if (dut->ap_cipher == AP_TKIP) 6825 run_system(dut, "cfg -a AP_CYPHER=TKIP"); 6826 else 6827 run_system(dut, "cfg -a AP_CYPHER=CCMP"); 6828 break; 6829 case AP_WPA2_EAP: 6830 case AP_WPA2_EAP_MIXED: 6831 case AP_WPA_EAP: 6832 if (dut->ap_key_mgmt == AP_WPA2_EAP) 6833 run_system(dut, "cfg -a AP_WPA=2"); 6834 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) 6835 run_system(dut, "cfg -a AP_WPA=3"); 6836 else 6837 run_system(dut, "cfg -a AP_WPA=1"); 6838 run_system(dut, "cfg -a AP_SECMODE=WPA"); 6839 run_system(dut, "cfg -a AP_SECFILE=EAP"); 6840 if (dut->ap_cipher == AP_CCMP_TKIP) 6841 run_system(dut, "cfg -a AP_CYPHER=\"CCMP TKIP\""); 6842 else if (dut->ap_cipher == AP_TKIP) 6843 run_system(dut, "cfg -a AP_CYPHER=TKIP"); 6844 else 6845 run_system(dut, "cfg -a AP_CYPHER=CCMP"); 6846 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER=%s", 6847 dut->ap_radius_ipaddr); 6848 run_system(dut, buf); 6849 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT=%d", 6850 dut->ap_radius_port); 6851 run_system(dut, buf); 6852 res = snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SECRET=%s", 6853 dut->ap_radius_password); 6854 if (res < 0 || res >= sizeof(buf)) 6855 return ERROR_SEND_STATUS; 6856 run_system(dut, buf); 6857 break; 6858 case AP_WPA2_EAP_OSEN: 6859 /* TODO */ 6860 sigma_dut_print(dut, DUT_MSG_ERROR, "EAP+OSEN not supported"); 6861 break; 6862 case AP_SUITEB: 6863 /* TODO */ 6864 sigma_dut_print(dut, DUT_MSG_ERROR, "SuiteB not supported"); 6865 break; 6866 case AP_WPA2_OWE: 6867 /* TODO */ 6868 sigma_dut_print(dut, DUT_MSG_ERROR, "OWE not supported"); 6869 break; 6870 case AP_WPA2_FT_EAP: 6871 case AP_WPA2_FT_PSK: 6872 case AP_WPA2_EAP_SHA256: 6873 case AP_WPA2_PSK_SHA256: 6874 case AP_WPA2_ENT_FT_EAP: 6875 case AP_OSEN: 6876 /* TODO */ 6877 send_resp(dut, conn, SIGMA_ERROR, 6878 "errorCode,Unsupported KeyMgnt value"); 6879 return 0; 6880 } 6881 6882 if (dut->ap_is_dual) { 6883 /* ath1 settings in case of dual */ 6884 snprintf(buf, sizeof(buf), "cfg -a 'AP_SSID_2=%s'", 6885 dut->ap_ssid); 6886 run_system(dut, buf); 6887 6888 switch (dut->ap_key_mgmt) { 6889 case AP_OPEN: 6890 if (dut->ap_cipher == AP_WEP) { 6891 run_system(dut, "cfg -a AP_SECMODE_2=WEP"); 6892 run_system(dut, "cfg -a AP_SECFILE_2=NONE"); 6893 /* shared auth mode not supported */ 6894 run_system(dut, "cfg -a AP_WEP_MODE_0=1"); 6895 run_system(dut, "cfg -a AP_WEP_MODE_1=1"); 6896 snprintf(buf, sizeof(buf), 6897 "cfg -a WEP_RADIO_NUM0_KEY_1=%s", 6898 dut->ap_wepkey); 6899 run_system(dut, buf); 6900 snprintf(buf, sizeof(buf), 6901 "cfg -a WEP_RADIO_NUM1_KEY_1=%s", 6902 dut->ap_wepkey); 6903 run_system(dut, buf); 6904 } else { 6905 run_system(dut, "cfg -a AP_SECMODE_2=None"); 6906 } 6907 break; 6908 case AP_WPA2_PSK: 6909 case AP_WPA2_PSK_MIXED: 6910 case AP_WPA_PSK: 6911 case AP_WPA2_SAE: 6912 case AP_WPA2_PSK_SAE: 6913 if (dut->ap_key_mgmt == AP_WPA2_PSK || 6914 dut->ap_key_mgmt == AP_WPA2_SAE || 6915 dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 6916 run_system(dut, "cfg -a AP_WPA_2=2"); 6917 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 6918 run_system(dut, "cfg -a AP_WPA_2=3"); 6919 else 6920 run_system(dut, "cfg -a AP_WPA_2=1"); 6921 // run_system(dut, "cfg -a AP_WPA_2=2"); 6922 /* TODO: SAE configuration */ 6923 run_system(dut, "cfg -a AP_SECMODE_2=WPA"); 6924 run_system(dut, "cfg -a AP_SECFILE_2=PSK"); 6925 res = snprintf(buf, sizeof(buf), 6926 "cfg -a 'PSK_KEY_2=%s'", 6927 dut->ap_passphrase); 6928 if (res < 0 || res >= sizeof(buf)) 6929 return ERROR_SEND_STATUS; 6930 run_system(dut, buf); 6931 if (dut->ap_cipher == AP_CCMP_TKIP) 6932 run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\""); 6933 else if (dut->ap_cipher == AP_TKIP) 6934 run_system(dut, "cfg -a AP_CYPHER_2=TKIP"); 6935 else 6936 run_system(dut, "cfg -a AP_CYPHER_2=CCMP"); 6937 break; 6938 case AP_WPA2_EAP: 6939 case AP_WPA2_EAP_MIXED: 6940 case AP_WPA_EAP: 6941 if (dut->ap_key_mgmt == AP_WPA2_EAP) 6942 run_system(dut, "cfg -a AP_WPA_2=2"); 6943 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) 6944 run_system(dut, "cfg -a AP_WPA_2=3"); 6945 else 6946 run_system(dut, "cfg -a AP_WPA_2=1"); 6947 run_system(dut, "cfg -a AP_SECMODE_2=WPA"); 6948 run_system(dut, "cfg -a AP_SECFILE_2=EAP"); 6949 if (dut->ap_cipher == AP_CCMP_TKIP) 6950 run_system(dut, "cfg -a AP_CYPHER_2=\"CCMP TKIP\""); 6951 else if (dut->ap_cipher == AP_TKIP) 6952 run_system(dut, "cfg -a AP_CYPHER_2=TKIP"); 6953 else 6954 run_system(dut, "cfg -a AP_CYPHER_2=CCMP"); 6955 6956 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_SERVER_2=%s", 6957 dut->ap_radius_ipaddr); 6958 run_system(dut, buf); 6959 snprintf(buf, sizeof(buf), "cfg -a AP_AUTH_PORT_2=%d", 6960 dut->ap_radius_port); 6961 run_system(dut, buf); 6962 res = snprintf(buf, sizeof(buf), 6963 "cfg -a AP_AUTH_SECRET_2=%s", 6964 dut->ap_radius_password); 6965 if (res < 0 || res >= sizeof(buf)) 6966 return ERROR_SEND_STATUS; 6967 run_system(dut, buf); 6968 break; 6969 case AP_WPA2_EAP_OSEN: 6970 /* TODO */ 6971 sigma_dut_print(dut, DUT_MSG_ERROR, 6972 "EAP+OSEN not supported"); 6973 break; 6974 case AP_SUITEB: 6975 /* TODO */ 6976 sigma_dut_print(dut, DUT_MSG_ERROR, 6977 "SuiteB not supported"); 6978 break; 6979 case AP_WPA2_OWE: 6980 /* TODO */ 6981 sigma_dut_print(dut, DUT_MSG_ERROR, 6982 "OWE not supported"); 6983 break; 6984 case AP_WPA2_FT_EAP: 6985 case AP_WPA2_FT_PSK: 6986 case AP_WPA2_EAP_SHA256: 6987 case AP_WPA2_PSK_SHA256: 6988 case AP_WPA2_ENT_FT_EAP: 6989 case AP_OSEN: 6990 /* TODO */ 6991 send_resp(dut, conn, SIGMA_ERROR, 6992 "errorCode,Unsupported KeyMgnt value"); 6993 return 0; 6994 } 6995 6996 /* wifi0 settings in case of dual */ 6997 run_system(dut, "cfg -a AP_RADIO_ID=0"); 6998 run_system(dut, "cfg -a AP_PRIMARY_CH=6"); 6999 run_system(dut, "cfg -a AP_STARTMODE=dual"); 7000 run_system(dut, "cfg -a AP_CHMODE=11NGHT40PLUS"); 7001 run_system(dut, "cfg -a TX_CHAINMASK=7"); 7002 run_system(dut, "cfg -a RX_CHAINMASK=7"); 7003 } 7004 7005 switch (dut->ap_pmf) { 7006 case AP_PMF_DISABLED: 7007 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=0"); 7008 run_system(dut, buf); 7009 break; 7010 case AP_PMF_OPTIONAL: 7011 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=1"); 7012 run_system(dut, buf); 7013 break; 7014 case AP_PMF_REQUIRED: 7015 snprintf(buf, sizeof(buf), "cfg -a AP_PMF=2"); 7016 run_system(dut, buf); 7017 break; 7018 } 7019 if (dut->ap_add_sha256) { 7020 snprintf(buf, sizeof(buf), "cfg -a AP_WPA_SHA256=1"); 7021 run_system(dut, buf); 7022 } else { 7023 snprintf(buf, sizeof(buf), "cfg -r AP_WPA_SHA256"); 7024 run_system(dut, buf); 7025 } 7026 7027 if (dut->ap_hs2) 7028 run_system(dut, "cfg -a AP_HOTSPOT=1"); 7029 else 7030 run_system(dut, "cfg -r AP_HOTSPOT"); 7031 7032 if (dut->ap_interworking) { 7033 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_ANT=%d", 7034 dut->ap_access_net_type); 7035 run_system(dut, buf); 7036 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_INTERNET=%d", 7037 dut->ap_internet); 7038 run_system(dut, buf); 7039 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUEGROUP=%d", 7040 dut->ap_venue_group); 7041 run_system(dut, buf); 7042 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_VENUETYPE=%d", 7043 dut->ap_venue_type); 7044 run_system(dut, buf); 7045 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=%s", 7046 dut->ap_hessid); 7047 run_system(dut, buf); 7048 7049 if (dut->ap_roaming_cons[0]) { 7050 char *second, *rc; 7051 rc = strdup(dut->ap_roaming_cons); 7052 if (rc == NULL) 7053 return 0; 7054 7055 second = strchr(rc, ';'); 7056 if (second) 7057 *second++ = '\0'; 7058 7059 snprintf(buf, sizeof(buf), 7060 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=%s", rc); 7061 run_system(dut, buf); 7062 7063 if (second) { 7064 snprintf(buf, sizeof(buf), 7065 "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2" 7066 "=%s", second); 7067 run_system(dut, buf); 7068 } 7069 free(rc); 7070 } else { 7071 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM"); 7072 run_system(dut, 7073 "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2"); 7074 } 7075 } else { 7076 run_system(dut, "cfg -r AP_HOTSPOT_ANT"); 7077 run_system(dut, "cfg -r AP_HOTSPOT_INTERNET"); 7078 run_system(dut, "cfg -r AP_HOTSPOT_VENUEGROUP"); 7079 run_system(dut, "cfg -r AP_HOTSPOT_VENUETYPE"); 7080 run_system(dut, "cfg -r AP_HOTSPOT_HESSID"); 7081 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM"); 7082 run_system(dut, "cfg -r AP_HOTSPOT_ROAMINGCONSORTIUM2"); 7083 } 7084 7085 if (dut->ap_proxy_arp) 7086 run_system(dut, "cfg -a IEEE80211V_PROXYARP=1"); 7087 else 7088 run_system(dut, "cfg -a IEEE80211V_PROXYARP=0"); 7089 if (dut->ap_dgaf_disable) 7090 run_system(dut, "cfg -a AP_HOTSPOT_DISABLE_DGAF=1"); 7091 else 7092 run_system(dut, "cfg -r AP_HOTSPOT_DISABLE_DGAF"); 7093 7094 if (strlen(dut->ap_tag_ssid[0])) { 7095 snprintf(buf, sizeof(buf), 7096 "cfg -a AP_SSID_2=%s", dut->ap_tag_ssid[0]); 7097 run_system(dut, buf); 7098 7099 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) { 7100 run_system(dut, "cfg -a AP_SECMODE_2=WPA"); 7101 run_system(dut, "cfg -a AP_SECFILE_2=OSEN"); 7102 7103 res = snprintf(buf, sizeof(buf), 7104 "cfg -a AP_AUTH_SERVER_2=%s", 7105 dut->ap2_radius_ipaddr); 7106 if (res < 0 || res >= sizeof(buf)) 7107 return ERROR_SEND_STATUS; 7108 run_system(dut, buf); 7109 7110 res = snprintf(buf, sizeof(buf), 7111 "cfg -a AP_AUTH_PORT_2=%d", 7112 dut->ap2_radius_port); 7113 if (res < 0 || res >= sizeof(buf)) 7114 return ERROR_SEND_STATUS; 7115 run_system(dut, buf); 7116 7117 res = snprintf(buf, sizeof(buf), 7118 "cfg -a AP_AUTH_SECRET_2=%s", 7119 dut->ap2_radius_password); 7120 if (res < 0 || res >= sizeof(buf)) 7121 return ERROR_SEND_STATUS; 7122 run_system(dut, buf); 7123 } else { 7124 run_system(dut, "cfg -a AP_SECMODE_2=None"); 7125 run_system(dut, "cfg -r AP_AUTH_SERVER_2"); 7126 run_system(dut, "cfg -r AP_AUTH_PORT_2"); 7127 run_system(dut, "cfg -r AP_AUTH_SECRET_2"); 7128 } 7129 7130 run_system(dut, "cfg -a AP_STARTMODE=multi"); 7131 } 7132 7133 run_system(dut, "cfg -c"); 7134 7135 sigma_dut_print(dut, DUT_MSG_INFO, "Starting AP"); 7136 if (system("apup") != 0) { 7137 /* to be debugged why apup returns error 7138 send_resp(dut, conn, SIGMA_ERROR, 7139 "errorCode,apup failed"); 7140 return 0; 7141 */ 7142 } 7143 sigma_dut_print(dut, DUT_MSG_INFO, "AP started"); 7144 7145 if (dut->ap_key_mgmt != AP_OPEN) { 7146 int res; 7147 /* allow some time for hostapd to start before returning 7148 * success */ 7149 usleep(500000); 7150 if (run_hostapd_cli(dut, "ping") != 0) { 7151 send_resp(dut, conn, SIGMA_ERROR, 7152 "errorCode,Failed to talk to hostapd"); 7153 return 0; 7154 } 7155 7156 if (dut->ap_hs2 && !dut->ap_anqpserver) { 7157 /* the cfg app doesn't like ";" in the variables */ 7158 res = ath_ap_append_hostapd_conf(dut); 7159 if (res < 0) 7160 return res; 7161 7162 /* wait for hostapd to be ready */ 7163 usleep(500000); 7164 if (run_hostapd_cli(dut, "ping") != 0) { 7165 send_resp(dut, conn, SIGMA_ERROR, 7166 "errorCode,Failed to talk to " 7167 "hostapd"); 7168 return 0; 7169 } 7170 } 7171 } 7172 7173 ath_ap_set_params(dut); 7174 7175 if (dut->ap_anqpserver) 7176 return cmd_ath_ap_anqpserver_start(dut); 7177 7178 if (dut->ap2_proxy_arp) 7179 run_iwpriv(dut, ifname, "proxy_arp 1"); 7180 7181 if (dut->ap_allow_vht_wep || dut->ap_allow_vht_tkip) 7182 run_iwpriv(dut, ifname, "htweptkip 1"); 7183 7184 return 1; 7185 } 7186 7187 7188 static int set_ebtables_proxy_arp(struct sigma_dut *dut, const char *chain, 7189 const char *ifname) 7190 { 7191 char buf[200]; 7192 7193 if (!chain || !ifname) 7194 return -2; 7195 7196 snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain); 7197 if (system(buf) != 0) { 7198 sigma_dut_print(dut, DUT_MSG_ERROR, 7199 "Failed to set ebtables rules, RULE-1, %s", 7200 chain); 7201 return -2; 7202 } 7203 7204 snprintf(buf, sizeof(buf), 7205 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP", 7206 chain, ifname); 7207 if (system(buf) != 0) { 7208 sigma_dut_print(dut, DUT_MSG_ERROR, 7209 "Failed to set ebtables rules, RULE-2, %s", 7210 chain); 7211 return -2; 7212 } 7213 7214 snprintf(buf, sizeof(buf), 7215 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-solicitation -o %s -j DROP", 7216 chain, ifname); 7217 if (system(buf) != 0) { 7218 sigma_dut_print(dut, DUT_MSG_ERROR, 7219 "Failed to set ebtables rules, RULE-3, %s", 7220 chain); 7221 return -2; 7222 } 7223 7224 snprintf(buf, sizeof(buf), 7225 "ebtables -A %s -d Multicast -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type neighbor-advertisement -o %s -j DROP", 7226 chain, ifname); 7227 if (system(buf) != 0) { 7228 sigma_dut_print(dut, DUT_MSG_ERROR, 7229 "Failed to set ebtables rules, RULE-4, %s", 7230 chain); 7231 return -2; 7232 } 7233 7234 return 0; 7235 } 7236 7237 7238 static int set_ebtables_disable_dgaf(struct sigma_dut *dut, 7239 const char *chain, 7240 const char *ifname) 7241 { 7242 char buf[200]; 7243 7244 if (!chain || !ifname) 7245 return -2; 7246 7247 snprintf(buf, sizeof(buf), "ebtables -P %s ACCEPT", chain); 7248 if (system(buf) != 0) { 7249 sigma_dut_print(dut, DUT_MSG_ERROR, 7250 "Failed to set ebtables rules, RULE-5, %s", 7251 chain); 7252 return -2; 7253 } 7254 7255 snprintf(buf, sizeof(buf), 7256 "ebtables -A %s -p ARP -d Broadcast -o %s -j DROP", 7257 chain, ifname); 7258 if (system(buf) != 0) { 7259 sigma_dut_print(dut, DUT_MSG_ERROR, 7260 "Failed to set ebtables rules, RULE-6, %s", 7261 chain); 7262 return -2; 7263 } 7264 7265 snprintf(buf, sizeof(buf), 7266 "ebtables -A %s -p IPv4 -d Multicast -o %s -j DROP", 7267 chain, ifname); 7268 if (system(buf) != 0) { 7269 sigma_dut_print(dut, DUT_MSG_ERROR, 7270 "Failed to set ebtables rules, RULE-7, %s", 7271 chain); 7272 return -2; 7273 } 7274 7275 snprintf(buf, sizeof(buf), 7276 "ebtables -A %s -p IPv6 -d Multicast -o %s -j DROP", 7277 chain, ifname); 7278 if (system(buf) != 0) { 7279 sigma_dut_print(dut, DUT_MSG_ERROR, 7280 "Failed to set ebtables rules, RULE-8, %s", 7281 chain); 7282 return -2; 7283 } 7284 7285 return 0; 7286 } 7287 7288 7289 static void set_ebtables_forward_drop(struct sigma_dut *dut, 7290 const char *ifname, const char *ifname2) 7291 { 7292 char buf[128]; 7293 7294 snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP", 7295 ifname, ifname2); 7296 if (system(buf) != 0) 7297 sigma_dut_print(dut, DUT_MSG_ERROR, 7298 "Failed to set ebtables rule"); 7299 7300 snprintf(buf, sizeof(buf), "ebtables -A FORWARD -i %s -o %s -j DROP", 7301 ifname2, ifname); 7302 if (system(buf) != 0) 7303 sigma_dut_print(dut, DUT_MSG_ERROR, 7304 "Failed to set ebtables rule"); 7305 } 7306 7307 7308 static int check_channel(int channel) 7309 { 7310 int channel_list[] = { 36, 40, 44, 48, 52, 60, 64, 100, 104, 108, 112, 7311 116, 120, 124, 128, 132, 140, 144, 149, 153, 157, 7312 161, 165 }; 7313 int num_chan = sizeof(channel_list) / sizeof(int); 7314 int i; 7315 7316 for (i = 0; i < num_chan; i++) { 7317 if (channel == channel_list[i]) 7318 return i; 7319 } 7320 7321 return -1; 7322 } 7323 7324 7325 static int get_oper_centr_freq_seq_idx(int chwidth, int channel) 7326 { 7327 int ch_base; 7328 int period; 7329 7330 if (check_channel(channel) < 0) 7331 return -1; 7332 7333 if (channel >= 36 && channel <= 64) 7334 ch_base = 36; 7335 else if (channel >= 100 && channel <= 144) 7336 ch_base = 100; 7337 else 7338 ch_base = 149; 7339 7340 period = channel % ch_base * 5 / chwidth; 7341 return ch_base + period * chwidth / 5 + (chwidth - 20) / 10; 7342 } 7343 7344 7345 static int is_ht40plus_chan(int chan) 7346 { 7347 return chan == 36 || chan == 44 || chan == 52 || chan == 60 || 7348 chan == 100 || chan == 108 || chan == 116 || chan == 124 || 7349 chan == 132 || chan == 149 || chan == 157; 7350 } 7351 7352 7353 static int is_ht40minus_chan(int chan) 7354 { 7355 return chan == 40 || chan == 48 || chan == 56 || chan == 64 || 7356 chan == 104 || chan == 112 || chan == 120 || chan == 128 || 7357 chan == 136 || chan == 144 || chan == 153 || chan == 161; 7358 } 7359 7360 7361 static int get_5g_channel_freq(int chan) 7362 { 7363 return 5000 + chan * 5; 7364 } 7365 7366 7367 static const char * hostapd_cipher_name(enum ap_cipher cipher) 7368 { 7369 switch (cipher) { 7370 case AP_CCMP: 7371 return "CCMP"; 7372 case AP_TKIP: 7373 return "TKIP"; 7374 case AP_CCMP_TKIP: 7375 return "CCMP TKIP"; 7376 case AP_GCMP_256: 7377 return "GCMP-256"; 7378 case AP_GCMP_128: 7379 return "GCMP"; 7380 case AP_CCMP_256: 7381 return "CCMP-256"; 7382 case AP_CCMP_128_GCMP_256: 7383 return "CCMP GCMP-256"; 7384 default: 7385 return "UNKNOWN"; 7386 } 7387 } 7388 7389 7390 static const char * 7391 hostapd_group_mgmt_cipher_name(enum ap_group_mgmt_cipher cipher) 7392 { 7393 switch (cipher) { 7394 case AP_BIP_GMAC_256: 7395 return "BIP-GMAC-256"; 7396 case AP_BIP_CMAC_256: 7397 return "BIP-CMAC-256"; 7398 case AP_BIP_GMAC_128: 7399 return "BIP-GMAC-128"; 7400 case AP_BIP_CMAC_128: 7401 return "AES-128-CMAC"; 7402 default: 7403 return "UNKNOWN"; 7404 } 7405 } 7406 7407 7408 static int ap_set_60g_ese(struct sigma_dut *dut, int count, 7409 struct sigma_ese_alloc *allocs) 7410 { 7411 switch (get_driver_type(dut)) { 7412 #ifdef __linux__ 7413 case DRIVER_WIL6210: 7414 return wil6210_set_ese(dut, count, allocs); 7415 #endif /* __linux__ */ 7416 default: 7417 sigma_dut_print(dut, DUT_MSG_ERROR, 7418 "Unsupported ap_set_60g_ese with the current driver"); 7419 return -1; 7420 } 7421 } 7422 7423 7424 static int ap_set_force_mcs(struct sigma_dut *dut, int force, int mcs) 7425 { 7426 switch (get_driver_type(dut)) { 7427 #ifdef __linux__ 7428 case DRIVER_WIL6210: 7429 return wil6210_set_force_mcs(dut, force, mcs); 7430 #endif /* __linux__ */ 7431 default: 7432 sigma_dut_print(dut, DUT_MSG_ERROR, 7433 "Unsupported ap_set_force_mcs with the current driver"); 7434 return -1; 7435 } 7436 } 7437 7438 7439 enum sigma_cmd_result cmd_ap_config_commit(struct sigma_dut *dut, 7440 struct sigma_conn *conn, 7441 struct sigma_cmd *cmd) 7442 { 7443 /* const char *name = get_param(cmd, "NAME"); */ 7444 FILE *f; 7445 const char *ifname; 7446 char buf[500]; 7447 char path[100]; 7448 char ap_conf_path[100]; 7449 enum driver_type drv; 7450 const char *key_mgmt; 7451 #ifdef ANDROID 7452 struct group *gr; 7453 #endif /* ANDROID */ 7454 7455 drv = get_driver_type(dut); 7456 7457 if (dut->mode == SIGMA_MODE_STATION) { 7458 stop_sta_mode(dut); 7459 sleep(1); 7460 } 7461 7462 if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) { 7463 snprintf(buf, sizeof(buf), "ifconfig %s down", 7464 dut->sniffer_ifname); 7465 if (system(buf) != 0) { 7466 sigma_dut_print(dut, DUT_MSG_INFO, 7467 "Failed to run '%s'", buf); 7468 } 7469 snprintf(buf, sizeof(buf), "iw dev %s set type station", 7470 dut->sniffer_ifname); 7471 if (system(buf) != 0) { 7472 sigma_dut_print(dut, DUT_MSG_INFO, 7473 "Failed to run '%s'", buf); 7474 } 7475 } 7476 7477 dut->mode = SIGMA_MODE_AP; 7478 7479 if (drv == DRIVER_ATHEROS) 7480 return cmd_ath_ap_config_commit(dut, conn, cmd); 7481 if (drv == DRIVER_WCN) 7482 return cmd_wcn_ap_config_commit(dut, conn, cmd); 7483 if (drv == DRIVER_OPENWRT) 7484 return cmd_owrt_ap_config_commit(dut, conn, cmd); 7485 7486 concat_sigma_tmpdir(dut, "/sigma_dut-ap.conf", ap_conf_path, 7487 sizeof(ap_conf_path)); 7488 f = fopen(ap_conf_path, "w"); 7489 if (f == NULL) { 7490 sigma_dut_print(dut, DUT_MSG_ERROR, 7491 "%s: Failed to open sigma_dut-ap.conf", 7492 __func__); 7493 return -2; 7494 } 7495 7496 ifname = get_hostapd_ifname(dut); 7497 7498 switch (dut->ap_mode) { 7499 case AP_11g: 7500 case AP_11b: 7501 case AP_11ng: 7502 fprintf(f, "hw_mode=g\n"); 7503 break; 7504 case AP_11a: 7505 case AP_11na: 7506 case AP_11ac: 7507 fprintf(f, "hw_mode=a\n"); 7508 break; 7509 case AP_11ad: 7510 fprintf(f, "hw_mode=ad\n"); 7511 break; 7512 case AP_11ax: 7513 if (dut->use_5g) 7514 fprintf(f, "hw_mode=a\n"); 7515 else 7516 fprintf(f, "hw_mode=g\n"); 7517 break; 7518 default: 7519 fclose(f); 7520 return -1; 7521 } 7522 7523 if (drv == DRIVER_MAC80211 || drv == DRIVER_LINUX_WCN) 7524 fprintf(f, "driver=nl80211\n"); 7525 7526 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO || 7527 drv == DRIVER_LINUX_WCN) && 7528 (dut->ap_mode == AP_11ng || dut->ap_mode == AP_11na || 7529 (dut->ap_mode == AP_11ax && !dut->use_5g))) { 7530 int ht40plus = 0, ht40minus = 0, tx_stbc = 0; 7531 7532 fprintf(f, "ieee80211n=1\n"); 7533 if (dut->ap_mode == AP_11ax) 7534 fprintf(f, "ieee80211ax=1\n"); 7535 if (dut->ap_mode == AP_11ng && 7536 (dut->ap_chwidth == AP_40 || 7537 (dut->ap_chwidth == AP_AUTO && 7538 dut->default_11ng_ap_chwidth == AP_40))) { 7539 if (dut->ap_channel >= 1 && dut->ap_channel <= 7) 7540 ht40plus = 1; 7541 else if (dut->ap_channel >= 8 && dut->ap_channel <= 11) 7542 ht40minus = 1; 7543 fprintf(f, "obss_interval=300\n"); 7544 } 7545 7546 /* configure ht_capab based on channel width */ 7547 if (dut->ap_mode == AP_11na && 7548 (dut->ap_chwidth == AP_40 || 7549 (dut->ap_chwidth == AP_AUTO && 7550 dut->default_11na_ap_chwidth == AP_40))) { 7551 if (is_ht40plus_chan(dut->ap_channel)) 7552 ht40plus = 1; 7553 else if (is_ht40minus_chan(dut->ap_channel)) 7554 ht40minus = 1; 7555 } 7556 7557 if (dut->ap_tx_stbc) 7558 tx_stbc = 1; 7559 7560 /* Overwrite the ht_capab with offset value if configured */ 7561 if (dut->ap_chwidth == AP_40 && 7562 dut->ap_chwidth_offset == SEC_CH_40ABOVE) { 7563 ht40plus = 1; 7564 ht40minus = 0; 7565 } else if (dut->ap_chwidth == AP_40 && 7566 dut->ap_chwidth_offset == SEC_CH_40BELOW) { 7567 ht40minus = 1; 7568 ht40plus = 0; 7569 } 7570 7571 fprintf(f, "ht_capab=%s%s%s\n", 7572 ht40plus ? "[HT40+]" : "", 7573 ht40minus ? "[HT40-]" : "", 7574 tx_stbc ? "[TX-STBC]" : ""); 7575 } 7576 7577 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO || 7578 drv == DRIVER_LINUX_WCN) && 7579 (dut->ap_mode == AP_11ac || 7580 (dut->ap_mode == AP_11ax && dut->use_5g))) { 7581 int ht40plus = 0, ht40minus = 0; 7582 7583 fprintf(f, "ieee80211ac=1\n" 7584 "ieee80211n=1\n"); 7585 if (dut->ap_mode == AP_11ax) 7586 fprintf(f, "ieee80211ax=1\n"); 7587 7588 /* configure ht_capab based on channel width */ 7589 if (dut->ap_chwidth != AP_20) { 7590 if (is_ht40plus_chan(dut->ap_channel)) 7591 ht40plus = 1; 7592 else if (is_ht40minus_chan(dut->ap_channel)) 7593 ht40minus = 1; 7594 7595 fprintf(f, "ht_capab=%s%s\n", 7596 ht40plus ? "[HT40+]" : "", 7597 ht40minus ? "[HT40-]" : ""); 7598 } 7599 } 7600 7601 if ((drv == DRIVER_MAC80211 || drv == DRIVER_QNXNTO || 7602 drv == DRIVER_LINUX_WCN) && 7603 (dut->ap_mode == AP_11ac || dut->ap_mode == AP_11na)) { 7604 if (dut->ap_countrycode[0]) { 7605 fprintf(f, "country_code=%s\n", dut->ap_countrycode); 7606 fprintf(f, "ieee80211d=1\n"); 7607 fprintf(f, "ieee80211h=1\n"); 7608 } 7609 } 7610 7611 if (drv == DRIVER_LINUX_WCN && dut->ap_mode == AP_11ax) { 7612 if (dut->ap_txBF) { 7613 fprintf(f, "he_su_beamformer=1\n"); 7614 fprintf(f, "he_su_beamformee=1\n"); 7615 if (dut->ap_mu_txBF) 7616 fprintf(f, "he_mu_beamformer=1\n"); 7617 } else { 7618 fprintf(f, "he_su_beamformer=0\n"); 7619 fprintf(f, "he_su_beamformee=0\n"); 7620 fprintf(f, "he_mu_beamformer=0\n"); 7621 } 7622 } 7623 7624 fprintf(f, "interface=%s\n", ifname); 7625 if (dut->bridge) 7626 fprintf(f, "bridge=%s\n", dut->bridge); 7627 fprintf(f, "channel=%d\n", dut->ap_channel); 7628 7629 if (sigma_hapd_ctrl) 7630 fprintf(f, "ctrl_interface=%s\n", sigma_hapd_ctrl); 7631 else 7632 fprintf(f, "ctrl_interface=/var/run/hostapd\n"); 7633 7634 if (dut->ap_ssid[0]) 7635 fprintf(f, "ssid=%s\n", dut->ap_ssid); 7636 else 7637 fprintf(f, "ssid=QCA AP OOB\n"); 7638 if (dut->ap_bcnint) 7639 fprintf(f, "beacon_int=%d\n", dut->ap_bcnint); 7640 if (dut->ap_start_disabled) 7641 fprintf(f, "start_disabled=1\n"); 7642 7643 if (dut->ap_akm_values) { 7644 struct { 7645 int akm; 7646 const char *str; 7647 } akms[] = { 7648 { AKM_WPA_EAP, "WPA-EAP" }, 7649 { AKM_WPA_PSK, "WPA-PSK" }, 7650 { AKM_FT_EAP, "FT-EAP" }, 7651 { AKM_FT_PSK, "FT-PSK" }, 7652 { AKM_EAP_SHA256, "WPA-EAP-SHA256" }, 7653 { AKM_PSK_SHA256, "WPA-PSK-SHA256" }, 7654 { AKM_SAE, "SAE" }, 7655 { AKM_FT_SAE, "FT-SAE" }, 7656 { AKM_SUITE_B, "WPA-EAP-SUITE-B-192" }, 7657 { AKM_FT_SUITE_B, "FT-EAP-SHA384" }, 7658 { AKM_FILS_SHA256, "FILS-SHA256" }, 7659 { AKM_FILS_SHA384, "FILS-SHA384" }, 7660 { AKM_FT_FILS_SHA256, "FT-FILS-SHA256" }, 7661 { AKM_FT_FILS_SHA384, "FT-FILS-SHA384" }, 7662 }; 7663 int first = 1; 7664 unsigned int i; 7665 7666 fprintf(f, "wpa_key_mgmt="); 7667 for (i = 0; i < ARRAY_SIZE(akms); i++) { 7668 if (dut->ap_akm_values & (1 << akms[i].akm)) { 7669 fprintf(f, "%s%s", first ? "" : " ", 7670 akms[i].str); 7671 first = 0; 7672 } 7673 } 7674 fprintf(f, "\n"); 7675 /* TODO: mixed mode and WPAv1 only */ 7676 fprintf(f, "wpa=2\n"); 7677 fprintf(f, "wpa_pairwise=%s\n", 7678 hostapd_cipher_name(dut->ap_cipher)); 7679 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7680 fprintf(f, "group_cipher=%s\n", 7681 hostapd_cipher_name(dut->ap_group_cipher)); 7682 if ((dut->ap_akm_values & 7683 ((1 << AKM_SAE) | (1 << AKM_FT_SAE))) && 7684 !(dut->ap_akm_values & 7685 ((1 << AKM_WPA_PSK) | (1 << AKM_FT_PSK))) && 7686 dut->ap_passphrase[0]) 7687 fprintf(f, "sae_password=%s\n", dut->ap_passphrase); 7688 else if (!dut->ap_passphrase[0] && dut->ap_psk[0]) 7689 fprintf(f, "wpa_psk=%s", dut->ap_psk); 7690 else if (dut->ap_passphrase[0]) 7691 fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase); 7692 if (dut->ap_akm_values & ((1 << AKM_WPA_EAP) | 7693 (1 << AKM_FT_EAP) | 7694 (1 << AKM_EAP_SHA256) | 7695 (1 << AKM_SUITE_B) | 7696 (1 << AKM_FT_SUITE_B) | 7697 (1 << AKM_FILS_SHA256) | 7698 (1 << AKM_FILS_SHA384) | 7699 (1 << AKM_FT_FILS_SHA256) | 7700 (1 << AKM_FT_FILS_SHA384))) { 7701 fprintf(f, "ieee8021x=1\n"); 7702 fprintf(f, "auth_server_addr=%s\n", 7703 dut->ap_radius_ipaddr); 7704 if (dut->ap_radius_port) 7705 fprintf(f, "auth_server_port=%d\n", 7706 dut->ap_radius_port); 7707 fprintf(f, "auth_server_shared_secret=%s\n", 7708 dut->ap_radius_password); 7709 } 7710 goto skip_key_mgmt; 7711 } 7712 7713 switch (dut->ap_key_mgmt) { 7714 case AP_OPEN: 7715 if (dut->ap_cipher == AP_WEP) 7716 fprintf(f, "wep_key0=%s\n", dut->ap_wepkey); 7717 break; 7718 case AP_WPA2_PSK: 7719 case AP_WPA2_PSK_MIXED: 7720 case AP_WPA_PSK: 7721 case AP_WPA2_SAE: 7722 case AP_WPA2_PSK_SAE: 7723 case AP_WPA2_PSK_SHA256: 7724 case AP_WPA2_FT_PSK: 7725 if (dut->ap_key_mgmt == AP_WPA2_PSK || 7726 dut->ap_key_mgmt == AP_WPA2_SAE || 7727 dut->ap_key_mgmt == AP_WPA2_PSK_SAE || 7728 dut->ap_key_mgmt == AP_WPA2_PSK_SHA256 || 7729 dut->ap_key_mgmt == AP_WPA2_FT_PSK) 7730 fprintf(f, "wpa=2\n"); 7731 else if (dut->ap_key_mgmt == AP_WPA2_PSK_MIXED) 7732 fprintf(f, "wpa=3\n"); 7733 else 7734 fprintf(f, "wpa=1\n"); 7735 if (dut->ap_key_mgmt == AP_WPA2_SAE) 7736 key_mgmt = "SAE"; 7737 else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 7738 key_mgmt = "WPA-PSK SAE"; 7739 else 7740 key_mgmt = "WPA-PSK"; 7741 switch (dut->ap_pmf) { 7742 case AP_PMF_DISABLED: 7743 fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt, 7744 dut->ap_add_sha256 ? " WPA-PSK-SHA256" : ""); 7745 break; 7746 case AP_PMF_OPTIONAL: 7747 fprintf(f, "wpa_key_mgmt=%s%s\n", key_mgmt, 7748 dut->ap_add_sha256 ? " WPA-PSK-SHA256" : ""); 7749 break; 7750 case AP_PMF_REQUIRED: 7751 if (dut->ap_key_mgmt == AP_WPA2_SAE) 7752 key_mgmt = "SAE"; 7753 else if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE) 7754 key_mgmt = "WPA-PSK-SHA256 SAE"; 7755 else 7756 key_mgmt = "WPA-PSK-SHA256"; 7757 fprintf(f, "wpa_key_mgmt=%s\n", key_mgmt); 7758 break; 7759 } 7760 if (dut->ap_key_mgmt == AP_WPA2_PSK_SHA256) 7761 fprintf(f, "wpa_key_mgmt=WPA-PSK-SHA256\n"); 7762 else if (dut->ap_key_mgmt == AP_WPA2_FT_PSK) 7763 fprintf(f, "wpa_key_mgmt=FT-PSK\n"); 7764 fprintf(f, "wpa_pairwise=%s\n", 7765 hostapd_cipher_name(dut->ap_cipher)); 7766 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7767 fprintf(f, "group_cipher=%s\n", 7768 hostapd_cipher_name(dut->ap_group_cipher)); 7769 if (dut->ap_key_mgmt == AP_WPA2_SAE) 7770 fprintf(f, "sae_password=%s\n", dut->ap_passphrase); 7771 else if (!dut->ap_passphrase[0] && dut->ap_psk[0]) 7772 fprintf(f, "wpa_psk=%s", dut->ap_psk); 7773 else 7774 fprintf(f, "wpa_passphrase=%s\n", dut->ap_passphrase); 7775 break; 7776 case AP_WPA2_EAP: 7777 case AP_WPA2_EAP_MIXED: 7778 case AP_WPA_EAP: 7779 case AP_WPA2_EAP_OSEN: 7780 case AP_WPA2_EAP_SHA256: 7781 case AP_WPA2_FT_EAP: 7782 case AP_WPA2_ENT_FT_EAP: 7783 fprintf(f, "ieee8021x=1\n"); 7784 if (dut->ap_key_mgmt == AP_WPA2_EAP || 7785 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN || 7786 dut->ap_key_mgmt == AP_WPA2_EAP_SHA256 || 7787 dut->ap_key_mgmt == AP_WPA2_FT_EAP || 7788 dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP) 7789 fprintf(f, "wpa=2\n"); 7790 else if (dut->ap_key_mgmt == AP_WPA2_EAP_MIXED) 7791 fprintf(f, "wpa=3\n"); 7792 else 7793 fprintf(f, "wpa=1\n"); 7794 switch (dut->ap_pmf) { 7795 case AP_PMF_DISABLED: 7796 fprintf(f, "wpa_key_mgmt=WPA-EAP%s\n", 7797 dut->ap_add_sha256 ? " WPA-EAP-SHA256" : ""); 7798 break; 7799 case AP_PMF_OPTIONAL: 7800 fprintf(f, "wpa_key_mgmt=WPA-EAP%s%s\n", 7801 dut->ap_add_sha256 ? " WPA-EAP-SHA256" : "", 7802 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" : 7803 ""); 7804 break; 7805 case AP_PMF_REQUIRED: 7806 fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256%s\n", 7807 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN ? " OSEN" : 7808 ""); 7809 break; 7810 } 7811 if (dut->ap_key_mgmt == AP_WPA2_EAP_SHA256) 7812 fprintf(f, "wpa_key_mgmt=WPA-EAP-SHA256\n"); 7813 else if (dut->ap_key_mgmt == AP_WPA2_FT_EAP) 7814 fprintf(f, "wpa_key_mgmt=FT-EAP\n"); 7815 else if (dut->ap_key_mgmt == AP_WPA2_ENT_FT_EAP) 7816 fprintf(f, "wpa_key_mgmt=FT-EAP WPA-EAP\n"); 7817 fprintf(f, "wpa_pairwise=%s\n", 7818 hostapd_cipher_name(dut->ap_cipher)); 7819 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7820 fprintf(f, "group_cipher=%s\n", 7821 hostapd_cipher_name(dut->ap_group_cipher)); 7822 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr); 7823 if (dut->ap_radius_port) 7824 fprintf(f, "auth_server_port=%d\n", 7825 dut->ap_radius_port); 7826 fprintf(f, "auth_server_shared_secret=%s\n", 7827 dut->ap_radius_password); 7828 if (dut->program == PROGRAM_HS2_R3) { 7829 fprintf(f, "radius_das_port=3799\n"); 7830 fprintf(f, "radius_das_client=0.0.0.0 %s\n", 7831 dut->ap_radius_password); 7832 fprintf(f, "radius_das_require_event_timestamp=1\n"); 7833 } 7834 break; 7835 case AP_SUITEB: 7836 fprintf(f, "ieee8021x=1\n"); 7837 fprintf(f, "wpa=2\n"); 7838 fprintf(f, "wpa_key_mgmt=WPA-EAP-SUITE-B-192\n"); 7839 fprintf(f, "wpa_pairwise=%s\n", 7840 hostapd_cipher_name(dut->ap_cipher)); 7841 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7842 fprintf(f, "group_cipher=%s\n", 7843 hostapd_cipher_name(dut->ap_group_cipher)); 7844 if (dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET) 7845 fprintf(f, "group_mgmt_cipher=%s\n", 7846 hostapd_group_mgmt_cipher_name( 7847 dut->ap_group_mgmt_cipher)); 7848 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr); 7849 if (dut->ap_radius_port) 7850 fprintf(f, "auth_server_port=%d\n", 7851 dut->ap_radius_port); 7852 fprintf(f, "auth_server_shared_secret=%s\n", 7853 dut->ap_radius_password); 7854 break; 7855 case AP_WPA2_OWE: 7856 fprintf(f, "wpa=2\n"); 7857 fprintf(f, "wpa_key_mgmt=OWE\n"); 7858 fprintf(f, "rsn_pairwise=%s\n", 7859 hostapd_cipher_name(dut->ap_cipher)); 7860 if (dut->ap_sae_groups) { 7861 fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups); 7862 if (dut->owe_ptk_workaround) 7863 fprintf(f, "owe_ptk_workaround=1\n"); 7864 } 7865 break; 7866 case AP_OSEN: 7867 fprintf(f, "osen=1\n"); 7868 fprintf(f, "disable_dgaf=1\n"); 7869 fprintf(f, "wpa_pairwise=%s\n", 7870 hostapd_cipher_name(dut->ap_cipher)); 7871 if (dut->ap_group_cipher != AP_NO_GROUP_CIPHER_SET) 7872 fprintf(f, "group_cipher=%s\n", 7873 hostapd_cipher_name(dut->ap_group_cipher)); 7874 fprintf(f, "auth_server_addr=%s\n", dut->ap_radius_ipaddr); 7875 if (dut->ap_radius_port) 7876 fprintf(f, "auth_server_port=%d\n", 7877 dut->ap_radius_port); 7878 fprintf(f, "auth_server_shared_secret=%s\n", 7879 dut->ap_radius_password); 7880 break; 7881 } 7882 skip_key_mgmt: 7883 7884 if (dut->ap_sae_passwords) { 7885 char *tmp, *pos, *end, *id; 7886 7887 tmp = strdup(dut->ap_sae_passwords); 7888 if (!tmp) { 7889 fclose(f); 7890 return ERROR_SEND_STATUS; 7891 } 7892 7893 pos = tmp; 7894 while (*pos) { 7895 end = strchr(pos, ';'); 7896 if (end) 7897 *end = '\0'; 7898 id = strchr(pos, ':'); 7899 if (id) 7900 *id++ = '\0'; 7901 7902 fprintf(f, "sae_password=%s%s%s\n", 7903 pos, id ? "|id=" : "", id ? id : ""); 7904 if (!end) 7905 break; 7906 pos = end + 1; 7907 } 7908 7909 free(tmp); 7910 } 7911 7912 if (dut->ap_rsn_preauth) 7913 fprintf(f, "rsn_preauth=1\n"); 7914 7915 if (dut->ap_pmksa && dut->ap_pmksa_caching) 7916 fprintf(f, "disable_pmksa_caching=1\n"); 7917 7918 if (dut->ap_beacon_prot) 7919 fprintf(f, "beacon_prot=1\n"); 7920 7921 if (dut->ap_transition_disable) 7922 fprintf(f, "transition_disable=0x%02x\n", 7923 dut->ap_transition_disable); 7924 7925 if (dut->ap_ocvc == 1 || dut->ap_ocvc == 0) 7926 fprintf(f, "ocv=%d\n", dut->ap_ocvc); 7927 7928 switch (dut->ap_pmf) { 7929 case AP_PMF_DISABLED: 7930 break; 7931 case AP_PMF_OPTIONAL: 7932 fprintf(f, "ieee80211w=1\n"); 7933 if (dut->ap_key_mgmt == AP_WPA2_PSK_SAE || 7934 (dut->ap_akm_values & (AKM_SAE | AKM_WPA_PSK)) == 7935 (AKM_SAE | AKM_WPA_PSK)) 7936 fprintf(f, "sae_require_mfp=1\n"); 7937 break; 7938 case AP_PMF_REQUIRED: 7939 fprintf(f, "ieee80211w=2\n"); 7940 break; 7941 } 7942 7943 if (dut->ap_pmf != AP_PMF_DISABLED && 7944 dut->ap_group_mgmt_cipher != AP_NO_GROUP_MGMT_CIPHER_SET) 7945 fprintf(f, "group_mgmt_cipher=%s\n", 7946 hostapd_group_mgmt_cipher_name( 7947 dut->ap_group_mgmt_cipher)); 7948 7949 if (ap_ft_enabled(dut)) { 7950 unsigned char own_addr[ETH_ALEN]; 7951 7952 fprintf(f, "mobility_domain=%s\n", dut->ap_mobility_domain); 7953 fprintf(f, "ft_over_ds=%d\n", dut->ap_ft_ds == VALUE_ENABLED); 7954 if (get_hwaddr(ifname, own_addr) < 0) { 7955 memset(own_addr, 0, ETH_ALEN); 7956 own_addr[0] = 0x02; 7957 } 7958 fprintf(f, 7959 "nas_identifier=%02x%02x%02x%02x%02x%02x.nas.example.com\n", 7960 own_addr[0], own_addr[1], own_addr[2], 7961 own_addr[3], own_addr[4], own_addr[5]); 7962 fprintf(f, "r1_key_holder=%02x%02x%02x%02x%02x%02x\n", 7963 own_addr[0], own_addr[1], own_addr[2], 7964 own_addr[3], own_addr[4], own_addr[5]); 7965 fprintf(f, "ft_psk_generate_local=1\n"); 7966 fprintf(f, "pmk_r1_push=0\n"); 7967 fprintf(f, 7968 "r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n"); 7969 fprintf(f, 7970 "r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\n"); 7971 } 7972 7973 if (dut->rsne_override) 7974 fprintf(f, "own_ie_override=%s\n", dut->rsne_override); 7975 if (dut->rsnxe_override_eapol) 7976 fprintf(f, "rsnxe_override_eapol=%s\n", 7977 dut->rsnxe_override_eapol); 7978 7979 if (dut->sae_commit_override) 7980 fprintf(f, "sae_commit_override=%s\n", 7981 dut->sae_commit_override); 7982 7983 if (dut->ap_sae_groups) 7984 fprintf(f, "sae_groups=%s\n", dut->ap_sae_groups); 7985 7986 if (dut->sae_pwe != SAE_PWE_DEFAULT || dut->sae_h2e_default) { 7987 const char *sae_pwe = NULL; 7988 7989 if (dut->sae_pwe == SAE_PWE_LOOP && sae_pw_id_used(dut)) 7990 sae_pwe = "3"; 7991 else if (dut->sae_pwe == SAE_PWE_LOOP) 7992 sae_pwe = "0"; 7993 else if (dut->sae_pwe == SAE_PWE_H2E) 7994 sae_pwe = "1"; 7995 else if (dut->sae_h2e_default) 7996 sae_pwe = "2"; 7997 if (sae_pwe) 7998 fprintf(f, "sae_pwe=%s\n", sae_pwe); 7999 } 8000 8001 if (dut->sae_anti_clogging_threshold >= 0) 8002 fprintf(f, "sae_anti_clogging_threshold=%d\n", 8003 dut->sae_anti_clogging_threshold); 8004 if (dut->sae_reflection) 8005 fprintf(f, "sae_reflection_attack=1\n"); 8006 if (dut->sae_confirm_immediate) 8007 fprintf(f, "sae_confirm_immediate=2\n"); 8008 8009 if (dut->ap_p2p_mgmt) 8010 fprintf(f, "manage_p2p=1\n"); 8011 8012 if (dut->ap_tdls_prohibit || dut->ap_l2tif) 8013 fprintf(f, "tdls_prohibit=1\n"); 8014 if (dut->ap_tdls_prohibit_chswitch || dut->ap_l2tif) 8015 fprintf(f, "tdls_prohibit_chan_switch=1\n"); 8016 if (dut->ap_p2p_cross_connect >= 0) { 8017 fprintf(f, "manage_p2p=1\n" 8018 "allow_cross_connection=%d\n", 8019 dut->ap_p2p_cross_connect); 8020 } 8021 8022 if (dut->ap_l2tif || dut->ap_proxy_arp || 8023 dut->ap_key_mgmt == AP_WPA2_EAP_OSEN) { 8024 if (!dut->bridge) { 8025 sigma_dut_print(dut, DUT_MSG_ERROR, 8026 "Bridge must be configured. Run with -b <brname>."); 8027 fclose(f); 8028 return -2; 8029 } 8030 fprintf(f, "ap_isolate=1\n"); 8031 } 8032 8033 if (dut->ap_proxy_arp) 8034 fprintf(f, "proxy_arp=1\n"); 8035 8036 if (dut->ap_wme) 8037 fprintf(f, "wmm_enabled=1\n"); 8038 8039 if (dut->ap_wmmps == AP_WMMPS_ON) 8040 fprintf(f, "uapsd_advertisement_enabled=1\n"); 8041 8042 if (dut->ap_hs2) { 8043 if (dut->ap_bss_load) { 8044 char *bss_load; 8045 8046 switch (dut->ap_bss_load) { 8047 case -1: 8048 bss_load = "bss_load_update_period=10"; 8049 break; 8050 case 1: 8051 /* STA count: 1, CU: 50, AAC: 65535 */ 8052 bss_load = "bss_load_test=1:50:65535"; 8053 break; 8054 case 2: 8055 /* STA count: 1, CU: 200, AAC: 65535 */ 8056 bss_load = "bss_load_test=1:200:65535"; 8057 break; 8058 case 3: 8059 /* STA count: 1, CU: 75, AAC: 65535 */ 8060 bss_load = "bss_load_test=1:75:65535"; 8061 break; 8062 default: 8063 bss_load = NULL; 8064 break; 8065 } 8066 8067 if (!bss_load) { 8068 fclose(f); 8069 return -2; 8070 } 8071 fprintf(f, "%s\n", bss_load); 8072 } 8073 8074 if (append_hostapd_conf_hs2(dut, f)) { 8075 fclose(f); 8076 return -2; 8077 } 8078 } 8079 8080 if (dut->ap_interworking && append_hostapd_conf_interworking(dut, f)) { 8081 fclose(f); 8082 return -2; 8083 } 8084 8085 if (dut->ap_hs2 && strlen(dut->ap_tag_ssid[0])) { 8086 unsigned char bssid[6]; 8087 char ifname2[50]; 8088 8089 if (get_hwaddr(ifname, bssid)) { 8090 fclose(f); 8091 return -2; 8092 } 8093 if (bssid[0] & 0x02) 8094 bssid[5] ^= 0x01; 8095 else 8096 bssid[0] |= 0x02; 8097 8098 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname); 8099 fprintf(f, "bss=%s\n", ifname2); 8100 fprintf(f, "ssid=%s\n", dut->ap_tag_ssid[0]); 8101 if (dut->bridge) 8102 fprintf(f, "bridge=%s\n", dut->bridge); 8103 8104 if (drv == DRIVER_LINUX_WCN) 8105 fprintf(f, "use_driver_iface_addr=1\n"); 8106 else 8107 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", 8108 bssid[0], bssid[1], bssid[2], bssid[3], 8109 bssid[4], bssid[5]); 8110 8111 if (dut->ap_tag_key_mgmt[0] == AP2_OSEN) { 8112 fprintf(f, "osen=1\n"); 8113 /* Disable DGAF for OSEN BSS */ 8114 fprintf(f, "disable_dgaf=1\n"); 8115 fprintf(f, "ap_isolate=1\n"); 8116 if (strlen(dut->ap2_radius_ipaddr)) 8117 fprintf(f, "auth_server_addr=%s\n", 8118 dut->ap2_radius_ipaddr); 8119 if (dut->ap2_radius_port) 8120 fprintf(f, "auth_server_port=%d\n", 8121 dut->ap2_radius_port); 8122 if (strlen(dut->ap2_radius_password)) 8123 fprintf(f, "auth_server_shared_secret=%s\n", 8124 dut->ap2_radius_password); 8125 8126 set_ebtables_forward_drop(dut, ifname, ifname2); 8127 } else if (dut->ap2_osu) { 8128 fprintf(f, "ap_isolate=1\n"); 8129 set_ebtables_forward_drop(dut, ifname, ifname2); 8130 } 8131 8132 if (dut->ap2_proxy_arp) { 8133 if (!dut->bridge) { 8134 sigma_dut_print(dut, DUT_MSG_ERROR, 8135 "Bridge must be configured. Run with -b <brname>."); 8136 fclose(f); 8137 return -2; 8138 } 8139 fprintf(f, "ap_isolate=1\n"); 8140 fprintf(f, "proxy_arp=1\n"); 8141 8142 if (set_ebtables_proxy_arp(dut, "FORWARD", ifname2) || 8143 set_ebtables_proxy_arp(dut, "OUTPUT", ifname2)) { 8144 fclose(f); 8145 return -2; 8146 } 8147 8148 } 8149 } 8150 8151 if (dut->program == PROGRAM_WPS) { 8152 /* 60G WPS tests requires wps_state of 2 (configured) */ 8153 int wps_state = is_60g_sigma_dut(dut) ? 2 : 1; 8154 8155 fprintf(f, "eap_server=1\n" 8156 "wps_state=%d\n" 8157 "device_name=QCA AP\n" 8158 "manufacturer=QCA\n" 8159 "device_type=6-0050F204-1\n" 8160 "config_methods=label virtual_display %s" 8161 "virtual_push_button keypad%s\n" 8162 "ap_pin=12345670\n" 8163 "friendly_name=QCA Access Point\n" 8164 "upnp_iface=%s\n", 8165 wps_state, 8166 is_60g_sigma_dut(dut) ? "physical_display " : "", 8167 dut->ap_wpsnfc ? " nfc_interface ext_nfc_token" : "", 8168 dut->bridge ? dut->bridge : ifname); 8169 if (dut->wsc_fragment) { 8170 fprintf(f, "device_name=%s\n" 8171 "manufacturer=%s\n" 8172 "model_name=%s\n" 8173 "model_number=%s\n" 8174 "serial_number=%s\n", 8175 WPS_LONG_DEVICE_NAME, 8176 WPS_LONG_MANUFACTURER, 8177 WPS_LONG_MODEL_NAME, 8178 WPS_LONG_MODEL_NUMBER, 8179 WPS_LONG_SERIAL_NUMBER); 8180 } else { 8181 fprintf(f, "device_name=QCA AP\n" 8182 "manufacturer=QCA\n"); 8183 } 8184 if (dut->eap_fragment) 8185 fprintf(f, "fragment_size=128\n"); 8186 } 8187 8188 if (dut->ap_dpp_conf_addr && dut->ap_dpp_conf_pkhash) 8189 fprintf(f, "dpp_controller=ipaddr=%s pkhash=%s\n", 8190 dut->ap_dpp_conf_addr, dut->ap_dpp_conf_pkhash); 8191 8192 if (dut->ap_he_rtsthrshld == VALUE_ENABLED) 8193 fprintf(f, "he_rts_threshold=512\n"); 8194 else if (dut->ap_he_rtsthrshld == VALUE_DISABLED) 8195 fprintf(f, "he_rts_threshold=1024\n"); 8196 8197 if ((dut->program == PROGRAM_VHT) || 8198 (dut->program == PROGRAM_HE && dut->use_5g)) { 8199 int vht_oper_centr_freq_idx; 8200 8201 if (check_channel(dut->ap_channel) < 0) { 8202 send_resp(dut, conn, SIGMA_INVALID, 8203 "errorCode,Invalid channel"); 8204 fclose(f); 8205 return 0; 8206 } 8207 8208 switch (dut->ap_chwidth) { 8209 case AP_20: 8210 dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH; 8211 vht_oper_centr_freq_idx = 8212 get_oper_centr_freq_seq_idx(20, 8213 dut->ap_channel); 8214 break; 8215 case AP_40: 8216 dut->ap_vht_chwidth = AP_20_40_VHT_OPER_CHWIDTH; 8217 vht_oper_centr_freq_idx = 8218 get_oper_centr_freq_seq_idx(40, 8219 dut->ap_channel); 8220 break; 8221 case AP_80: 8222 dut->ap_vht_chwidth = AP_80_VHT_OPER_CHWIDTH; 8223 vht_oper_centr_freq_idx = 8224 get_oper_centr_freq_seq_idx(80, 8225 dut->ap_channel); 8226 break; 8227 case AP_160: 8228 dut->ap_vht_chwidth = AP_160_VHT_OPER_CHWIDTH; 8229 vht_oper_centr_freq_idx = 8230 get_oper_centr_freq_seq_idx(160, 8231 dut->ap_channel); 8232 break; 8233 default: 8234 dut->ap_vht_chwidth = VHT_DEFAULT_OPER_CHWIDTH; 8235 vht_oper_centr_freq_idx = 8236 get_oper_centr_freq_seq_idx(80, 8237 dut->ap_channel); 8238 break; 8239 } 8240 fprintf(f, "vht_oper_centr_freq_seg0_idx=%d\n", 8241 vht_oper_centr_freq_idx); 8242 fprintf(f, "vht_oper_chwidth=%d\n", dut->ap_vht_chwidth); 8243 if (dut->ap_mode == AP_11ax) { 8244 fprintf(f, "he_oper_chwidth=%d\n", dut->ap_vht_chwidth); 8245 fprintf(f, "he_oper_centr_freq_seg0_idx=%d\n", 8246 vht_oper_centr_freq_idx); 8247 } 8248 8249 if (dut->ap_sgi80 || dut->ap_txBF || 8250 dut->ap_ldpc != VALUE_NOT_SET || 8251 dut->ap_tx_stbc || dut->ap_mu_txBF) { 8252 fprintf(f, "vht_capab=%s%s%s%s%s\n", 8253 dut->ap_sgi80 ? "[SHORT-GI-80]" : "", 8254 dut->ap_txBF ? 8255 "[SU-BEAMFORMER][SU-BEAMFORMEE][BF-ANTENNA-2][SOUNDING-DIMENSION-2]" : "", 8256 (dut->ap_ldpc == VALUE_ENABLED) ? 8257 "[RXLDPC]" : "", 8258 dut->ap_tx_stbc ? "[TX-STBC-2BY1]" : "", 8259 dut->ap_mu_txBF ? "[MU-BEAMFORMER]" : ""); 8260 } 8261 } 8262 8263 if (dut->ap_key_mgmt == AP_WPA2_OWE && dut->ap_tag_ssid[0][0] && 8264 dut->ap_tag_key_mgmt[0] == AP2_OPEN) { 8265 /* OWE transition mode */ 8266 unsigned char bssid[6]; 8267 char ifname2[50]; 8268 unsigned long val; 8269 FILE *f2; 8270 8271 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname); 8272 8273 fprintf(f, "owe_transition_ifname=%s\n", ifname2); 8274 val = 0x12345678; /* default to something */ 8275 f2 = fopen("/dev/urandom", "r"); 8276 if (f2) { 8277 if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) { 8278 sigma_dut_print(dut, DUT_MSG_ERROR, 8279 "Could not read /dev/urandom"); 8280 } 8281 fclose(f2); 8282 } 8283 fprintf(f, "ssid=owe-%lx\n", val); 8284 fprintf(f, "ignore_broadcast_ssid=1\n"); 8285 8286 if (get_hwaddr(ifname, bssid)) { 8287 fclose(f); 8288 return -2; 8289 } 8290 if (bssid[0] & 0x02) 8291 bssid[5] ^= 0x01; 8292 else 8293 bssid[0] |= 0x02; 8294 8295 fprintf(f, "bss=%s\n", ifname2); 8296 fprintf(f, "ssid=%s\n", dut->ap_ssid); 8297 if (dut->bridge) 8298 fprintf(f, "bridge=%s\n", dut->bridge); 8299 if (drv == DRIVER_LINUX_WCN) 8300 fprintf(f, "use_driver_iface_addr=1\n"); 8301 else 8302 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", 8303 bssid[0], bssid[1], bssid[2], bssid[3], 8304 bssid[4], bssid[5]); 8305 fprintf(f, "owe_transition_ifname=%s\n", ifname); 8306 } 8307 8308 if (dut->ap_key_mgmt == AP_OPEN && 8309 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) { 8310 /* OWE transition mode */ 8311 unsigned char bssid[6]; 8312 char ifname2[50]; 8313 unsigned long val; 8314 FILE *f2; 8315 8316 snprintf(ifname2, sizeof(ifname2), "%s_1", ifname); 8317 8318 fprintf(f, "owe_transition_ifname=%s\n", ifname2); 8319 fprintf(f, "ssid=%s\n", dut->ap_ssid); 8320 8321 if (get_hwaddr(ifname, bssid)) { 8322 fclose(f); 8323 return -2; 8324 } 8325 if (bssid[0] & 0x02) 8326 bssid[5] ^= 0x01; 8327 else 8328 bssid[0] |= 0x02; 8329 8330 fprintf(f, "bss=%s\n", ifname2); 8331 val = 0x12345678; /* default to something */ 8332 f2 = fopen("/dev/urandom", "r"); 8333 if (f2) { 8334 if (fread(&val, 1, sizeof(val), f2) != sizeof(val)) { 8335 sigma_dut_print(dut, DUT_MSG_ERROR, 8336 "Could not read /dev/urandom"); 8337 } 8338 fclose(f2); 8339 } 8340 fprintf(f, "ssid=owe-%lx\n", val); 8341 if (dut->bridge) 8342 fprintf(f, "bridge=%s\n", dut->bridge); 8343 if (drv == DRIVER_LINUX_WCN) 8344 fprintf(f, "use_driver_iface_addr=1\n"); 8345 else 8346 fprintf(f, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", 8347 bssid[0], bssid[1], bssid[2], bssid[3], 8348 bssid[4], bssid[5]); 8349 fprintf(f, "owe_transition_ifname=%s\n", ifname); 8350 fprintf(f, "wpa=2\n"); 8351 fprintf(f, "wpa_key_mgmt=OWE\n"); 8352 fprintf(f, "rsn_pairwise=CCMP\n"); 8353 fprintf(f, "ieee80211w=2\n"); 8354 fprintf(f, "ignore_broadcast_ssid=1\n"); 8355 if (dut->ap_sae_groups) { 8356 fprintf(f, "owe_groups=%s\n", dut->ap_sae_groups); 8357 if (dut->owe_ptk_workaround) 8358 fprintf(f, "owe_ptk_workaround=1\n"); 8359 } 8360 } 8361 8362 if (dut->program == PROGRAM_OCE) { 8363 fprintf(f, "oce=%d\n", 8364 dut->dev_role == DEVROLE_STA_CFON ? 2 : 1); 8365 } 8366 fclose(f); 8367 if (dut->use_hostapd_pid_file) 8368 kill_hostapd_process_pid(dut); 8369 #ifdef __QNXNTO__ 8370 if (system("slay hostapd") == 0) 8371 #else /* __QNXNTO__ */ 8372 if (!dut->use_hostapd_pid_file && 8373 (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 || 8374 system("killall hostapd") == 0)) 8375 #endif /* __QNXNTO__ */ 8376 { 8377 int i; 8378 /* Wait some time to allow hostapd to complete cleanup before 8379 * starting a new process */ 8380 for (i = 0; i < 10; i++) { 8381 usleep(500000); 8382 #ifdef __QNXNTO__ 8383 if (system("pidin | grep hostapd") != 0) 8384 break; 8385 #else /* __QNXNTO__ */ 8386 if (system("pidof hostapd") != 0) 8387 break; 8388 #endif /* __QNXNTO__ */ 8389 } 8390 } 8391 dut->hostapd_running = 0; 8392 8393 #ifdef ANDROID 8394 /* Set proper conf file permissions so that hostapd process 8395 * can access it. 8396 */ 8397 if (chmod(ap_conf_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) < 0) 8398 sigma_dut_print(dut, DUT_MSG_ERROR, 8399 "Error changing permissions"); 8400 8401 gr = getgrnam("wifi"); 8402 if (!gr || chown(ap_conf_path, -1, gr->gr_gid) < 0) 8403 sigma_dut_print(dut, DUT_MSG_ERROR, "Error changing groupid"); 8404 #endif /* ANDROID */ 8405 8406 f = fopen(ap_conf_path, "r"); 8407 if (f) { 8408 size_t len; 8409 8410 len = fread(buf, 1, sizeof(buf), f); 8411 fclose(f); 8412 if (len >= sizeof(buf)) 8413 len = sizeof(buf) - 1; 8414 buf[len] = '\0'; 8415 sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd debug log:\n%s", 8416 buf); 8417 } 8418 8419 if (drv == DRIVER_QNXNTO) { 8420 snprintf(buf, sizeof(buf), 8421 "hostapd -B %s%s%s %s%s %s/sigma_dut-ap.conf", 8422 dut->hostapd_debug_log ? "-dddKt " : "", 8423 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ? 8424 "-f " : "", 8425 dut->hostapd_debug_log ? dut->hostapd_debug_log : "", 8426 dut->hostapd_entropy_log ? " -e" : "", 8427 dut->hostapd_entropy_log ? dut->hostapd_entropy_log : 8428 "", 8429 dut->sigma_tmpdir); 8430 } else { 8431 /* 8432 * It looks like a monitor interface can cause some issues for 8433 * beaconing, so remove it (if injection was used) before 8434 * starting hostapd. 8435 */ 8436 if (if_nametoindex("sigmadut") > 0 && 8437 system("iw dev sigmadut del") != 0) 8438 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove " 8439 "monitor interface"); 8440 8441 snprintf(path, sizeof(path), "%shostapd", 8442 file_exists("hostapd") ? "./" : ""); 8443 snprintf(buf, sizeof(buf), 8444 "%s -B%s%s%s%s%s%s %s/sigma_dut-ap.conf", 8445 dut->hostapd_bin ? dut->hostapd_bin : path, 8446 dut->hostapd_debug_log ? " -dddKt" : "", 8447 (dut->hostapd_debug_log && dut->hostapd_debug_log[0]) ? 8448 " -f " : "", 8449 dut->hostapd_debug_log ? dut->hostapd_debug_log : "", 8450 dut->hostapd_entropy_log ? " -e" : "", 8451 dut->hostapd_entropy_log ? dut->hostapd_entropy_log : 8452 "", 8453 dut->use_hostapd_pid_file ? 8454 " -P " SIGMA_DUT_HOSTAPD_PID_FILE : "", 8455 dut->sigma_tmpdir); 8456 } 8457 8458 sigma_dut_print(dut, DUT_MSG_DEBUG, "hostapd command: %s", buf); 8459 if (system(buf) != 0) { 8460 send_resp(dut, conn, SIGMA_ERROR, 8461 "errorCode,Failed to start hostapd"); 8462 return 0; 8463 } 8464 8465 /* allow some time for hostapd to start before returning success */ 8466 usleep(500000); 8467 if (run_hostapd_cli(dut, "ping") != 0) { 8468 send_resp(dut, conn, SIGMA_ERROR, 8469 "errorCode,Failed to talk to hostapd"); 8470 return 0; 8471 } 8472 8473 if (dut->ap_ba_bufsize != BA_BUFSIZE_NOT_SET) { 8474 int buf_size; 8475 8476 if (dut->ap_ba_bufsize == BA_BUFSIZE_256) 8477 buf_size = 256; 8478 else 8479 buf_size = 64; 8480 8481 if ((drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) && 8482 sta_set_addba_buf_size(dut, ifname, buf_size)) { 8483 send_resp(dut, conn, SIGMA_ERROR, 8484 "ErrorCode,set_addba_buf_size failed"); 8485 return STATUS_SENT_ERROR; 8486 } 8487 8488 sigma_dut_print(dut, DUT_MSG_INFO, 8489 "setting addba buf_size=%d", buf_size); 8490 } 8491 8492 if (drv == DRIVER_LINUX_WCN) { 8493 const char *ifname_ptr = ifname; 8494 8495 if ((dut->ap_key_mgmt == AP_OPEN && 8496 dut->ap_tag_key_mgmt[0] == AP2_WPA2_OWE) || 8497 (dut->ap_key_mgmt == AP_WPA2_OWE && 8498 dut->ap_tag_ssid[0][0] && 8499 dut->ap_tag_key_mgmt[0] == AP2_OPEN)) { 8500 /* OWE transition mode */ 8501 if (dut->bridge) 8502 ifname_ptr = dut->bridge; 8503 } 8504 8505 sigma_dut_print(dut, DUT_MSG_INFO, 8506 "setting ip addr %s mask %s ifname %s", 8507 ap_inet_addr, ap_inet_mask, ifname_ptr); 8508 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s up", 8509 ifname_ptr, ap_inet_addr, ap_inet_mask); 8510 if (system(buf) != 0) { 8511 sigma_dut_print(dut, DUT_MSG_ERROR, 8512 "Failed to initialize the interface"); 8513 return -1; 8514 } 8515 } 8516 8517 /* Configure the driver with LDPC setting for AP mode as a new vdev is 8518 * created when hostapd is started. 8519 */ 8520 if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) 8521 wcn_config_ap_ldpc(dut, ifname); 8522 8523 if (dut->ap_l2tif) { 8524 snprintf(path, sizeof(path), 8525 "/sys/class/net/%s/brport/hairpin_mode", 8526 ifname); 8527 if (!file_exists(path)) { 8528 sigma_dut_print(dut, DUT_MSG_ERROR, 8529 "%s must be binded to the bridge for L2TIF", 8530 ifname); 8531 return -2; 8532 } 8533 8534 snprintf(buf, sizeof(buf), "echo 1 > %s", path); 8535 if (system(buf) != 0) { 8536 sigma_dut_print(dut, DUT_MSG_ERROR, 8537 "Failed to enable hairpin_mode for L2TIF"); 8538 return -2; 8539 } 8540 8541 snprintf(buf, sizeof(buf), "ebtables -P FORWARD ACCEPT"); 8542 if (system(buf) != 0) { 8543 sigma_dut_print(dut, DUT_MSG_ERROR, 8544 "Failed to set ebtables rules, RULE-9"); 8545 return -2; 8546 } 8547 8548 snprintf(buf, sizeof(buf), 8549 "ebtables -A FORWARD -p IPv4 --ip-proto icmp -i %s -j DROP", 8550 ifname); 8551 if (system(buf) != 0) { 8552 sigma_dut_print(dut, DUT_MSG_ERROR, 8553 "Failed to set ebtables rules, RULE-11"); 8554 return -2; 8555 } 8556 } 8557 8558 if (dut->ap_proxy_arp) { 8559 if (dut->ap_dgaf_disable) { 8560 if (set_ebtables_disable_dgaf(dut, "FORWARD", ifname) || 8561 set_ebtables_disable_dgaf(dut, "OUTPUT", ifname)) 8562 return -2; 8563 } else { 8564 if (set_ebtables_proxy_arp(dut, "FORWARD", ifname) || 8565 set_ebtables_proxy_arp(dut, "OUTPUT", ifname)) 8566 return -2; 8567 } 8568 8569 /* For 4.5-(c) */ 8570 snprintf(buf, sizeof(buf), 8571 "ebtables -A FORWARD -p ARP --arp-opcode 2 -i %s -j DROP", 8572 ifname); 8573 if (system(buf) != 0) { 8574 sigma_dut_print(dut, DUT_MSG_ERROR, 8575 "Failed to set ebtables rules, RULE-10"); 8576 return -2; 8577 } 8578 } 8579 8580 if (dut->ap_tdls_prohibit || dut->ap_l2tif) { 8581 /* Drop TDLS frames */ 8582 snprintf(buf, sizeof(buf), 8583 "ebtables -A FORWARD -p 0x890d -i %s -j DROP", ifname); 8584 if (system(buf) != 0) { 8585 sigma_dut_print(dut, DUT_MSG_ERROR, 8586 "Failed to set ebtables rules, RULE-13"); 8587 return -2; 8588 } 8589 } 8590 8591 if (dut->ap_fake_pkhash && 8592 run_hostapd_cli(dut, "set wps_corrupt_pkhash 1") != 0) { 8593 send_resp(dut, conn, SIGMA_ERROR, 8594 "errorCode,Could not enable FakePubKey"); 8595 return 0; 8596 } 8597 8598 if (dut->program == PROGRAM_60GHZ) { 8599 if (dut->ap_num_ese_allocs > 0) { 8600 /* wait extra time for AP to start */ 8601 sleep(2); 8602 if (ap_set_60g_ese(dut, dut->ap_num_ese_allocs, 8603 dut->ap_ese_allocs)) { 8604 send_resp(dut, conn, SIGMA_ERROR, 8605 "errorCode,Could not set ExtSch"); 8606 return 0; 8607 } 8608 } 8609 if (dut->ap_fixed_rate) { 8610 sigma_dut_print(dut, DUT_MSG_DEBUG, 8611 "forcing TX MCS index %d", 8612 dut->ap_mcs); 8613 if (ap_set_force_mcs(dut, 1, dut->ap_mcs)) { 8614 send_resp(dut, conn, SIGMA_ERROR, 8615 "errorCode,Could not force MCS"); 8616 return -2; 8617 } 8618 } 8619 } 8620 8621 if (dut->wps_forced_version) { 8622 snprintf(buf, sizeof(buf), "SET wps_version_number %d", 8623 dut->wps_forced_version); 8624 if (hapd_command(ifname, buf) < 0) { 8625 send_resp(dut, conn, SIGMA_ERROR, 8626 "errorCode,Fail to set wps_version_number"); 8627 return STATUS_SENT; 8628 } 8629 } 8630 8631 dut->hostapd_running = 1; 8632 return 1; 8633 } 8634 8635 8636 static int parse_qos_params(struct sigma_dut *dut, struct sigma_conn *conn, 8637 struct qos_params *qos, const char *cwmin, 8638 const char *cwmax, const char *aifs, 8639 const char *txop, const char *acm) 8640 { 8641 int val; 8642 8643 if (cwmin) { 8644 qos->ac = 1; 8645 val = atoi(cwmin); 8646 if (val < 0 || val > 15) { 8647 send_resp(dut, conn, SIGMA_INVALID, 8648 "errorCode,Invalid cwMin"); 8649 return 0; 8650 } 8651 qos->cwmin = val; 8652 } 8653 8654 if (cwmax) { 8655 qos->ac = 1; 8656 val = atoi(cwmax); 8657 if (val < 0 || val > 15) { 8658 send_resp(dut, conn, SIGMA_INVALID, 8659 "errorCode,Invalid cwMax"); 8660 return 0; 8661 } 8662 qos->cwmax = val; 8663 } 8664 8665 if (aifs) { 8666 qos->ac = 1; 8667 val = atoi(aifs); 8668 if (val < 1 || val > 255) { 8669 send_resp(dut, conn, SIGMA_INVALID, 8670 "errorCode,Invalid AIFS"); 8671 return 0; 8672 } 8673 qos->aifs = val; 8674 } 8675 8676 if (txop) { 8677 qos->ac = 1; 8678 val = atoi(txop); 8679 if (val < 0 || val > 0xffff) { 8680 send_resp(dut, conn, SIGMA_INVALID, 8681 "errorCode,Invalid txop"); 8682 return 0; 8683 } 8684 qos->txop = val * 32; 8685 } 8686 8687 if (acm) { 8688 qos->ac = 1; 8689 qos->acm = strcasecmp(acm, "on") == 0; 8690 } 8691 8692 return 1; 8693 } 8694 8695 8696 static enum sigma_cmd_result cmd_ap_set_apqos(struct sigma_dut *dut, 8697 struct sigma_conn *conn, 8698 struct sigma_cmd *cmd) 8699 { 8700 /* TXOP: The values provided here for VHT5G only */ 8701 if (!parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VO], 8702 get_param(cmd, "cwmin_VO"), 8703 get_param(cmd, "cwmax_VO"), 8704 get_param(cmd, "AIFS_VO"), 8705 get_param(cmd, "TXOP_VO"), 8706 get_param(cmd, "ACM_VO")) || 8707 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_VI], 8708 get_param(cmd, "cwmin_VI"), 8709 get_param(cmd, "cwmax_VI"), 8710 get_param(cmd, "AIFS_VI"), 8711 get_param(cmd, "TXOP_VI"), 8712 get_param(cmd, "ACM_VI")) || 8713 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BE], 8714 get_param(cmd, "cwmin_BE"), 8715 get_param(cmd, "cwmax_BE"), 8716 get_param(cmd, "AIFS_BE"), 8717 get_param(cmd, "TXOP_BE"), 8718 get_param(cmd, "ACM_BE")) || 8719 !parse_qos_params(dut, conn, &dut->ap_qos[AP_AC_BK], 8720 get_param(cmd, "cwmin_BK"), 8721 get_param(cmd, "cwmax_BK"), 8722 get_param(cmd, "AIFS_BK"), 8723 get_param(cmd, "TXOP_BK"), 8724 get_param(cmd, "ACM_BK"))) 8725 return 0; 8726 8727 return 1; 8728 } 8729 8730 8731 static enum sigma_cmd_result cmd_ap_set_staqos(struct sigma_dut *dut, 8732 struct sigma_conn *conn, 8733 struct sigma_cmd *cmd) 8734 { 8735 if (!parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VO], 8736 get_param(cmd, "cwmin_VO"), 8737 get_param(cmd, "cwmax_VO"), 8738 get_param(cmd, "AIFS_VO"), 8739 get_param(cmd, "TXOP_VO"), 8740 get_param(cmd, "ACM_VO")) || 8741 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_VI], 8742 get_param(cmd, "cwmin_VI"), 8743 get_param(cmd, "cwmax_VI"), 8744 get_param(cmd, "AIFS_VI"), 8745 get_param(cmd, "TXOP_VI"), 8746 get_param(cmd, "ACM_VI")) || 8747 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BE], 8748 get_param(cmd, "cwmin_BE"), 8749 get_param(cmd, "cwmax_BE"), 8750 get_param(cmd, "AIFS_BE"), 8751 get_param(cmd, "TXOP_BE"), 8752 get_param(cmd, "ACM_BE")) || 8753 !parse_qos_params(dut, conn, &dut->ap_sta_qos[AP_AC_BK], 8754 get_param(cmd, "cwmin_BK"), 8755 get_param(cmd, "cwmax_BK"), 8756 get_param(cmd, "AIFS_BK"), 8757 get_param(cmd, "TXOP_BK"), 8758 get_param(cmd, "ACM_BK"))) 8759 return 0; 8760 8761 return 1; 8762 } 8763 8764 8765 static void cmd_ath_ap_hs2_reset(struct sigma_dut *dut) 8766 { 8767 unsigned char bssid[6]; 8768 char buf[100]; 8769 run_system(dut, "cfg -a AP_SSID=\"Hotspot 2.0\""); 8770 run_system(dut, "cfg -a AP_PRIMARY_CH=1"); 8771 run_system(dut, "cfg -a AP_SECMODE=WPA"); 8772 run_system(dut, "cfg -a AP_SECFILE=EAP"); 8773 run_system(dut, "cfg -a AP_WPA=2"); 8774 run_system(dut, "cfg -a AP_CYPHER=CCMP"); 8775 run_system(dut, "cfg -a AP_HOTSPOT=1"); 8776 run_system(dut, "cfg -a AP_HOTSPOT_ANT=2"); 8777 run_system(dut, "cfg -a AP_HOTSPOT_INTERNET=0"); 8778 run_system(dut, "cfg -a AP_HOTSPOT_VENUEGROUP=2"); 8779 run_system(dut, "cfg -a AP_HOTSPOT_VENUETYPE=8"); 8780 run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM=506f9a"); 8781 run_system(dut, "cfg -a AP_HOTSPOT_ROAMINGCONSORTIUM2=001bc504bd"); 8782 if (!get_hwaddr("ath0", bssid)) { 8783 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=" 8784 "%02x:%02x:%02x:%02x:%02x:%02x", 8785 bssid[0], bssid[1], bssid[2], bssid[3], 8786 bssid[4], bssid[5]); 8787 run_system(dut, buf); 8788 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 8789 "%02x:%02x:%02x:%02x:%02x:%02x", 8790 bssid[0], bssid[1], bssid[2], bssid[3], 8791 bssid[4], bssid[5]); 8792 } else { 8793 if (!get_hwaddr("wifi0", bssid)) { 8794 snprintf(buf, sizeof(buf), "cfg -a AP_HOTSPOT_HESSID=" 8795 "%02x:%02x:%02x:%02x:%02x:%02x", 8796 bssid[0], bssid[1], bssid[2], bssid[3], 8797 bssid[4], bssid[5]); 8798 run_system(dut, buf); 8799 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), 8800 "%02x:%02x:%02x:%02x:%02x:%02x", 8801 bssid[0], bssid[1], bssid[2], bssid[3], 8802 bssid[4], bssid[5]); 8803 } else { 8804 /* load the driver and try again */ 8805 run_system(dut, "/etc/rc.d/rc.wlan up"); 8806 8807 if (!get_hwaddr("wifi0", bssid)) { 8808 snprintf(buf, sizeof(buf), 8809 "cfg -a AP_HOTSPOT_HESSID=" 8810 "%02x:%02x:%02x:%02x:%02x:%02x", 8811 bssid[0], bssid[1], bssid[2], 8812 bssid[3], bssid[4], bssid[5]); 8813 run_system(dut, buf); 8814 snprintf(dut->ap_hessid, 8815 sizeof(dut->ap_hessid), 8816 "%02x:%02x:%02x:%02x:%02x:%02x", 8817 bssid[0], bssid[1], bssid[2], 8818 bssid[3], bssid[4], bssid[5]); 8819 } 8820 } 8821 } 8822 8823 run_system(dut, "cfg -r AP_SSID_2"); 8824 run_system(dut, "cfg -c"); 8825 /* run_system(dut, "cfg -s"); */ 8826 } 8827 8828 8829 static void ath_reset_vht_defaults(struct sigma_dut *dut) 8830 { 8831 run_system(dut, "cfg -x"); 8832 run_system(dut, "cfg -a AP_RADIO_ID=1"); 8833 run_system(dut, "cfg -a AP_PRIMARY_CH_2=36"); 8834 run_system(dut, "cfg -a AP_STARTMODE=standard"); 8835 run_system(dut, "cfg -a AP_CHMODE_2=11ACVHT80"); 8836 run_system(dut, "cfg -a TX_CHAINMASK_2=7"); 8837 run_system(dut, "cfg -a RX_CHAINMASK_2=7"); 8838 run_system(dut, "cfg -a ATH_countrycode=0x348"); 8839 /* NOTE: For Beeliner we have to turn off MU-MIMO */ 8840 if (system("rm /tmp/secath*") != 0) { 8841 sigma_dut_print(dut, DUT_MSG_ERROR, 8842 "Failed to remove secath file"); 8843 } 8844 } 8845 8846 8847 static enum sigma_cmd_result cmd_ap_reset_default(struct sigma_dut *dut, 8848 struct sigma_conn *conn, 8849 struct sigma_cmd *cmd) 8850 { 8851 const char *type, *program; 8852 enum driver_type drv; 8853 char buf[128]; 8854 int i; 8855 8856 for (i = 0; i < MAX_WLAN_TAGS - 1; i++) { 8857 /* 8858 * Reset all tagged SSIDs to NULL-string and all key management 8859 * to open. 8860 */ 8861 dut->ap_tag_ssid[i][0] = '\0'; 8862 dut->ap_tag_key_mgmt[i] = AP2_OPEN; 8863 } 8864 8865 drv = get_driver_type(dut); 8866 8867 program = get_param(cmd, "program"); 8868 if (!program) 8869 program = get_param(cmd, "prog"); 8870 dut->program = sigma_program_to_enum(program); 8871 dut->device_type = AP_unknown; 8872 type = get_param(cmd, "type"); 8873 if (type && strcasecmp(type, "Testbed") == 0) 8874 dut->device_type = AP_testbed; 8875 if (type && strcasecmp(type, "DUT") == 0) 8876 dut->device_type = AP_dut; 8877 8878 dut->ap_rts = 0; 8879 dut->ap_frgmnt = 0; 8880 dut->ap_bcnint = 0; 8881 dut->ap_key_mgmt = AP_OPEN; 8882 dut->ap_ssid[0] = '\0'; 8883 dut->ap_fake_pkhash = 0; 8884 memset(dut->ap_qos, 0, sizeof(dut->ap_qos)); 8885 memset(dut->ap_sta_qos, 0, sizeof(dut->ap_sta_qos)); 8886 dut->ap_addba_reject = VALUE_NOT_SET; 8887 dut->ap_noack = VALUE_NOT_SET; 8888 dut->ap_is_dual = 0; 8889 dut->ap_mode = AP_inval; 8890 dut->ap_mode_1 = AP_inval; 8891 8892 dut->ap_allow_vht_wep = 0; 8893 dut->ap_allow_vht_tkip = 0; 8894 dut->ap_disable_protection = 0; 8895 memset(dut->ap_countrycode, 0, sizeof(dut->ap_countrycode)); 8896 dut->ap_dyn_bw_sig = VALUE_NOT_SET; 8897 dut->ap_ldpc = VALUE_NOT_SET; 8898 dut->ap_sig_rts = VALUE_NOT_SET; 8899 dut->ap_rx_amsdu = VALUE_NOT_SET; 8900 dut->ap_txBF = 0; 8901 dut->ap_mu_txBF = 0; 8902 dut->ap_chwidth = AP_AUTO; 8903 8904 dut->ap_rsn_preauth = 0; 8905 dut->ap_wpsnfc = 0; 8906 dut->ap_bss_load = -1; 8907 dut->ap_p2p_cross_connect = -1; 8908 8909 dut->ap_regulatory_mode = AP_80211D_MODE_DISABLED; 8910 dut->ap_dfs_mode = AP_DFS_MODE_DISABLED; 8911 dut->ap_chwidth_offset = SEC_CH_NO; 8912 8913 dut->mbo_pref_ap_cnt = 0; 8914 dut->ft_bss_mac_cnt = 0; 8915 dut->ap_interface_5g = 0; 8916 dut->ap_interface_2g = 0; 8917 dut->ap_pmf = AP_PMF_DISABLED; 8918 8919 dut->wsc_fragment = 0; 8920 dut->eap_fragment = 0; 8921 dut->wps_forced_version = 0; 8922 8923 if (dut->program == PROGRAM_HT || dut->program == PROGRAM_VHT) { 8924 dut->ap_wme = AP_WME_ON; 8925 dut->ap_wmmps = AP_WMMPS_ON; 8926 } else { 8927 dut->ap_wme = AP_WME_OFF; 8928 dut->ap_wmmps = AP_WMMPS_OFF; 8929 } 8930 8931 dut->ap_venue_url = 0; 8932 dut->ap_advice_of_charge = 0; 8933 dut->ap_oper_icon_metadata = 0; 8934 dut->ap_tnc_file_name = 0; 8935 dut->ap_tnc_time_stamp = 0; 8936 8937 dut->ap_akm_values = 0; 8938 free(dut->ap_sae_passwords); 8939 dut->ap_sae_passwords = NULL; 8940 8941 dut->ap_ocvc = -1; 8942 8943 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 || 8944 dut->program == PROGRAM_HS2_R3 || 8945 dut->program == PROGRAM_IOTLP) { 8946 int i; 8947 8948 if (drv == DRIVER_ATHEROS) 8949 cmd_ath_ap_hs2_reset(dut); 8950 else if (drv == DRIVER_OPENWRT) 8951 cmd_owrt_ap_hs2_reset(dut); 8952 8953 dut->ap_interworking = 1; 8954 dut->ap_access_net_type = 2; 8955 dut->ap_internet = 0; 8956 dut->ap_venue_group = 2; 8957 dut->ap_venue_type = 8; 8958 dut->ap_domain_name_list[0] = '\0'; 8959 dut->ap_hs2 = 1; 8960 snprintf(dut->ap_roaming_cons, sizeof(dut->ap_roaming_cons), 8961 "506f9a;001bc504bd"); 8962 dut->ap_l2tif = 0; 8963 dut->ap_proxy_arp = 0; 8964 if (dut->bridge) { 8965 char buf[50]; 8966 8967 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", 8968 dut->bridge); 8969 if (system(buf) != 0) { 8970 sigma_dut_print(dut, DUT_MSG_DEBUG, 8971 "%s ip neigh table flushing failed", 8972 dut->bridge); 8973 } 8974 8975 snprintf(buf, sizeof(buf), "ebtables -F"); 8976 if (system(buf) != 0) { 8977 sigma_dut_print(dut, DUT_MSG_DEBUG, 8978 "%s ebtables flushing failed", 8979 dut->bridge); 8980 } 8981 } 8982 dut->ap_dgaf_disable = 0; 8983 dut->ap_p2p_cross_connect = 0; 8984 dut->ap_gas_cb_delay = 0; 8985 dut->ap_nai_realm_list = 0; 8986 dut->ap_oper_name = 0; 8987 dut->ap_venue_name = 0; 8988 for (i = 0; i < 10; i++) { 8989 dut->ap_plmn_mcc[i][0] = '\0'; 8990 dut->ap_plmn_mnc[i][0] = '\0'; 8991 } 8992 dut->ap_wan_metrics = 0; 8993 dut->ap_conn_capab = 0; 8994 dut->ap_ip_addr_type_avail = 0; 8995 dut->ap_net_auth_type = 0; 8996 dut->ap_oper_class = 0; 8997 dut->ap_pmf = 0; 8998 dut->ap_add_sha256 = 0; 8999 } 9000 9001 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 || 9002 dut->program == PROGRAM_IOTLP) { 9003 int i; 9004 const char hessid[] = "50:6f:9a:00:11:22"; 9005 9006 memcpy(dut->ap_hessid, hessid, strlen(hessid) + 1); 9007 dut->ap_osu_ssid[0] = '\0'; 9008 dut->ap_pmf = 1; 9009 dut->ap_osu_provider_list = 0; 9010 dut->ap_osu_provider_nai_list = 0; 9011 for (i = 0; i < 10; i++) { 9012 dut->ap_osu_server_uri[i][0] = '\0'; 9013 dut->ap_osu_method[i] = 0xFF; 9014 } 9015 dut->ap_qos_map_set = 0; 9016 dut->ap_tag_key_mgmt[0] = AP2_OPEN; 9017 dut->ap2_proxy_arp = 0; 9018 dut->ap2_osu = 0; 9019 dut->ap_osu_icon_tag = 0; 9020 } 9021 9022 if (dut->program == PROGRAM_VHT) { 9023 /* Set up the defaults */ 9024 dut->use_5g = 1; 9025 dut->ap_mode = AP_11ac; 9026 dut->ap_channel = 36; 9027 dut->ap_ampdu = VALUE_NOT_SET; 9028 dut->ap_ndpa_frame = 1; 9029 if (dut->device_type == AP_testbed) { 9030 dut->ap_amsdu = VALUE_DISABLED; 9031 dut->ap_ldpc = VALUE_DISABLED; 9032 dut->ap_rx_amsdu = VALUE_DISABLED; 9033 dut->ap_sgi80 = 0; 9034 } else { 9035 dut->ap_amsdu = VALUE_ENABLED; 9036 /* 9037 * As LDPC is optional, don't enable this by default 9038 * for LINUX-WCN driver. The ap_set_wireless command 9039 * can be used to enable LDPC, when needed. 9040 */ 9041 if (drv != DRIVER_LINUX_WCN) 9042 dut->ap_ldpc = VALUE_ENABLED; 9043 dut->ap_rx_amsdu = VALUE_ENABLED; 9044 dut->ap_sgi80 = 1; 9045 } 9046 dut->ap_fixed_rate = 0; 9047 dut->ap_rx_streams = 3; 9048 dut->ap_tx_streams = 3; 9049 dut->ap_vhtmcs_map = 0; 9050 dut->ap_chwidth = AP_80; 9051 dut->ap_tx_stbc = 1; 9052 dut->ap_dyn_bw_sig = VALUE_ENABLED; 9053 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 9054 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED; 9055 if (get_driver_type(dut) == DRIVER_ATHEROS) 9056 ath_reset_vht_defaults(dut); 9057 } 9058 9059 if (dut->program == PROGRAM_IOTLP) { 9060 dut->wnm_bss_max_feature = VALUE_DISABLED; 9061 dut->wnm_bss_max_idle_time = 0; 9062 dut->wnm_bss_max_protection = VALUE_NOT_SET; 9063 dut->ap_proxy_arp = 1; 9064 } else { 9065 /* 9066 * Do not touch the BSS-MAX Idle time feature 9067 * if the program is not IOTLP. 9068 */ 9069 dut->wnm_bss_max_feature = VALUE_NOT_SET; 9070 dut->wnm_bss_max_idle_time = 0; 9071 dut->wnm_bss_max_protection = VALUE_NOT_SET; 9072 } 9073 9074 if (dut->program == PROGRAM_LOC) { 9075 dut->ap_rrm = 1; 9076 dut->ap_rtt = 1; 9077 dut->ap_lci = 0; 9078 dut->ap_val_lci[0] = '\0'; 9079 dut->ap_infoz[0] = '\0'; 9080 dut->ap_lcr = 0; 9081 dut->ap_val_lcr[0] = '\0'; 9082 dut->ap_neighap = 0; 9083 dut->ap_opchannel = 0; 9084 dut->ap_scan = 0; 9085 dut->ap_fqdn_held = 0; 9086 dut->ap_fqdn_supl = 0; 9087 dut->ap_interworking = 0; 9088 dut->ap_gas_cb_delay = 0; 9089 dut->ap_msnt_type = 0; 9090 } 9091 dut->ap_ft_oa = 0; 9092 dut->ap_ft_ds = VALUE_NOT_SET; 9093 dut->ap_reg_domain = REG_DOMAIN_NOT_SET; 9094 dut->ap_mobility_domain[0] = '\0'; 9095 9096 if (dut->program == PROGRAM_MBO) { 9097 dut->ap_mbo = 1; 9098 dut->ap_interworking = 1; 9099 dut->ap_ne_class = 0; 9100 dut->ap_ne_op_ch = 0; 9101 dut->ap_set_bssidpref = 1; 9102 dut->ap_btmreq_disassoc_imnt = 0; 9103 dut->ap_btmreq_term_bit = 0; 9104 dut->ap_disassoc_timer = 0; 9105 dut->ap_btmreq_bss_term_dur = 0; 9106 dut->ap_channel = 36; 9107 dut->ap_chwidth = AP_20; 9108 dut->ap_cell_cap_pref = 0; 9109 dut->ap_gas_cb_delay = 0; 9110 dut->mbo_self_ap_tuple.ap_ne_class = -1; 9111 dut->mbo_self_ap_tuple.ap_ne_pref = -1; /* Not set */ 9112 dut->mbo_self_ap_tuple.ap_ne_op_ch = -1; 9113 dut->ap_btmreq_bss_term_tsf = 0; 9114 dut->ap_assoc_delay = 0; 9115 } 9116 9117 if (dut->program == PROGRAM_OCE) { 9118 if (dut->ap_dhcp_stop) 9119 run_system(dut, "/etc/init.d/dnsmasq start"); 9120 9121 dut->ap_dhcp_stop = 0; 9122 dut->ap_oce = VALUE_ENABLED; 9123 dut->ap_broadcast_ssid = VALUE_ENABLED; 9124 dut->ap_fils_dscv_int = 20; 9125 dut->ap_filsdscv = VALUE_ENABLED; 9126 dut->ap_filshlp = VALUE_DISABLED; 9127 dut->ap_rnr = VALUE_DISABLED; 9128 dut->ap_nairealm[0] = '\0'; 9129 dut->ap_nairealm_int = 0; 9130 dut->ap_blechanutil = 0; 9131 dut->ap_ble_admit_cap = 0; 9132 dut->ap_esp = VALUE_ENABLED; 9133 dut->ap_datappdudura = 0; 9134 dut->ap_airtimefract = 0; 9135 dut->ap_blestacnt = 0; 9136 dut->ap_ul_availcap = 0; 9137 dut->ap_dl_availcap = 0; 9138 dut->ap_akm = 0; 9139 dut->ap_add_sha256 = 0; 9140 dut->ap_add_sha384 = 0; 9141 dut->ap_80plus80 = 0; 9142 } 9143 9144 dut->ap_he_ppdu = PPDU_NOT_SET; 9145 dut->ap_he_ulofdma = VALUE_NOT_SET; 9146 dut->ap_numsounddim = 0; 9147 dut->ap_bcc = VALUE_DISABLED; 9148 dut->ap_mu_edca = VALUE_DISABLED; 9149 dut->ap_he_mimo = MIMO_NOT_SET; 9150 dut->ap_he_rtsthrshld = VALUE_NOT_SET; 9151 dut->ap_mbssid = VALUE_DISABLED; 9152 dut->ap_ampdu = VALUE_NOT_SET; 9153 dut->he_mcsnssmap = 0; 9154 dut->ap_fixed_rate = 0; 9155 dut->he_mmss = 0; 9156 dut->he_set_sta_1x1 = VALUE_DISABLED; 9157 dut->he_srctrl_allow = -1; 9158 if (dut->device_type == AP_testbed) { 9159 dut->ap_he_dlofdma = VALUE_DISABLED; 9160 dut->ap_he_frag = VALUE_DISABLED; 9161 dut->ap_twtresp = VALUE_DISABLED; 9162 dut->he_ul_mcs = 7; 9163 } else { 9164 dut->ap_he_dlofdma = VALUE_NOT_SET; 9165 dut->ap_he_frag = VALUE_NOT_SET; 9166 dut->ap_ba_bufsize = BA_BUFSIZE_NOT_SET; 9167 dut->ap_twtresp = VALUE_NOT_SET; 9168 dut->he_ul_mcs = 0; 9169 } 9170 9171 if (dut->program == PROGRAM_HE) { 9172 if (dut->device_type == AP_testbed) { 9173 dut->ap_ldpc = VALUE_DISABLED; 9174 dut->ap_ba_bufsize = BA_BUFSIZE_64; 9175 dut->ap_amsdu = VALUE_DISABLED; 9176 dut->ap_txBF = 0; 9177 dut->ap_mu_txBF = 0; 9178 dut->he_sounding = VALUE_DISABLED; 9179 } else { 9180 if (drv == DRIVER_WCN || drv == DRIVER_LINUX_WCN) { 9181 dut->ap_txBF = 0; 9182 dut->ap_mu_txBF = 0; 9183 } else { 9184 dut->ap_txBF = 1; 9185 dut->ap_mu_txBF = 1; 9186 } 9187 dut->he_sounding = VALUE_ENABLED; 9188 if (drv == DRIVER_LINUX_WCN) { 9189 dut->ap_ldpc = VALUE_ENABLED; 9190 wcn_config_ap_ldpc(dut, get_main_ifname(dut)); 9191 #ifdef NL80211_SUPPORT 9192 if (wcn_set_he_ltf(dut, get_main_ifname(dut), 9193 QCA_WLAN_HE_LTF_AUTO)) { 9194 sigma_dut_print(dut, DUT_MSG_ERROR, 9195 "Failed to set LTF in ap_reset_default"); 9196 } 9197 #endif /* NL80211_SUPPORT */ 9198 } 9199 } 9200 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 9201 dut->ap_dfs_mode = AP_DFS_MODE_ENABLED; 9202 } 9203 9204 dut->ap_oper_chn = 0; 9205 9206 dut->ap_pmksa = 0; 9207 dut->ap_pmksa_caching = 0; 9208 9209 free(dut->rsne_override); 9210 dut->rsne_override = NULL; 9211 free(dut->rsnxe_override_eapol); 9212 dut->rsnxe_override_eapol = NULL; 9213 9214 free(dut->sae_commit_override); 9215 dut->sae_commit_override = NULL; 9216 9217 free(dut->ap_sae_groups); 9218 dut->ap_sae_groups = NULL; 9219 9220 dut->sae_anti_clogging_threshold = -1; 9221 dut->sae_reflection = 0; 9222 dut->sae_confirm_immediate = 0; 9223 dut->sae_pwe = SAE_PWE_DEFAULT; 9224 9225 dut->ap_cipher = AP_CCMP; 9226 dut->ap_group_cipher = AP_NO_GROUP_CIPHER_SET; 9227 dut->ap_group_mgmt_cipher = AP_NO_GROUP_MGMT_CIPHER_SET; 9228 dut->ap_passphrase[0] = '\0'; 9229 dut->ap_psk[0] = '\0'; 9230 dut->ap_beacon_prot = 0; 9231 dut->ap_transition_disable = 0; 9232 9233 dut->dpp_conf_id = -1; 9234 free(dut->ap_dpp_conf_addr); 9235 dut->ap_dpp_conf_addr = NULL; 9236 free(dut->ap_dpp_conf_pkhash); 9237 dut->ap_dpp_conf_pkhash = NULL; 9238 dut->ap_start_disabled = 0; 9239 9240 if (is_60g_sigma_dut(dut)) { 9241 dut->ap_mode = AP_11ad; 9242 dut->ap_channel = 2; 9243 dut->wps_disable = 0; /* WPS is enabled */ 9244 dut->ap_pmf = 0; 9245 dut->ap_num_ese_allocs = 0; 9246 dut->ap_fixed_rate = 0; 9247 9248 dut->dev_role = DEVROLE_AP; 9249 9250 sigma_dut_print(dut, DUT_MSG_DEBUG, 9251 "Setting msdu_size to MAX: 7912"); 9252 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912", 9253 get_main_ifname(dut)); 9254 9255 if (system(buf) != 0) { 9256 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s", 9257 buf); 9258 return ERROR_SEND_STATUS; 9259 } 9260 9261 if (ap_set_force_mcs(dut, 0, 1)) { 9262 sigma_dut_print(dut, DUT_MSG_ERROR, 9263 "Failed to reset force MCS"); 9264 return ERROR_SEND_STATUS; 9265 } 9266 9267 if (set_ps(get_main_ifname(dut), dut, 1)) { 9268 sigma_dut_print(dut, DUT_MSG_ERROR, 9269 "Failed to enable power save"); 9270 return ERROR_SEND_STATUS; 9271 } 9272 } 9273 9274 if (dut->program == PROGRAM_WPS && 9275 get_driver_type(dut) == DRIVER_WIL6210) { 9276 /* 9277 * In 60 GHz WPS tests, we configure the AP OOB to 9278 * secure connection with a random passphrase. 9279 */ 9280 char r[16], passphrase[65]; 9281 9282 if (random_get_bytes(r, sizeof(r))) { 9283 sigma_dut_print(dut, DUT_MSG_ERROR, 9284 "Failed to get random bytes"); 9285 return ERROR_SEND_STATUS; 9286 } 9287 if (base64_encode(r, sizeof(r), 9288 passphrase, sizeof(passphrase))) { 9289 sigma_dut_print(dut, DUT_MSG_ERROR, 9290 "Failed to generate random passphrase"); 9291 return ERROR_SEND_STATUS; 9292 } 9293 9294 dut->ap_key_mgmt = AP_WPA2_PSK; 9295 dut->ap_cipher = AP_GCMP_128; 9296 strlcpy(dut->ap_passphrase, passphrase, 9297 sizeof(dut->ap_passphrase)); 9298 sigma_dut_print(dut, DUT_MSG_DEBUG, 9299 "60G WPS: configure secure AP with random passphrase"); 9300 } 9301 9302 dut->hostapd_running = 0; 9303 9304 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 9305 return 1; 9306 9307 if (dut->use_hostapd_pid_file) { 9308 kill_hostapd_process_pid(dut); 9309 } else if (kill_process(dut, "(hostapd)", 1, SIGTERM) == 0 || 9310 system("killall hostapd") == 0) { 9311 int i; 9312 /* Wait some time to allow hostapd to complete cleanup before 9313 * starting a new process */ 9314 for (i = 0; i < 10; i++) { 9315 usleep(500000); 9316 if (system("pidof hostapd") != 0) 9317 break; 9318 } 9319 } 9320 9321 if (if_nametoindex("sigmadut") > 0 && 9322 system("iw dev sigmadut del") != 0) 9323 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to remove " 9324 "monitor interface"); 9325 9326 return 1; 9327 } 9328 9329 9330 int sta_cfon_reset_default(struct sigma_dut *dut, struct sigma_conn *conn, 9331 struct sigma_cmd *cmd) 9332 { 9333 return cmd_ap_reset_default(dut, conn, cmd); 9334 } 9335 9336 9337 static enum sigma_cmd_result cmd_ap_get_info(struct sigma_dut *dut, 9338 struct sigma_conn *conn, 9339 struct sigma_cmd *cmd) 9340 { 9341 /* const char *name = get_param(cmd, "NAME"); */ 9342 struct stat s; 9343 char resp[200]; 9344 FILE *f; 9345 enum driver_type drv = get_driver_type(dut); 9346 int res; 9347 9348 switch (drv) { 9349 case DRIVER_ATHEROS: { 9350 /* Atheros AP */ 9351 struct utsname uts; 9352 char *version, athver[100]; 9353 9354 if (stat("/proc/athversion", &s) != 0) { 9355 if (system("/etc/rc.d/rc.wlan up") != 0) { 9356 } 9357 } 9358 9359 athver[0] = '\0'; 9360 f = fopen("/proc/athversion", "r"); 9361 if (f) { 9362 if (fgets(athver, sizeof(athver), f)) { 9363 char *pos = strchr(athver, '\n'); 9364 if (pos) 9365 *pos = '\0'; 9366 } 9367 fclose(f); 9368 } 9369 9370 if (uname(&uts) == 0) 9371 version = uts.release; 9372 else 9373 version = "Unknown"; 9374 9375 if (if_nametoindex("ath1") > 0) 9376 res = snprintf(resp, sizeof(resp), 9377 "interface,ath0_24G ath1_5G,agent,1.0,version,%s/drv:%s", 9378 version, athver); 9379 else 9380 res = snprintf(resp, sizeof(resp), 9381 "interface,ath0_24G,agent,1.0,version,%s/drv:%s", 9382 version, athver); 9383 if (res < 0 || res >= sizeof(resp)) 9384 send_resp(dut, conn, SIGMA_ERROR, NULL); 9385 else 9386 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9387 return 0; 9388 } 9389 case DRIVER_LINUX_WCN: 9390 case DRIVER_MAC80211: { 9391 struct utsname uts; 9392 char *version; 9393 9394 if (uname(&uts) == 0) 9395 version = uts.release; 9396 else 9397 version = "Unknown"; 9398 9399 if (if_nametoindex("wlan1") > 0) 9400 snprintf(resp, sizeof(resp), "interface,wlan0_24G " 9401 "wlan1_5G,agent,1.0,version,%s", version); 9402 else 9403 snprintf(resp, sizeof(resp), "interface,wlan0_any," 9404 "agent,1.0,version,%s", version); 9405 9406 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9407 return 0; 9408 } 9409 case DRIVER_QNXNTO: { 9410 struct utsname uts; 9411 char *version; 9412 9413 if (uname(&uts) == 0) 9414 version = uts.release; 9415 else 9416 version = "Unknown"; 9417 snprintf(resp, sizeof(resp), 9418 "interface,%s_any,agent,1.0,version,%s", 9419 dut->main_ifname ? get_main_ifname(dut) : "NA", 9420 version); 9421 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9422 return 0; 9423 } 9424 case DRIVER_OPENWRT: { 9425 switch (get_openwrt_driver_type()) { 9426 case OPENWRT_DRIVER_ATHEROS: { 9427 struct utsname uts; 9428 char *version; 9429 9430 if (uname(&uts) == 0) 9431 version = uts.release; 9432 else 9433 version = "Unknown"; 9434 9435 if (if_nametoindex("ath1") > 0) 9436 snprintf(resp, sizeof(resp), 9437 "interface,ath0_5G ath1_24G,agent,1.0,version,%s", 9438 version); 9439 else 9440 snprintf(resp, sizeof(resp), 9441 "interface,ath0_any,agent,1.0,version,%s", 9442 version); 9443 9444 send_resp(dut, conn, SIGMA_COMPLETE, resp); 9445 return 0; 9446 } 9447 default: 9448 send_resp(dut, conn, SIGMA_ERROR, 9449 "errorCode,Unsupported openwrt driver"); 9450 return 0; 9451 } 9452 } 9453 default: 9454 send_resp(dut, conn, SIGMA_ERROR, 9455 "errorCode,Unsupported driver"); 9456 return 0; 9457 } 9458 } 9459 9460 9461 static enum sigma_cmd_result cmd_ap_deauth_sta(struct sigma_dut *dut, 9462 struct sigma_conn *conn, 9463 struct sigma_cmd *cmd) 9464 { 9465 /* const char *name = get_param(cmd, "NAME"); */ 9466 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 9467 const char *val, *disconnect; 9468 char buf[100]; 9469 9470 val = get_param(cmd, "MinorCode"); 9471 if (val) { 9472 /* TODO: add support for P2P minor code */ 9473 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MinorCode not " 9474 "yet supported"); 9475 return 0; 9476 } 9477 9478 val = get_param(cmd, "STA_MAC_ADDRESS"); 9479 if (val == NULL) 9480 return -1; 9481 disconnect = get_param(cmd, "disconnect"); 9482 if (disconnect && strcasecmp(disconnect, "silent") == 0) 9483 snprintf(buf, sizeof(buf), "deauth %s tx=0", val); 9484 else 9485 snprintf(buf, sizeof(buf), "deauth %s", val); 9486 if (run_hostapd_cli(dut, buf) != 0) 9487 return -2; 9488 9489 return 1; 9490 } 9491 9492 9493 #ifdef __linux__ 9494 int inject_frame(int s, const void *data, size_t len, int encrypt); 9495 int open_monitor(const char *ifname); 9496 #endif /* __linux__ */ 9497 9498 enum send_frame_type { 9499 DISASSOC, DEAUTH, SAQUERY 9500 }; 9501 enum send_frame_protection { 9502 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED 9503 }; 9504 9505 9506 static int ap_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn, 9507 enum send_frame_type frame, 9508 enum send_frame_protection protected, 9509 const char *sta_addr) 9510 { 9511 #ifdef __linux__ 9512 unsigned char buf[1000], *pos; 9513 int s, res; 9514 unsigned char addr_sta[6], addr_own[6]; 9515 char *ifname; 9516 char cbuf[100]; 9517 struct ifreq ifr; 9518 9519 if ((dut->ap_mode == AP_11a || dut->ap_mode == AP_11na || 9520 dut->ap_mode == AP_11ac) && 9521 if_nametoindex("wlan1") > 0) 9522 ifname = "wlan1"; 9523 else 9524 ifname = "wlan0"; 9525 9526 if (hwaddr_aton(sta_addr, addr_sta) < 0) 9527 return -1; 9528 9529 s = socket(AF_INET, SOCK_DGRAM, 0); 9530 if (s < 0) 9531 return -1; 9532 memset(&ifr, 0, sizeof(ifr)); 9533 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 9534 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 9535 perror("ioctl"); 9536 close(s); 9537 return -1; 9538 } 9539 close(s); 9540 memcpy(addr_own, ifr.ifr_hwaddr.sa_data, 6); 9541 9542 if (if_nametoindex("sigmadut") == 0) { 9543 snprintf(cbuf, sizeof(cbuf), 9544 "iw dev %s interface add sigmadut type monitor", 9545 ifname); 9546 if (system(cbuf) != 0 || 9547 if_nametoindex("sigmadut") == 0) { 9548 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add " 9549 "monitor interface with '%s'", cbuf); 9550 return -2; 9551 } 9552 } 9553 9554 if (system("ifconfig sigmadut up") != 0) { 9555 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set " 9556 "monitor interface up"); 9557 return -2; 9558 } 9559 9560 pos = buf; 9561 9562 /* Frame Control */ 9563 switch (frame) { 9564 case DISASSOC: 9565 *pos++ = 0xa0; 9566 break; 9567 case DEAUTH: 9568 *pos++ = 0xc0; 9569 break; 9570 case SAQUERY: 9571 *pos++ = 0xd0; 9572 break; 9573 } 9574 9575 if (protected == INCORRECT_KEY) 9576 *pos++ = 0x40; /* Set Protected field to 1 */ 9577 else 9578 *pos++ = 0x00; 9579 9580 /* Duration */ 9581 *pos++ = 0x00; 9582 *pos++ = 0x00; 9583 9584 /* addr1 = DA (station) */ 9585 memcpy(pos, addr_sta, 6); 9586 pos += 6; 9587 /* addr2 = SA (own address) */ 9588 memcpy(pos, addr_own, 6); 9589 pos += 6; 9590 /* addr3 = BSSID (own address) */ 9591 memcpy(pos, addr_own, 6); 9592 pos += 6; 9593 9594 /* Seq# (to be filled by driver/mac80211) */ 9595 *pos++ = 0x00; 9596 *pos++ = 0x00; 9597 9598 if (protected == INCORRECT_KEY) { 9599 /* CCMP parameters */ 9600 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8); 9601 pos += 8; 9602 } 9603 9604 if (protected == INCORRECT_KEY) { 9605 switch (frame) { 9606 case DEAUTH: 9607 /* Reason code (encrypted) */ 9608 memcpy(pos, "\xa7\x39", 2); 9609 pos += 2; 9610 break; 9611 case DISASSOC: 9612 /* Reason code (encrypted) */ 9613 memcpy(pos, "\xa7\x39", 2); 9614 pos += 2; 9615 break; 9616 case SAQUERY: 9617 /* Category|Action|TransID (encrypted) */ 9618 memcpy(pos, "\x6f\xbd\xe9\x4d", 4); 9619 pos += 4; 9620 break; 9621 default: 9622 return -1; 9623 } 9624 9625 /* CCMP MIC */ 9626 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8); 9627 pos += 8; 9628 } else { 9629 switch (frame) { 9630 case DEAUTH: 9631 /* reason code = 8 */ 9632 *pos++ = 0x08; 9633 *pos++ = 0x00; 9634 break; 9635 case DISASSOC: 9636 /* reason code = 8 */ 9637 *pos++ = 0x08; 9638 *pos++ = 0x00; 9639 break; 9640 case SAQUERY: 9641 /* Category - SA Query */ 9642 *pos++ = 0x08; 9643 /* SA query Action - Request */ 9644 *pos++ = 0x00; 9645 /* Transaction ID */ 9646 *pos++ = 0x12; 9647 *pos++ = 0x34; 9648 break; 9649 } 9650 } 9651 9652 s = open_monitor("sigmadut"); 9653 if (s < 0) { 9654 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open " 9655 "monitor socket"); 9656 return 0; 9657 } 9658 9659 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY); 9660 if (res < 0) { 9661 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to " 9662 "inject frame"); 9663 close(s); 9664 return 0; 9665 } 9666 if (res < pos - buf) { 9667 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial " 9668 "frame sent"); 9669 close(s); 9670 return 0; 9671 } 9672 9673 close(s); 9674 9675 return 1; 9676 #else /* __linux__ */ 9677 send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_send_frame not " 9678 "yet supported"); 9679 return 0; 9680 #endif /* __linux__ */ 9681 } 9682 9683 9684 int ap_send_frame_hs2(struct sigma_dut *dut, struct sigma_conn *conn, 9685 struct sigma_cmd *cmd) 9686 { 9687 const char *val, *dest; 9688 char buf[100]; 9689 9690 val = get_param(cmd, "FrameName"); 9691 if (val == NULL) 9692 return -1; 9693 9694 if (strcasecmp(val, "QoSMapConfigure") == 0) { 9695 dest = get_param(cmd, "Dest"); 9696 if (!dest) 9697 return -1; 9698 9699 val = get_param(cmd, "QoS_MAP_SET"); 9700 if (val) { 9701 dut->ap_qos_map_set = atoi(val); 9702 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d", 9703 dut->ap_qos_map_set); 9704 } 9705 9706 if (dut->ap_qos_map_set == 1) 9707 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1); 9708 else if (dut->ap_qos_map_set == 2) 9709 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2); 9710 9711 snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest); 9712 if (run_hostapd_cli(dut, buf) != 0) 9713 return -1; 9714 } 9715 9716 return 1; 9717 } 9718 9719 9720 static int ath_ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn, 9721 struct sigma_cmd *cmd) 9722 { 9723 const char *val; 9724 const char *ifname; 9725 int chwidth, nss; 9726 9727 val = get_param(cmd, "FrameName"); 9728 if (!val || strcasecmp(val, "op_md_notif_frm") != 0) { 9729 send_resp(dut, conn, SIGMA_ERROR, 9730 "errorCode,Unsupported FrameName"); 9731 return 0; 9732 } 9733 9734 /* 9735 * Sequence of commands for Opmode notification on 9736 * Peregrine based products 9737 */ 9738 ifname = get_main_ifname(dut); 9739 9740 /* Disable STBC */ 9741 run_iwpriv(dut, ifname, "tx_stbc 0"); 9742 9743 /* Check whether optional arg channel width was passed */ 9744 val = get_param(cmd, "Channel_width"); 9745 if (val) { 9746 switch (atoi(val)) { 9747 case 20: 9748 chwidth = 0; 9749 break; 9750 case 40: 9751 chwidth = 1; 9752 break; 9753 case 80: 9754 chwidth = 2; 9755 break; 9756 case 160: 9757 chwidth = 3; 9758 break; 9759 default: 9760 chwidth = 2; 9761 break; 9762 } 9763 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 9764 } 9765 9766 /* Check whether optional arg NSS was passed */ 9767 val = get_param(cmd, "NSS"); 9768 if (val) { 9769 /* Convert nss to chainmask */ 9770 switch (atoi(val)) { 9771 case 1: 9772 nss = 1; 9773 break; 9774 case 2: 9775 nss = 3; 9776 break; 9777 case 3: 9778 nss = 7; 9779 break; 9780 default: 9781 /* We do not support NSS > 3 */ 9782 nss = 3; 9783 break; 9784 } 9785 run_iwpriv(dut, ifname, "rxchainmask %d", nss); 9786 } 9787 9788 /* Send the opmode notification */ 9789 run_iwpriv(dut, ifname, "opmode_notify 1"); 9790 9791 return 1; 9792 } 9793 9794 9795 static int ath_ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn, 9796 struct sigma_cmd *cmd) 9797 { 9798 const char *val; 9799 FILE *f; 9800 int rand_int = 0; 9801 9802 val = get_param(cmd, "MsntType"); 9803 if (val) { 9804 if (dut->ap_msnt_type == 0) 9805 dut->ap_msnt_type = atoi(val); 9806 9807 if (dut->ap_msnt_type != 5 && dut->ap_msnt_type != 2) { 9808 dut->ap_msnt_type = atoi(val); 9809 if (dut->ap_msnt_type == 1) { 9810 val = get_param(cmd, "RandInterval"); 9811 if (val) 9812 rand_int = atoi(val); 9813 f = fopen("/tmp/ftmrr.txt", "a"); 9814 if (!f) { 9815 sigma_dut_print(dut, DUT_MSG_ERROR, 9816 "Failed to open /tmp/ftmrr.txt"); 9817 return -1; 9818 } 9819 9820 fprintf(f, "sta_mac = %s\n", cmd->values[3]); 9821 fprintf(f, "meas_type = 0x10\nrand_inter = 0x%x\nmin_ap_count = 0x%s\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0xf\nmeas_req_mode = 0x00\n", 9822 rand_int, cmd->values[7]); 9823 fclose(f); 9824 dut->ap_msnt_type = 5; 9825 run_system(dut, "wpc -f /tmp/ftmrr.txt"); 9826 } 9827 } else if (dut->ap_msnt_type == 5) { 9828 run_system(dut, "wpc -f /tmp/ftmrr.txt"); 9829 } else if (dut->ap_msnt_type == 2) { 9830 f = fopen("/tmp/wru.txt", "w"); 9831 if (!f) { 9832 sigma_dut_print(dut, DUT_MSG_ERROR, 9833 "Failed to open /tmp/wru.txt"); 9834 return -1; 9835 } 9836 9837 fprintf(f, "sta_mac = %s\n", cmd->values[3]); 9838 fprintf(f, "meas_type = 0x08\ndialogtoken = 0x1\nnum_repetitions = 0x0\nmeas_token = 0x1\nmeas_req_mode = 0x00\nloc_subject = 0x01\n"); 9839 fclose(f); 9840 run_system(dut, "wpc -w /tmp/wru.txt"); 9841 } 9842 } 9843 return 1; 9844 } 9845 9846 9847 /* 9848 * The following functions parse_send_frame_params_int(), 9849 * parse_send_frame_params_str(), and parse_send_frame_params_mac() 9850 * are used by ath_ap_send_frame_bcn_rpt_req(). 9851 * Beacon Report Request is a frame used as part of the MBO program. 9852 * The command for sending beacon report has a lot of 9853 * arguments and having these functions reduces code size. 9854 * 9855 */ 9856 static int parse_send_frame_params_int(char *param, struct sigma_cmd *cmd, 9857 struct sigma_dut *dut, 9858 char *buf, size_t buf_size) 9859 { 9860 const char *str_val; 9861 int int_val; 9862 char temp[100]; 9863 9864 str_val = get_param(cmd, param); 9865 if (!str_val) { 9866 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param); 9867 return -1; 9868 } 9869 int_val = atoi(str_val); 9870 snprintf(temp, sizeof(temp), " %d", int_val); 9871 strlcat(buf, temp, buf_size); 9872 return 0; 9873 } 9874 9875 9876 static int parse_send_frame_params_str(char *param, struct sigma_cmd *cmd, 9877 struct sigma_dut *dut, 9878 char *buf, size_t buf_size) 9879 { 9880 const char *str_val; 9881 char temp[100]; 9882 9883 str_val = get_param(cmd, param); 9884 if (!str_val) { 9885 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param); 9886 return -1; 9887 } 9888 snprintf(temp, sizeof(temp), " %s", str_val); 9889 temp[sizeof(temp) - 1] = '\0'; 9890 strlcat(buf, temp, buf_size); 9891 return 0; 9892 } 9893 9894 9895 static int parse_send_frame_params_mac(char *param, struct sigma_cmd *cmd, 9896 struct sigma_dut *dut, 9897 char *buf, size_t buf_size) 9898 { 9899 const char *str_val; 9900 unsigned char mac[6]; 9901 char temp[100]; 9902 9903 str_val = get_param(cmd, param); 9904 if (!str_val) { 9905 sigma_dut_print(dut, DUT_MSG_ERROR, "%s not given", param); 9906 return -1; 9907 } 9908 9909 if (parse_mac_address(dut, str_val, mac) < 0) { 9910 sigma_dut_print(dut, DUT_MSG_ERROR, 9911 "MAC Address not in proper format"); 9912 return -1; 9913 } 9914 snprintf(temp, sizeof(temp), " %02x:%02x:%02x:%02x:%02x:%02x", 9915 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 9916 strlcat(buf, temp, buf_size); 9917 return 0; 9918 } 9919 9920 9921 static void fill_1_or_0_based_on_presence(struct sigma_cmd *cmd, char *param, 9922 char *buf, size_t buf_size) 9923 { 9924 const char *str_val; 9925 char *value = " 1"; 9926 9927 str_val = get_param(cmd, param); 9928 if (!str_val || str_val[0] == '\0') 9929 value = " 0"; 9930 strlcat(buf, value, buf_size); 9931 9932 } 9933 9934 9935 /* 9936 * wifitool athN sendbcnrpt 9937 * <STA MAC - Plugs in from Dest_MAC> 9938 * <regclass - Plugs in from RegClass - int> 9939 * <channum - Plugs in from Channel PARAM of dev_send_frame - int> 9940 * <rand_ivl - Plugs in from RandInt - string> 9941 * <duration - Plugs in from MeaDur - integer> 9942 * <mode - Plugs in from MeaMode - string> 9943 * <req_ssid - Plugs in from SSID PARAM of dev_send_frame - string> 9944 * <rep_cond - Plugs in from RptCond - integer> 9945 * <rpt_detail - Plugs in from RptDet - integer> 9946 * <req_ie - Plugs in from ReqInfo PARAM of dev_send_frame - string> 9947 * <chanrpt_mode - Plugs in from APChanRpt - integer> 9948 * <specific_bssid - Plugs in from BSSID PARAM of dev_send_frame> 9949 * [AP channel numbers] 9950 */ 9951 static int ath_ap_send_frame_bcn_rpt_req(struct sigma_dut *dut, 9952 struct sigma_cmd *cmd, 9953 const char *ifname) 9954 { 9955 char buf[100]; 9956 int rpt_det; 9957 const char *str_val; 9958 const char *mea_mode; 9959 9960 snprintf(buf, sizeof(buf), "wifitool %s sendbcnrpt", ifname); 9961 9962 if (parse_send_frame_params_mac("Dest_MAC", cmd, dut, buf, sizeof(buf))) 9963 return -1; 9964 if (parse_send_frame_params_int("RegClass", cmd, dut, buf, sizeof(buf))) 9965 return -1; 9966 if (parse_send_frame_params_int("Channel", cmd, dut, buf, sizeof(buf))) 9967 return -1; 9968 if (parse_send_frame_params_str("RandInt", cmd, dut, buf, sizeof(buf))) 9969 return -1; 9970 if (parse_send_frame_params_int("MeaDur", cmd, dut, buf, sizeof(buf))) 9971 return -1; 9972 9973 str_val = get_param(cmd, "MeaMode"); 9974 if (!str_val) { 9975 sigma_dut_print(dut, DUT_MSG_ERROR, 9976 "MeaMode parameter not present in send bcn-rpt-req"); 9977 return -1; 9978 } 9979 if (strcasecmp(str_val, "passive") == 0) { 9980 mea_mode = " 0"; 9981 } else if (strcasecmp(str_val, "active") == 0) { 9982 mea_mode = " 1"; 9983 } else if (strcasecmp(str_val, "table") == 0) { 9984 mea_mode = " 2"; 9985 } else { 9986 sigma_dut_print(dut, DUT_MSG_ERROR, 9987 "MEA-MODE Value not correctly given"); 9988 return -1; 9989 } 9990 strlcat(buf, mea_mode, sizeof(buf)); 9991 9992 fill_1_or_0_based_on_presence(cmd, "SSID", buf, sizeof(buf)); 9993 9994 if (parse_send_frame_params_int("RptCond", cmd, dut, buf, sizeof(buf))) 9995 return -1; 9996 9997 if (parse_send_frame_params_int("RptDet", cmd, dut, buf, sizeof(buf))) 9998 return -1; 9999 str_val = get_param(cmd, "RptDet"); 10000 rpt_det = str_val ? atoi(str_val) : 0; 10001 10002 if (rpt_det) 10003 fill_1_or_0_based_on_presence(cmd, "ReqInfo", buf, sizeof(buf)); 10004 else 10005 strlcat(buf, " 0", sizeof(buf)); 10006 10007 if (rpt_det) 10008 fill_1_or_0_based_on_presence(cmd, "APChanRpt", buf, 10009 sizeof(buf)); 10010 else 10011 strlcat(buf, " 0", sizeof(buf)); 10012 10013 if (parse_send_frame_params_mac("BSSID", cmd, dut, buf, sizeof(buf))) 10014 return -1; 10015 10016 str_val = get_param(cmd, "APChanRpt"); 10017 if (str_val) { 10018 const char *pos; 10019 int ap_chanrpt; 10020 int ap_chanrpt_2 = 0; 10021 char chanrpt[100]; 10022 10023 ap_chanrpt = atoi(str_val); 10024 pos = strchr(str_val, '_'); 10025 if (pos) { 10026 pos++; 10027 ap_chanrpt_2 = atoi(pos); 10028 } 10029 if (ap_chanrpt) { 10030 snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt); 10031 strlcat(buf, chanrpt, sizeof(buf)); 10032 } 10033 if (ap_chanrpt_2) { 10034 snprintf(chanrpt, sizeof(chanrpt), " %d", ap_chanrpt_2); 10035 strlcat(buf, chanrpt, sizeof(buf)); 10036 } 10037 } 10038 10039 run_system(dut, buf); 10040 return 0; 10041 } 10042 10043 10044 static void inform_and_sleep(struct sigma_dut *dut, int seconds) 10045 { 10046 sigma_dut_print(dut, DUT_MSG_DEBUG, "sleeping for %d seconds", seconds); 10047 sleep(seconds); 10048 sigma_dut_print(dut, DUT_MSG_DEBUG, "woke up after %d seconds", 10049 seconds); 10050 } 10051 10052 10053 static int ath_ap_send_frame_btm_req(struct sigma_dut *dut, 10054 struct sigma_cmd *cmd, const char *ifname) 10055 { 10056 unsigned char mac_addr[ETH_ALEN]; 10057 int disassoc_timer; 10058 char buf[100]; 10059 const char *val; 10060 int cand_list = 1; 10061 10062 val = get_param(cmd, "Dest_MAC"); 10063 if (!val || parse_mac_address(dut, val, mac_addr) < 0) { 10064 sigma_dut_print(dut, DUT_MSG_ERROR, 10065 "MAC Address not in proper format"); 10066 return -1; 10067 } 10068 10069 val = get_param(cmd, "Disassoc_Timer"); 10070 if (val) 10071 disassoc_timer = atoi(val); 10072 else 10073 disassoc_timer = dut->ap_disassoc_timer; 10074 if (disassoc_timer < 0) { 10075 sigma_dut_print(dut, DUT_MSG_ERROR, 10076 "Invalid Disassoc_Timer value %d", 10077 disassoc_timer); 10078 return -1; 10079 } 10080 10081 val = get_param(cmd, "Cand_List"); 10082 if (val && val[0]) 10083 cand_list = atoi(val); 10084 10085 val = get_param(cmd, "BTMQuery_Reason_Code"); 10086 if (val) 10087 run_iwpriv(dut, ifname, "mbo_trans_rs %s", val); 10088 10089 if (dut->ap_btmreq_disassoc_imnt && !dut->ap_assoc_delay) 10090 run_iwpriv(dut, ifname, "mbo_asoc_ret 1"); 10091 10092 snprintf(buf, sizeof(buf), 10093 "wifitool %s sendbstmreq %02x:%02x:%02x:%02x:%02x:%02x %d %d 15 %d %d %d %d", 10094 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], 10095 mac_addr[4], mac_addr[5], cand_list, disassoc_timer, 10096 dut->ap_btmreq_disassoc_imnt, 10097 dut->ap_btmreq_term_bit, 10098 dut->ap_btmreq_bss_term_tsf, 10099 dut->ap_btmreq_bss_term_dur); 10100 run_system(dut, buf); 10101 10102 if (dut->ap_btmreq_term_bit) { 10103 if (dut->ap_btmreq_bss_term_tsf >= 2) 10104 inform_and_sleep(dut, dut->ap_btmreq_bss_term_tsf - 2); 10105 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x", 10106 mac_addr[0], mac_addr[1], mac_addr[2], 10107 mac_addr[3], mac_addr[4], mac_addr[5]); 10108 inform_and_sleep(dut, 2); 10109 run_system_wrapper(dut, "ifconfig %s down", ifname); 10110 inform_and_sleep(dut, 5); 10111 run_system_wrapper(dut, "ifconfig %s up", ifname); 10112 } else if (dut->ap_btmreq_disassoc_imnt) { 10113 inform_and_sleep(dut, (disassoc_timer / 1000) + 1); 10114 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x", 10115 mac_addr[0], mac_addr[1], mac_addr[2], 10116 mac_addr[3], mac_addr[4], mac_addr[5]); 10117 } 10118 return 0; 10119 } 10120 10121 10122 static int ath_ap_send_frame_disassoc(struct sigma_dut *dut, 10123 struct sigma_cmd *cmd, const char *ifname) 10124 { 10125 unsigned char mac_addr[ETH_ALEN]; 10126 const char *val; 10127 10128 val = get_param(cmd, "Dest_MAC"); 10129 if (!val || parse_mac_address(dut, val, mac_addr) < 0) { 10130 sigma_dut_print(dut, DUT_MSG_ERROR, 10131 "MAC Address not in proper format"); 10132 return -1; 10133 } 10134 10135 run_iwpriv(dut, ifname, "kickmac %02x:%02x:%02x:%02x:%02x:%02x", 10136 mac_addr[0], mac_addr[1], mac_addr[2], 10137 mac_addr[3], mac_addr[4], mac_addr[5]); 10138 return 0; 10139 } 10140 10141 10142 static int ath_ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn, 10143 struct sigma_cmd *cmd) 10144 { 10145 const char *val; 10146 const char *ifname; 10147 10148 ifname = get_main_ifname(dut); 10149 10150 val = get_param(cmd, "FrameName"); 10151 if (!val) 10152 return -1; 10153 10154 if (strcasecmp(val, "BTMReq") == 0) 10155 ath_ap_send_frame_btm_req(dut, cmd, ifname); 10156 else if (strcasecmp(val, "BcnRptReq") == 0) 10157 ath_ap_send_frame_bcn_rpt_req(dut, cmd, ifname); 10158 else if (strcasecmp(val, "disassoc") == 0) 10159 ath_ap_send_frame_disassoc(dut, cmd, ifname); 10160 else 10161 return -1; 10162 10163 return 1; 10164 } 10165 10166 10167 static int ap_send_frame_vht(struct sigma_dut *dut, struct sigma_conn *conn, 10168 struct sigma_cmd *cmd) 10169 { 10170 switch (get_driver_type(dut)) { 10171 case DRIVER_ATHEROS: 10172 return ath_ap_send_frame_vht(dut, conn, cmd); 10173 break; 10174 case DRIVER_OPENWRT: 10175 switch (get_openwrt_driver_type()) { 10176 case OPENWRT_DRIVER_ATHEROS: 10177 return ath_ap_send_frame_vht(dut, conn, cmd); 10178 default: 10179 send_resp(dut, conn, SIGMA_ERROR, 10180 "errorCode,Unsupported ap_send_frame with the current openwrt driver"); 10181 return 0; 10182 } 10183 default: 10184 send_resp(dut, conn, SIGMA_ERROR, 10185 "errorCode,Unsupported ap_send_frame with the current driver"); 10186 return 0; 10187 } 10188 } 10189 10190 10191 static int ap_send_frame_loc(struct sigma_dut *dut, struct sigma_conn *conn, 10192 struct sigma_cmd *cmd) 10193 { 10194 switch (get_driver_type(dut)) { 10195 case DRIVER_ATHEROS: 10196 return ath_ap_send_frame_loc(dut, conn, cmd); 10197 case DRIVER_OPENWRT: 10198 switch (get_openwrt_driver_type()) { 10199 case OPENWRT_DRIVER_ATHEROS: 10200 return ath_ap_send_frame_loc(dut, conn, cmd); 10201 default: 10202 send_resp(dut, conn, SIGMA_ERROR, 10203 "errorCode,Unsupported ap_send_frame_loc with the current openwrt driver"); 10204 return 0; 10205 } 10206 default: 10207 send_resp(dut, conn, SIGMA_ERROR, 10208 "errorCode,Unsupported ap_send_frame_loc with the current driver"); 10209 return 0; 10210 } 10211 } 10212 10213 10214 static int ap_send_frame_mbo(struct sigma_dut *dut, struct sigma_conn *conn, 10215 struct sigma_cmd *cmd) 10216 { 10217 switch (get_driver_type(dut)) { 10218 case DRIVER_ATHEROS: 10219 return ath_ap_send_frame_mbo(dut, conn, cmd); 10220 case DRIVER_OPENWRT: 10221 switch (get_openwrt_driver_type()) { 10222 case OPENWRT_DRIVER_ATHEROS: 10223 return ath_ap_send_frame_mbo(dut, conn, cmd); 10224 default: 10225 send_resp(dut, conn, SIGMA_ERROR, 10226 "errorCode,Unsupported ap_send_frame with the current openwrt driver"); 10227 return 0; 10228 } 10229 default: 10230 send_resp(dut, conn, SIGMA_ERROR, 10231 "errorCode,Unsupported ap_send_frame with the current driver"); 10232 return 0; 10233 } 10234 } 10235 10236 10237 static int ap_send_frame_60g(struct sigma_dut *dut, 10238 struct sigma_conn *conn, 10239 struct sigma_cmd *cmd) 10240 { 10241 switch (get_driver_type(dut)) { 10242 #ifdef __linux__ 10243 case DRIVER_WIL6210: 10244 return wil6210_send_frame_60g(dut, conn, cmd); 10245 #endif /* __linux__ */ 10246 default: 10247 send_resp(dut, conn, SIGMA_ERROR, 10248 "errorCode,Unsupported sta_set_frame(60G) with the current driver"); 10249 return 0; 10250 } 10251 } 10252 10253 10254 enum sigma_cmd_result cmd_ap_send_frame(struct sigma_dut *dut, 10255 struct sigma_conn *conn, 10256 struct sigma_cmd *cmd) 10257 { 10258 /* const char *name = get_param(cmd, "NAME"); */ 10259 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 10260 const char *val; 10261 enum send_frame_type frame; 10262 enum send_frame_protection protected; 10263 char buf[100]; 10264 10265 val = get_param(cmd, "Program"); 10266 if (val) { 10267 if (strcasecmp(val, "HS2") == 0 || 10268 strcasecmp(val, "HS2-R2") == 0 || 10269 strcasecmp(val, "IOTLP") == 0) 10270 return ap_send_frame_hs2(dut, conn, cmd); 10271 if (strcasecmp(val, "VHT") == 0) 10272 return ap_send_frame_vht(dut, conn, cmd); 10273 if (strcasecmp(val, "LOC") == 0) 10274 return ap_send_frame_loc(dut, conn, cmd); 10275 if (strcasecmp(val, "MBO") == 0) 10276 return ap_send_frame_mbo(dut, conn, cmd); 10277 if (strcasecmp(val, "60GHz") == 0) 10278 return ap_send_frame_60g(dut, conn, cmd); 10279 } 10280 10281 val = get_param(cmd, "PMFFrameType"); 10282 if (val == NULL) 10283 val = get_param(cmd, "FrameName"); 10284 if (val == NULL) 10285 val = get_param(cmd, "Type"); 10286 if (val == NULL) 10287 return -1; 10288 if (strcasecmp(val, "disassoc") == 0) 10289 frame = DISASSOC; 10290 else if (strcasecmp(val, "deauth") == 0) 10291 frame = DEAUTH; 10292 else if (strcasecmp(val, "saquery") == 0) 10293 frame = SAQUERY; 10294 else { 10295 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported " 10296 "PMFFrameType"); 10297 return 0; 10298 } 10299 10300 val = get_param(cmd, "PMFProtected"); 10301 if (val == NULL) 10302 val = get_param(cmd, "Protected"); 10303 if (val == NULL) 10304 return -1; 10305 if (strcasecmp(val, "Correct-key") == 0 || 10306 strcasecmp(val, "CorrectKey") == 0) 10307 protected = CORRECT_KEY; 10308 else if (strcasecmp(val, "IncorrectKey") == 0) 10309 protected = INCORRECT_KEY; 10310 else if (strcasecmp(val, "Unprotected") == 0) 10311 protected = UNPROTECTED; 10312 else { 10313 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported " 10314 "PMFProtected"); 10315 return 0; 10316 } 10317 10318 val = get_param(cmd, "stationID"); 10319 if (val == NULL) 10320 return -1; 10321 10322 if (protected == INCORRECT_KEY || 10323 (protected == UNPROTECTED && frame == SAQUERY)) 10324 return ap_inject_frame(dut, conn, frame, protected, val); 10325 10326 switch (frame) { 10327 case DISASSOC: 10328 snprintf(buf, sizeof(buf), "disassoc %s test=%d", 10329 val, protected == CORRECT_KEY); 10330 break; 10331 case DEAUTH: 10332 snprintf(buf, sizeof(buf), "deauth %s test=%d", 10333 val, protected == CORRECT_KEY); 10334 break; 10335 case SAQUERY: 10336 snprintf(buf, sizeof(buf), "sa_query %s", val); 10337 break; 10338 } 10339 10340 if (run_hostapd_cli(dut, buf) != 0) 10341 return -2; 10342 10343 return 1; 10344 } 10345 10346 10347 static enum sigma_cmd_result cmd_ap_get_mac_address(struct sigma_dut *dut, 10348 struct sigma_conn *conn, 10349 struct sigma_cmd *cmd) 10350 { 10351 #if defined( __linux__) 10352 /* const char *name = get_param(cmd, "NAME"); */ 10353 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 10354 char resp[100]; 10355 unsigned char addr[6]; 10356 char ifname[50]; 10357 struct ifreq ifr; 10358 int s, wlan_tag = 1; 10359 const char *val; 10360 10361 val = get_param(cmd, "WLAN_TAG"); 10362 if (val) { 10363 wlan_tag = atoi(val); 10364 if (wlan_tag < 1 || wlan_tag > 3) { 10365 /* 10366 * The only valid WLAN Tags as of now as per the latest 10367 * WFA scripts are 1, 2, and 3. 10368 */ 10369 send_resp(dut, conn, SIGMA_ERROR, 10370 "errorCode,Unsupported WLAN_TAG"); 10371 return 0; 10372 } 10373 } 10374 10375 get_if_name(dut, ifname, sizeof(ifname), wlan_tag); 10376 10377 s = socket(AF_INET, SOCK_DGRAM, 0); 10378 if (s < 0) 10379 return -1; 10380 memset(&ifr, 0, sizeof(ifr)); 10381 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 10382 if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { 10383 perror("ioctl"); 10384 close(s); 10385 snprintf(resp, sizeof(resp), 10386 "errorCode,Could not find interface %s", ifname); 10387 send_resp(dut, conn, SIGMA_ERROR, resp); 10388 return 0; 10389 } 10390 close(s); 10391 memcpy(addr, ifr.ifr_hwaddr.sa_data, 6); 10392 10393 snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x", 10394 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 10395 send_resp(dut, conn, SIGMA_COMPLETE, resp); 10396 return 0; 10397 #elif defined( __QNXNTO__) 10398 char resp[50]; 10399 unsigned char addr[6]; 10400 10401 if (!dut->main_ifname) { 10402 send_resp(dut, conn, SIGMA_ERROR, "ifname is null"); 10403 return 0; 10404 } 10405 10406 if (get_hwaddr(get_main_ifname(dut), addr) != 0) { 10407 send_resp(dut, conn, SIGMA_ERROR, 10408 "errorCode,Failed to get address"); 10409 return 0; 10410 } 10411 snprintf(resp, sizeof(resp), "mac,%02x:%02x:%02x:%02x:%02x:%02x", 10412 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); 10413 send_resp(dut, conn, SIGMA_COMPLETE, resp); 10414 return 0; 10415 #else /* __linux__ */ 10416 send_resp(dut, conn, SIGMA_ERROR, "errorCode,ap_get_mac_address not " 10417 "yet supported"); 10418 return 0; 10419 #endif /* __linux__ */ 10420 } 10421 10422 10423 int sta_cfon_get_mac_address(struct sigma_dut *dut, struct sigma_conn *conn, 10424 struct sigma_cmd *cmd) 10425 { 10426 return cmd_ap_get_mac_address(dut, conn, cmd); 10427 } 10428 10429 10430 static enum sigma_cmd_result cmd_ap_set_pmf(struct sigma_dut *dut, 10431 struct sigma_conn *conn, 10432 struct sigma_cmd *cmd) 10433 { 10434 /* 10435 * Ignore the command since the parameters are already handled through 10436 * ap_set_security. 10437 */ 10438 10439 return 1; 10440 } 10441 10442 10443 static enum sigma_cmd_result cmd_ap_set_hs2(struct sigma_dut *dut, 10444 struct sigma_conn *conn, 10445 struct sigma_cmd *cmd) 10446 { 10447 /* const char *name = get_param(cmd, "NAME"); */ 10448 /* const char *ifname = get_param(cmd, "INTERFACE"); */ 10449 const char *val, *dest; 10450 char *pos, buf[100]; 10451 int i, wlan_tag = 1, res; 10452 10453 sigma_dut_print(dut, DUT_MSG_INFO, "ap_set_hs2: Processing the " 10454 "following parameters"); 10455 for (i = 0; i < cmd->count; i++) { 10456 sigma_dut_print(dut, DUT_MSG_INFO, "%s %s", cmd->params[i], 10457 (cmd->values[i] ? cmd->values[i] : "NULL")); 10458 } 10459 10460 val = get_param(cmd, "ICMPv4_ECHO"); 10461 if (val && atoi(val)) { 10462 snprintf(buf, sizeof(buf), "ebtables -F"); 10463 if (system(buf) != 0) { 10464 sigma_dut_print(dut, DUT_MSG_ERROR, 10465 "Failed to set ebtables rules, RULE-12"); 10466 } 10467 return 1; 10468 } 10469 10470 val = get_param(cmd, "WLAN_TAG"); 10471 if (val) { 10472 wlan_tag = atoi(val); 10473 if (wlan_tag != 1 && wlan_tag != 2) { 10474 send_resp(dut, conn, SIGMA_INVALID, 10475 "errorCode,Invalid WLAN_TAG"); 10476 return 0; 10477 } 10478 } 10479 10480 if (wlan_tag == 2) { 10481 val = get_param(cmd, "PROXY_ARP"); 10482 if (val) 10483 dut->ap2_proxy_arp = atoi(val); 10484 10485 val = get_param(cmd, "OSU"); 10486 if (val) 10487 dut->ap2_osu = atoi(val); 10488 return 1; 10489 } 10490 10491 dest = get_param(cmd, "STA_MAC"); 10492 if (dest) { 10493 /* This is a special/ugly way of using this command. 10494 * If "Dest" MAC is included, assume that this command 10495 * is being issued after ap_config_commit for dynamically 10496 * setting the QoS Map Set. 10497 */ 10498 val = get_param(cmd, "QoS_MAP_SET"); 10499 if (val) { 10500 dut->ap_qos_map_set = atoi(val); 10501 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d", 10502 dut->ap_qos_map_set); 10503 } 10504 10505 if (dut->ap_qos_map_set == 1) 10506 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_1); 10507 else if (dut->ap_qos_map_set == 2) 10508 run_hostapd_cli(dut, "set_qos_map_set " QOS_MAP_SET_2); 10509 10510 snprintf(buf, sizeof(buf), "send_qos_map_conf %s", dest); 10511 if (run_hostapd_cli(dut, buf) != 0) 10512 return -1; 10513 } 10514 10515 val = get_param(cmd, "DGAF_DISABLE"); 10516 if (val) 10517 dut->ap_dgaf_disable = atoi(val); 10518 10519 dut->ap_interworking = 1; 10520 10521 val = get_param(cmd, "INTERWORKING"); 10522 if (val == NULL) 10523 val = get_param(cmd, "INTERNETWORKING"); 10524 if (val != NULL && atoi(val) == 0) { 10525 dut->ap_interworking = 0; 10526 dut->ap_hs2 = 0; 10527 return 1; 10528 } 10529 10530 val = get_param(cmd, "ACCS_NET_TYPE"); 10531 if (val) { 10532 if (strcasecmp(val, "Chargeable_Public_Network") == 0 || 10533 strcasecmp(val, "Chargable_Public_Network") == 0 || 10534 strcasecmp(val, "Chargable Public Network") == 0) 10535 dut->ap_access_net_type = 2; 10536 else 10537 dut->ap_access_net_type = atoi(val); 10538 } 10539 10540 val = get_param(cmd, "INTERNET"); 10541 if (val) 10542 dut->ap_internet = atoi(val); 10543 10544 val = get_param(cmd, "VENUE_GRP"); 10545 if (val) { 10546 if (strcasecmp(val, "Business") == 0) 10547 dut->ap_venue_group = 2; 10548 else 10549 dut->ap_venue_group = atoi(val); 10550 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d", 10551 dut->ap_venue_name); 10552 } 10553 10554 val = get_param(cmd, "VENUE_TYPE"); 10555 if (val) { 10556 if (strcasecmp(val, "R&D") == 0) 10557 dut->ap_venue_type = 8; 10558 else 10559 dut->ap_venue_type = atoi(val); 10560 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_type %d", 10561 dut->ap_venue_type); 10562 } 10563 10564 val = get_param(cmd, "HESSID"); 10565 if (val) { 10566 if (strlen(val) >= sizeof(dut->ap_hessid)) { 10567 send_resp(dut, conn, SIGMA_ERROR, 10568 "errorCode,Invalid HESSID"); 10569 return 0; 10570 } 10571 snprintf(dut->ap_hessid, sizeof(dut->ap_hessid), "%s", val); 10572 sigma_dut_print(dut, DUT_MSG_INFO, "ap_hessid %s", 10573 dut->ap_hessid); 10574 } 10575 10576 val = get_param(cmd, "ROAMING_CONS"); 10577 if (val) { 10578 if (strlen(val) >= sizeof(dut->ap_roaming_cons)) { 10579 send_resp(dut, conn, SIGMA_ERROR, 10580 "errorCode,Invalid ROAMING_CONS"); 10581 return 0; 10582 } 10583 if (strcasecmp(val, "Disabled") == 0) { 10584 dut->ap_roaming_cons[0] = '\0'; 10585 } else { 10586 snprintf(dut->ap_roaming_cons, 10587 sizeof(dut->ap_roaming_cons), "%s", val); 10588 } 10589 sigma_dut_print(dut, DUT_MSG_INFO, "ap_roaming_cons %s", 10590 dut->ap_roaming_cons); 10591 } 10592 10593 val = get_param(cmd, "ANQP"); 10594 if (val) 10595 dut->ap_anqpserver_on = atoi(val); 10596 10597 val = get_param(cmd, "NAI_REALM_LIST"); 10598 if (val) { 10599 dut->ap_nai_realm_list = atoi(val); 10600 sigma_dut_print(dut, DUT_MSG_INFO, "ap_nai_realm_list %d", 10601 dut->ap_nai_realm_list); 10602 } 10603 10604 val = get_param(cmd, "3GPP_INFO"); 10605 if (val) { 10606 /* What kind of encoding format is used?! */ 10607 send_resp(dut, conn, SIGMA_ERROR, "errorCode,3GPP_INFO " 10608 "not yet supported (contents not fully defined)"); 10609 return 0; 10610 } 10611 10612 val = get_param(cmd, "DOMAIN_LIST"); 10613 if (val) { 10614 if (strlen(val) >= sizeof(dut->ap_domain_name_list)) { 10615 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Too long " 10616 "DOMAIN_LIST"); 10617 return 0; 10618 } 10619 snprintf(dut->ap_domain_name_list, 10620 sizeof(dut->ap_domain_name_list), "%s", val); 10621 pos = dut->ap_domain_name_list; 10622 while (*pos) { 10623 if (*pos == ';') 10624 *pos = ','; 10625 pos++; 10626 } 10627 sigma_dut_print(dut, DUT_MSG_INFO, "ap_domain_name_list %s", 10628 dut->ap_domain_name_list); 10629 } 10630 10631 val = get_param(cmd, "OPER_NAME"); 10632 if (val) { 10633 dut->ap_oper_name = atoi(val); 10634 sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_name %d", 10635 dut->ap_oper_name); 10636 } 10637 10638 val = get_param(cmd, "VENUE_NAME"); 10639 if (val) { 10640 dut->ap_venue_name = atoi(val); 10641 sigma_dut_print(dut, DUT_MSG_INFO, "ap_venue_name %d", 10642 dut->ap_venue_name); 10643 } 10644 10645 val = get_param(cmd, "GAS_CB_DELAY"); 10646 if (val) { 10647 dut->ap_gas_cb_delay = atoi(val); 10648 sigma_dut_print(dut, DUT_MSG_INFO, "ap_gas_cb_delay %d", 10649 dut->ap_gas_cb_delay); 10650 } 10651 10652 val = get_param(cmd, "MIH"); 10653 if (val && atoi(val) > 0) { 10654 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MIH not " 10655 "supported"); 10656 return 0; 10657 } 10658 10659 val = get_param(cmd, "L2_TRAFFIC_INSPECT"); 10660 if (val) { 10661 dut->ap_l2tif = atoi(val); 10662 sigma_dut_print(dut, DUT_MSG_INFO, "ap_l2tif %d", 10663 dut->ap_l2tif); 10664 } 10665 10666 val = get_param(cmd, "BCST_UNCST"); 10667 if (val) { 10668 send_resp(dut, conn, SIGMA_ERROR, 10669 "errorCode,BCST_UNCST not yet supported"); 10670 return 0; 10671 } 10672 10673 val = get_param(cmd, "PLMN_MCC"); 10674 if (val) { 10675 char mcc[100], *start, *end; 10676 int i = 0; 10677 if (strlen(val) >= sizeof(mcc)) { 10678 send_resp(dut, conn, SIGMA_ERROR, 10679 "errorCode,PLMN_MCC too long"); 10680 return 0; 10681 } 10682 strlcpy(mcc, val, sizeof(mcc)); 10683 start = mcc; 10684 while ((end = strchr(start, ';'))) { 10685 /* process all except the last */ 10686 *end = '\0'; 10687 if (strlen(start) != 3) { 10688 send_resp(dut, conn, SIGMA_ERROR, 10689 "errorCode,Invalid PLMN_MCC"); 10690 return 0; 10691 } 10692 res = snprintf(dut->ap_plmn_mcc[i], 10693 sizeof(dut->ap_plmn_mcc[i]), "%s", 10694 start); 10695 if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i])) 10696 return ERROR_SEND_STATUS; 10697 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s", 10698 dut->ap_plmn_mcc[i]); 10699 i++; 10700 start = end + 1; 10701 *end = ';'; 10702 } 10703 if (strlen(start) != 3) { 10704 send_resp(dut, conn, SIGMA_ERROR, 10705 "errorCode,Invalid PLMN_MCC"); 10706 return 0; 10707 } 10708 /* process last or only one */ 10709 res = snprintf(dut->ap_plmn_mcc[i], 10710 sizeof(dut->ap_plmn_mcc[i]), "%s", start); 10711 if (res < 0 || res >= sizeof(dut->ap_plmn_mcc[i])) 10712 return ERROR_SEND_STATUS; 10713 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mcc %s", 10714 dut->ap_plmn_mcc[i]); 10715 } 10716 10717 val = get_param(cmd, "PLMN_MNC"); 10718 if (val) { 10719 char mnc[100], *start, *end; 10720 int i = 0; 10721 if (strlen(val) >= sizeof(mnc)) { 10722 send_resp(dut, conn, SIGMA_ERROR, 10723 "errorCode,PLMN_MNC too long"); 10724 return 0; 10725 } 10726 strlcpy(mnc, val, sizeof(mnc)); 10727 start = mnc; 10728 while ((end = strchr(start, ';'))) { 10729 *end = '\0'; 10730 if (strlen(start) != 2 && strlen(start) != 3) { 10731 send_resp(dut, conn, SIGMA_ERROR, 10732 "errorCode,Invalid PLMN_MNC"); 10733 return 0; 10734 } 10735 res = snprintf(dut->ap_plmn_mnc[i], 10736 sizeof(dut->ap_plmn_mnc[i]), "%s", 10737 start); 10738 if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i])) 10739 return ERROR_SEND_STATUS; 10740 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s", 10741 dut->ap_plmn_mnc[i]); 10742 i++; 10743 start = end + 1; 10744 *end = ';'; 10745 } 10746 if (strlen(start) != 2 && strlen(start) != 3) { 10747 send_resp(dut, conn, SIGMA_ERROR, 10748 "errorCode,Invalid PLMN_MNC"); 10749 return 0; 10750 } 10751 res = snprintf(dut->ap_plmn_mnc[i], 10752 sizeof(dut->ap_plmn_mnc[i]), "%s", start); 10753 if (res < 0 || res >= sizeof(dut->ap_plmn_mnc[i])) 10754 return ERROR_SEND_STATUS; 10755 sigma_dut_print(dut, DUT_MSG_INFO, "ap_plmn_mnc %s", 10756 dut->ap_plmn_mnc[i]); 10757 } 10758 10759 val = get_param(cmd, "PROXY_ARP"); 10760 if (val) { 10761 dut->ap_proxy_arp = atoi(val); 10762 sigma_dut_print(dut, DUT_MSG_INFO, "ap_proxy_arp %d", 10763 dut->ap_proxy_arp); 10764 } 10765 10766 val = get_param(cmd, "WAN_METRICS"); 10767 if (val) { 10768 dut->ap_wan_metrics = atoi(val); 10769 sigma_dut_print(dut, DUT_MSG_INFO, "ap_wan_metrics %d", 10770 dut->ap_wan_metrics); 10771 } 10772 10773 val = get_param(cmd, "CONN_CAP"); 10774 if (val) { 10775 dut->ap_conn_capab = atoi(val); 10776 sigma_dut_print(dut, DUT_MSG_INFO, "ap_conn_capab %d", 10777 dut->ap_conn_capab); 10778 } 10779 10780 val = get_param(cmd, "IP_ADD_TYPE_AVAIL"); 10781 if (val) { 10782 dut->ap_ip_addr_type_avail = atoi(val); 10783 sigma_dut_print(dut, DUT_MSG_INFO, "ap_ip_addr_type_avail %d", 10784 dut->ap_ip_addr_type_avail); 10785 } 10786 10787 val = get_param(cmd, "NET_AUTH_TYPE"); 10788 if (val) { 10789 dut->ap_net_auth_type = atoi(val); 10790 sigma_dut_print(dut, DUT_MSG_INFO, "ap_net_auth_type %d", 10791 dut->ap_net_auth_type); 10792 } 10793 10794 val = get_param(cmd, "OP_CLASS"); 10795 if (val == NULL) 10796 val = get_param(cmd, "OPER_CLASS"); 10797 if (val) { 10798 dut->ap_oper_class = atoi(val); 10799 sigma_dut_print(dut, DUT_MSG_INFO, "ap_oper_class %d", 10800 dut->ap_oper_class); 10801 } 10802 10803 val = get_param(cmd, "OSU_PROVIDER_LIST"); 10804 if (val) { 10805 dut->ap_osu_provider_list = atoi(val); 10806 sigma_dut_print(dut, DUT_MSG_INFO, "ap_osu_provider_list %d", 10807 dut->ap_osu_provider_list); 10808 } 10809 10810 val = get_param(cmd, "OSU_PROVIDER_NAI_LIST"); 10811 if (val) { 10812 dut->ap_osu_provider_nai_list = atoi(val); 10813 sigma_dut_print(dut, DUT_MSG_INFO, 10814 "ap_osu_provider_nai_list %d", 10815 dut->ap_osu_provider_nai_list); 10816 } 10817 10818 val = get_param(cmd, "OSU_SERVER_URI"); 10819 if (val) { 10820 i = 0; 10821 do { 10822 int len; 10823 const char *uri = val; 10824 val = strchr(val, ' '); 10825 len = val ? (val++ - uri) : (int) strlen(uri); 10826 if (len > 0 && len < 256) { 10827 memcpy(dut->ap_osu_server_uri[i], uri, len); 10828 dut->ap_osu_server_uri[i][len] = '\0'; 10829 sigma_dut_print(dut, DUT_MSG_INFO, 10830 "ap_osu_server_uri[%d] %s", i, 10831 dut->ap_osu_server_uri[i]); 10832 } 10833 } while (val && ++i < 10); 10834 } 10835 10836 val = get_param(cmd, "OSU_METHOD"); 10837 if (val) { 10838 i = 0; 10839 do { 10840 int len; 10841 const char *method = val; 10842 val = strchr(val, ' '); 10843 len = val ? (val++ - method) : (int) strlen(method); 10844 if (len > 0) { 10845 if (strncasecmp(method, "SOAP", len) == 0) 10846 dut->ap_osu_method[i] = 1; 10847 else if (strncasecmp(method, "OMADM", len) == 0) 10848 dut->ap_osu_method[i] = 0; 10849 else 10850 return -2; 10851 } 10852 } while (val && ++i < 10); 10853 } 10854 10855 val = get_param(cmd, "OSU_SSID"); 10856 if (val) { 10857 if (strlen(val) > 0 && strlen(val) <= 32) { 10858 strlcpy(dut->ap_osu_ssid, val, 10859 sizeof(dut->ap_osu_ssid)); 10860 sigma_dut_print(dut, DUT_MSG_INFO, 10861 "ap_osu_ssid %s", 10862 dut->ap_osu_ssid); 10863 } 10864 } 10865 10866 val = get_param(cmd, "OSU_ICON_TAG"); 10867 if (val) 10868 dut->ap_osu_icon_tag = atoi(val); 10869 10870 val = get_param(cmd, "QoS_MAP_SET"); 10871 if (val) { 10872 dut->ap_qos_map_set = atoi(val); 10873 sigma_dut_print(dut, DUT_MSG_INFO, "ap_qos_map_set %d", 10874 dut->ap_qos_map_set); 10875 } 10876 10877 val = get_param(cmd, "BSS_LOAD"); 10878 if (val) { 10879 dut->ap_bss_load = atoi(val); 10880 sigma_dut_print(dut, DUT_MSG_INFO, "ap_bss_load %d", 10881 dut->ap_bss_load); 10882 } 10883 10884 val = get_param(cmd, "Venue_URL"); 10885 if (val) 10886 dut->ap_venue_url = atoi(val); 10887 10888 val = get_param(cmd, "Advice_of_Charge"); 10889 if (val) 10890 dut->ap_advice_of_charge = atoi(val); 10891 10892 val = get_param(cmd, "Operator_Icon_Metadata"); 10893 if (val) 10894 dut->ap_oper_icon_metadata = atoi(val); 10895 10896 val = get_param(cmd, "TnC_File_Name"); 10897 if (val) 10898 dut->ap_tnc_file_name = atoi(val); 10899 10900 val = get_param(cmd, "TnC_File_Time_Stamp"); 10901 if (val) 10902 dut->ap_tnc_time_stamp = strtol(val, NULL, 10); 10903 10904 return 1; 10905 } 10906 10907 10908 void nfc_status(struct sigma_dut *dut, const char *state, const char *oper) 10909 { 10910 char buf[100]; 10911 10912 if (!file_exists("nfc-status")) 10913 return; 10914 10915 snprintf(buf, sizeof(buf), "./nfc-status %s %s", state, oper); 10916 run_system(dut, buf); 10917 } 10918 10919 10920 static int run_nfc_command(struct sigma_dut *dut, const char *cmd, 10921 const char *info) 10922 { 10923 int res; 10924 10925 printf("\n\n\n=====[ NFC operation ]=========================\n\n"); 10926 printf("%s\n\n", info); 10927 10928 nfc_status(dut, "START", info); 10929 res = run_system(dut, cmd); 10930 nfc_status(dut, res ? "FAIL" : "SUCCESS", info); 10931 if (res) { 10932 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d", 10933 cmd, res); 10934 return res; 10935 } 10936 10937 return 0; 10938 } 10939 10940 10941 static int ap_nfc_write_config_token(struct sigma_dut *dut, 10942 struct sigma_conn *conn, 10943 struct sigma_cmd *cmd) 10944 { 10945 int res; 10946 char buf[300]; 10947 10948 run_system(dut, "killall wps-ap-nfc.py"); 10949 unlink("nfc-success"); 10950 snprintf(buf, sizeof(buf), 10951 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-config", 10952 dut->summary_log ? "--summary " : "", 10953 dut->summary_log ? dut->summary_log : ""); 10954 res = run_nfc_command(dut, buf, 10955 "Touch NFC Tag to write WPS configuration token"); 10956 if (res || !file_exists("nfc-success")) { 10957 send_resp(dut, conn, SIGMA_ERROR, 10958 "ErrorCode,Failed to write tag"); 10959 return 0; 10960 } 10961 10962 return 1; 10963 } 10964 10965 10966 static int ap_nfc_wps_read_passwd(struct sigma_dut *dut, 10967 struct sigma_conn *conn, 10968 struct sigma_cmd *cmd) 10969 { 10970 int res; 10971 char buf[300]; 10972 10973 run_system(dut, "killall wps-ap-nfc.py"); 10974 10975 unlink("nfc-success"); 10976 snprintf(buf, sizeof(buf), 10977 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success", 10978 dut->summary_log ? "--summary " : "", 10979 dut->summary_log ? dut->summary_log : ""); 10980 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it"); 10981 if (res || !file_exists("nfc-success")) { 10982 send_resp(dut, conn, SIGMA_ERROR, 10983 "ErrorCode,Failed to read tag"); 10984 return 0; 10985 } 10986 10987 return 1; 10988 } 10989 10990 10991 static int ap_nfc_write_password_token(struct sigma_dut *dut, 10992 struct sigma_conn *conn, 10993 struct sigma_cmd *cmd) 10994 { 10995 int res; 10996 char buf[300]; 10997 10998 run_system(dut, "killall wps-ap-nfc.py"); 10999 unlink("nfc-success"); 11000 snprintf(buf, sizeof(buf), 11001 "./wps-ap-nfc.py --no-wait %s%s --success nfc-success write-password", 11002 dut->summary_log ? "--summary " : "", 11003 dut->summary_log ? dut->summary_log : ""); 11004 res = run_nfc_command(dut, buf, 11005 "Touch NFC Tag to write WPS password token"); 11006 if (res || !file_exists("nfc-success")) { 11007 send_resp(dut, conn, SIGMA_ERROR, 11008 "ErrorCode,Failed to write tag"); 11009 return 0; 11010 } 11011 11012 if (run_hostapd_cli(dut, "wps_nfc_token enable") != 0) { 11013 send_resp(dut, conn, SIGMA_ERROR, 11014 "ErrorCode,Failed to enable NFC password token"); 11015 return 0; 11016 } 11017 11018 return 1; 11019 } 11020 11021 11022 static int ap_nfc_wps_connection_handover(struct sigma_dut *dut, 11023 struct sigma_conn *conn, 11024 struct sigma_cmd *cmd) 11025 { 11026 int res; 11027 char buf[300]; 11028 11029 run_system(dut, "killall wps-ap-nfc.py"); 11030 unlink("nfc-success"); 11031 snprintf(buf, sizeof(buf), 11032 "./wps-ap-nfc.py -1 --no-wait %s%s --success nfc-success", 11033 dut->summary_log ? "--summary " : "", 11034 dut->summary_log ? dut->summary_log : ""); 11035 res = run_nfc_command(dut, buf, 11036 "Touch NFC Device to respond to WPS connection handover"); 11037 if (res) { 11038 send_resp(dut, conn, SIGMA_ERROR, 11039 "ErrorCode,Failed to enable NFC for connection " 11040 "handover"); 11041 return 0; 11042 } 11043 if (!file_exists("nfc-success")) { 11044 send_resp(dut, conn, SIGMA_ERROR, 11045 "ErrorCode,Failed to complete NFC connection handover"); 11046 return 0; 11047 } 11048 11049 return 1; 11050 } 11051 11052 11053 static enum sigma_cmd_result cmd_ap_nfc_action(struct sigma_dut *dut, 11054 struct sigma_conn *conn, 11055 struct sigma_cmd *cmd) 11056 { 11057 /* const char *name = get_param(cmd, "Name"); */ 11058 /* const char *intf = get_param(cmd, "Interface"); */ 11059 const char *oper = get_param(cmd, "Operation"); 11060 11061 if (oper == NULL) 11062 return -1; 11063 11064 if (strcasecmp(oper, "WRITE_CONFIG") == 0) 11065 return ap_nfc_write_config_token(dut, conn, cmd); 11066 if (strcasecmp(oper, "WRITE_PASSWD") == 0) 11067 return ap_nfc_write_password_token(dut, conn, cmd); 11068 if (strcasecmp(oper, "WPS_READ_PASSWD") == 0) 11069 return ap_nfc_wps_read_passwd(dut, conn, cmd); 11070 if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0) 11071 return ap_nfc_wps_connection_handover(dut, conn, cmd); 11072 11073 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation"); 11074 return 0; 11075 } 11076 11077 11078 static enum sigma_cmd_result cmd_ap_wps_read_pin(struct sigma_dut *dut, 11079 struct sigma_conn *conn, 11080 struct sigma_cmd *cmd) 11081 { 11082 char *pin = "12345670"; /* TODO: use random PIN */ 11083 char resp[100]; 11084 11085 snprintf(resp, sizeof(resp), "PIN,%s", pin); 11086 send_resp(dut, conn, SIGMA_COMPLETE, resp); 11087 11088 return 0; 11089 } 11090 11091 11092 static enum sigma_cmd_result cmd_ap_wps_enter_pin(struct sigma_dut *dut, 11093 struct sigma_conn *conn, 11094 struct sigma_cmd *cmd) 11095 { 11096 const char *pin = get_param(cmd, "PIN"); 11097 char wps_pin[11]; 11098 11099 if (!pin) 11100 return -1; 11101 11102 sigma_dut_print(dut, DUT_MSG_DEBUG, 11103 "Authorize a client to join with WPS PIN %s", pin); 11104 11105 strlcpy(wps_pin, pin, sizeof(wps_pin)); 11106 /* we need to tolerate extra '-' characters entered */ 11107 str_remove_chars(wps_pin, '-'); 11108 strlcpy(dut->wps_pin, wps_pin, sizeof(dut->wps_pin)); 11109 dut->wps_method = WFA_CS_WPS_PIN_KEYPAD; 11110 11111 return 1; 11112 } 11113 11114 11115 static enum sigma_cmd_result cmd_ap_wps_set_pbc(struct sigma_dut *dut, 11116 struct sigma_conn *conn, 11117 struct sigma_cmd *cmd) 11118 { 11119 sigma_dut_print(dut, DUT_MSG_DEBUG, 11120 "Selecting the push button configuration method"); 11121 11122 dut->wps_method = WFA_CS_WPS_PBC; 11123 11124 return 1; 11125 } 11126 11127 11128 int ap_wps_registration(struct sigma_dut *dut, struct sigma_conn *conn, 11129 struct sigma_cmd *cmd) 11130 { 11131 char buf[100], resp[256]; 11132 const char *intf = get_param(cmd, "interface"); 11133 const char *config_method = get_param(cmd, "WPSConfigMethod"); 11134 11135 if (config_method && strcasecmp(config_method, "PBC") == 0) 11136 dut->wps_method = WFA_CS_WPS_PBC; 11137 11138 if (!intf) 11139 intf = get_main_ifname(dut); 11140 11141 if (dut->wps_method == WFA_CS_WPS_NOT_READY) { 11142 send_resp(dut, conn, SIGMA_ERROR, 11143 "ErrorCode,WPS parameters not yet set"); 11144 return STATUS_SENT; 11145 } 11146 11147 if (dut->wps_method == WFA_CS_WPS_PBC) 11148 snprintf(buf, sizeof(buf), "WPS_PBC"); 11149 else /* WFA_CS_WPS_PIN_KEYPAD */ 11150 snprintf(buf, sizeof(buf), "WPS_PIN any %s", dut->wps_pin); 11151 11152 /* Run WPS command */ 11153 if (hapd_command(intf, buf) < 0) { 11154 /* command fails immediately if overlapped session detected */ 11155 snprintf(resp, sizeof(resp), "WpsState,OverlapSession"); 11156 send_resp(dut, conn, SIGMA_COMPLETE, resp); 11157 return STATUS_SENT; 11158 } 11159 11160 /* In AP mode return immediately and do not wait for WPS registration */ 11161 return SUCCESS_SEND_STATUS; 11162 } 11163 11164 11165 static enum sigma_cmd_result cmd_ap_get_parameter(struct sigma_dut *dut, 11166 struct sigma_conn *conn, 11167 struct sigma_cmd *cmd) 11168 { 11169 char value[256], resp[512]; 11170 const char *param = get_param(cmd, "parameter"); 11171 const char *ifname = get_param(cmd, "Interface"); 11172 const char *var; 11173 11174 if (!ifname) 11175 ifname = get_main_ifname(dut); 11176 11177 if (!param) { 11178 send_resp(dut, conn, SIGMA_ERROR, 11179 "ErrorCode,Parameter not specified"); 11180 return 0; 11181 } 11182 11183 if (strcasecmp(param, "SSID") == 0) { 11184 if (get_hapd_config(ifname, "ssid", value, sizeof(value))) { 11185 sigma_dut_print(dut, DUT_MSG_ERROR, 11186 "Failed to get SSID"); 11187 return -2; 11188 } 11189 snprintf(resp, sizeof(resp), "SSID,%s", value); 11190 } else if (strcasecmp(param, "PSK") == 0) { 11191 if (get_hapd_config(ifname, "passphrase", value, 11192 sizeof(value))) { 11193 sigma_dut_print(dut, DUT_MSG_ERROR, 11194 "Failed to get PSK"); 11195 return -2; 11196 } 11197 snprintf(resp, sizeof(resp), "PSK,%s", value); 11198 } else if (strcasecmp(param, "PMK") == 0) { 11199 var = get_param(cmd, "STA_MAC_Address"); 11200 if (!var) 11201 return INVALID_SEND_STATUS; 11202 snprintf(resp, sizeof(resp), "GET_PMK %s", var); 11203 if (hapd_command_resp(ifname, resp, &resp[4], 11204 sizeof(resp) - 4) < 0) { 11205 send_resp(dut, conn, SIGMA_ERROR, 11206 "ErrorCode,GET_PMK failed"); 11207 return STATUS_SENT_ERROR; 11208 } 11209 memcpy(resp, "PMK,", 4); 11210 } else { 11211 send_resp(dut, conn, SIGMA_ERROR, 11212 "ErrorCode,Unsupported parameter"); 11213 return 0; 11214 } 11215 11216 send_resp(dut, conn, SIGMA_COMPLETE, resp); 11217 return 0; 11218 } 11219 11220 11221 static int ath_vht_op_mode_notif(struct sigma_dut *dut, const char *ifname, 11222 const char *val) 11223 { 11224 char *token, *result; 11225 int nss = 0, chwidth = 0; 11226 char *saveptr; 11227 11228 /* 11229 * The following commands should be invoked to generate 11230 * VHT op mode notification 11231 */ 11232 11233 /* Extract the NSS info */ 11234 token = strdup(val); 11235 if (!token) 11236 return -1; 11237 result = strtok_r(token, ";", &saveptr); 11238 if (result) { 11239 int count = atoi(result); 11240 11241 /* We do not support NSS > 3 */ 11242 if (count < 0 || count > 3) { 11243 free(token); 11244 return -1; 11245 } 11246 11247 /* Convert nss to chainmask */ 11248 while (count--) 11249 nss = (nss << 1) | 1; 11250 11251 run_iwpriv(dut, ifname, "rxchainmask %d", nss); 11252 } 11253 11254 /* Extract the Channel width info */ 11255 result = strtok_r(NULL, ";", &saveptr); 11256 if (result) { 11257 switch (atoi(result)) { 11258 case 20: 11259 chwidth = 0; 11260 break; 11261 case 40: 11262 chwidth = 1; 11263 break; 11264 case 80: 11265 chwidth = 2; 11266 break; 11267 case 160: 11268 chwidth = 3; 11269 break; 11270 default: 11271 chwidth = 2; 11272 break; 11273 } 11274 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 11275 } 11276 11277 /* Send the opmode notification */ 11278 run_iwpriv(dut, ifname, "opmode_notify 1"); 11279 free(token); 11280 11281 return 0; 11282 } 11283 11284 11285 static int ath_vht_nss_mcs(struct sigma_dut *dut, const char *ifname, 11286 const char *val) 11287 { 11288 /* String (nss_operating_mode; mcs_operating_mode) */ 11289 int nss, mcs; 11290 char *token, *result; 11291 char *saveptr; 11292 11293 token = strdup(val); 11294 if (!token) 11295 return -1; 11296 result = strtok_r(token, ";", &saveptr); 11297 if (!result) { 11298 sigma_dut_print(dut, DUT_MSG_ERROR, 11299 "VHT NSS not specified"); 11300 goto end; 11301 } 11302 if (strcasecmp(result, "def") != 0) { 11303 nss = atoi(result); 11304 11305 if (nss == 4) 11306 ath_disable_txbf(dut, ifname); 11307 11308 run_iwpriv(dut, ifname, "nss %d", nss); 11309 } else { 11310 if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1) 11311 run_iwpriv(dut, ifname, "nss 1"); 11312 if (dut->device_type == AP_testbed && 11313 dut->program == PROGRAM_HE) { 11314 nss = dut->ap_tx_streams; 11315 run_iwpriv(dut, ifname, "nss %d", nss); 11316 } 11317 } 11318 11319 result = strtok_r(NULL, ";", &saveptr); 11320 if (!result) { 11321 sigma_dut_print(dut, DUT_MSG_ERROR, 11322 "VHT MCS not specified"); 11323 goto end; 11324 } 11325 if (strcasecmp(result, "def") == 0) { 11326 if (dut->device_type == AP_testbed && dut->ap_sgi80 == 1) 11327 run_iwpriv(dut, ifname, "vhtmcs 7"); 11328 else 11329 run_iwpriv(dut, ifname, "set11NRates 0"); 11330 if (dut->device_type == AP_testbed && 11331 dut->program == PROGRAM_HE) 11332 run_iwpriv(dut, ifname, "he_mcs 7"); 11333 } else { 11334 mcs = atoi(result); 11335 if (dut->program == PROGRAM_HE) 11336 run_iwpriv(dut, ifname, "he_mcs %d", mcs); 11337 else 11338 run_iwpriv(dut, ifname, "vhtmcs %d", mcs); 11339 } 11340 11341 end: 11342 free(token); 11343 return 0; 11344 } 11345 11346 11347 static int ath_vht_chnum_band(struct sigma_dut *dut, const char *ifname, 11348 const char *val) 11349 { 11350 char *token, *result; 11351 int channel = 36; 11352 int chwidth = 80; 11353 char *saveptr; 11354 11355 /* Extract the channel info */ 11356 token = strdup(val); 11357 if (!token) 11358 return -1; 11359 result = strtok_r(token, ";", &saveptr); 11360 if (result) 11361 channel = atoi(result); 11362 11363 /* Extract the channel width info */ 11364 result = strtok_r(NULL, ";", &saveptr); 11365 if (result) 11366 chwidth = atoi(result); 11367 11368 /* Issue the channel switch command */ 11369 run_iwpriv(dut, ifname, "doth_ch_chwidth %d 10 %d", channel, chwidth); 11370 11371 free(token); 11372 return 0; 11373 } 11374 11375 11376 static int ath_ndpa_stainfo_mac(struct sigma_dut *dut, const char *ifname, 11377 const char *val) 11378 { 11379 char buf[80]; 11380 unsigned char mac_addr[6]; 11381 11382 if (parse_mac_address(dut, val, mac_addr) < 0) 11383 return -1; 11384 11385 snprintf(buf, sizeof(buf), 11386 "wifitool %s beeliner_fw_test 92 0x%02x%02x%02x%02x", 11387 ifname, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]); 11388 run_system(dut, buf); 11389 11390 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 93 0x%02x%02x", 11391 ifname, mac_addr[4], mac_addr[5]); 11392 run_system(dut, buf); 11393 11394 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 94 1", ifname); 11395 run_system(dut, buf); 11396 11397 return 0; 11398 } 11399 11400 11401 void novap_reset(struct sigma_dut *dut, const char *ifname, int reset) 11402 { 11403 run_iwpriv(dut, ifname, "novap_reset %d", reset); 11404 } 11405 11406 11407 static struct mbo_pref_ap * mbo_find_nebor_ap_entry(struct sigma_dut *dut, 11408 const uint8_t *mac_addr) 11409 { 11410 int i; 11411 11412 for (i = 0; i < dut->mbo_pref_ap_cnt; i++) { 11413 if (memcmp(mac_addr, dut->mbo_pref_aps[i].mac_addr, 11414 ETH_ALEN) == 0) 11415 return &dut->mbo_pref_aps[i]; 11416 } 11417 return NULL; 11418 } 11419 11420 11421 static void mbo_add_nebor_entry(struct sigma_dut *dut, const uint8_t *mac_addr, 11422 int ap_ne_class, int ap_ne_op_ch, 11423 int ap_ne_pref) 11424 { 11425 struct mbo_pref_ap *entry; 11426 uint8_t self_mac[ETH_ALEN]; 11427 char ifname[50]; 11428 11429 get_if_name(dut, ifname, sizeof(ifname), 1); 11430 get_hwaddr(ifname, self_mac); 11431 11432 if (memcmp(mac_addr, self_mac, ETH_ALEN) == 0) 11433 entry = &dut->mbo_self_ap_tuple; 11434 else 11435 entry = mbo_find_nebor_ap_entry(dut, mac_addr); 11436 11437 if (!entry) { 11438 if (dut->mbo_pref_ap_cnt >= MBO_MAX_PREF_BSSIDS) { 11439 sigma_dut_print(dut, DUT_MSG_ERROR, 11440 "Nebor AP List is full. Not adding"); 11441 return; 11442 } 11443 entry = &dut->mbo_pref_aps[dut->mbo_pref_ap_cnt]; 11444 dut->mbo_pref_ap_cnt++; 11445 memcpy(entry->mac_addr, mac_addr, ETH_ALEN); 11446 entry->ap_ne_class = -1; 11447 entry->ap_ne_op_ch = -1; 11448 entry->ap_ne_pref = -1; 11449 } 11450 if (ap_ne_class != -1) 11451 entry->ap_ne_class = ap_ne_class; 11452 if (ap_ne_op_ch != -1) 11453 entry->ap_ne_op_ch = ap_ne_op_ch; 11454 if (ap_ne_pref != -1) 11455 entry->ap_ne_pref = ap_ne_pref; 11456 } 11457 11458 11459 static int ath_set_nebor_bssid(struct sigma_dut *dut, const char *ifname, 11460 struct sigma_cmd *cmd) 11461 { 11462 unsigned char mac_addr[ETH_ALEN]; 11463 const char *val; 11464 /* 11465 * -1 is invalid value for the following 11466 * to differentiate between unset and set values 11467 * -1 => implies not set by CAPI 11468 */ 11469 int ap_ne_class = -1, ap_ne_op_ch = -1, ap_ne_pref = -1; 11470 int list_offset = dut->mbo_pref_ap_cnt; 11471 11472 if (list_offset >= MBO_MAX_PREF_BSSIDS) { 11473 sigma_dut_print(dut, DUT_MSG_ERROR, 11474 "AP Pref Entry list is full"); 11475 return -1; 11476 } 11477 11478 val = get_param(cmd, "Nebor_Op_Class"); 11479 if (val) 11480 ap_ne_class = atoi(val); 11481 11482 val = get_param(cmd, "Nebor_Op_Ch"); 11483 if (val) 11484 ap_ne_op_ch = atoi(val); 11485 11486 val = get_param(cmd, "Nebor_Pref"); 11487 if (val) 11488 ap_ne_pref = atoi(val); 11489 11490 val = get_param(cmd, "Nebor_BSSID"); 11491 if (!val || parse_mac_address(dut, val, mac_addr) < 0) 11492 return -1; 11493 11494 mbo_add_nebor_entry(dut, mac_addr, ap_ne_class, ap_ne_op_ch, 11495 ap_ne_pref); 11496 apply_mbo_pref_ap_list(dut); 11497 return 0; 11498 } 11499 11500 11501 static enum sigma_cmd_result he_ltf(struct sigma_dut *dut, 11502 struct sigma_conn *conn, 11503 const char *ifname, const char *val) 11504 { 11505 const char *var; 11506 11507 if (dut->ap_he_ulofdma == VALUE_ENABLED) 11508 var = "he_ul_ltf"; 11509 else 11510 var = "he_ltf"; 11511 11512 if (strcmp(val, "6.4") == 0) { 11513 run_iwpriv(dut, ifname, "%s 2", var); 11514 } else if (strcmp(val, "12.8") == 0) { 11515 run_iwpriv(dut, ifname, "%s 3", var); 11516 } else if (strcmp(val, "3.2") == 0) { 11517 run_iwpriv(dut, ifname, "%s 1", var); 11518 } else { 11519 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported LTF"); 11520 return STATUS_SENT_ERROR; 11521 } 11522 11523 return SUCCESS_SEND_STATUS; 11524 } 11525 11526 11527 static enum sigma_cmd_result he_shortgi(struct sigma_dut *dut, 11528 struct sigma_conn *conn, 11529 const char *ifname, 11530 const char *val) 11531 { 11532 const char *var; 11533 11534 if (dut->ap_he_ulofdma == VALUE_ENABLED) 11535 var = "he_ul_shortgi"; 11536 else 11537 var = "shortgi"; 11538 11539 if (strcmp(val, "0.8") == 0) { 11540 run_iwpriv(dut, ifname, "%s 0", var); 11541 } else if (strcmp(val, "1.6") == 0) { 11542 run_iwpriv(dut, ifname, "%s 2", var); 11543 } else if (strcmp(val, "3.2") == 0) { 11544 run_iwpriv(dut, ifname, "%s 3", var); 11545 } else { 11546 send_resp(dut, conn, SIGMA_ERROR, 11547 "errorCode,Unsupported shortGI"); 11548 return STATUS_SENT_ERROR; 11549 } 11550 11551 return SUCCESS_SEND_STATUS; 11552 } 11553 11554 11555 static enum sigma_cmd_result he_ar_gi_ltf_mask(struct sigma_dut *dut, 11556 struct sigma_conn *conn, 11557 const char *ifname, 11558 const char *val) 11559 { 11560 11561 uint32_t he_ar_gi_ltf; 11562 uint16_t he_ar_gi, he_ar_ltf; 11563 11564 if (strcmp(val, "0.4") == 0) { 11565 he_ar_gi = 0x01; 11566 } else if (strcmp(val, "0.8") == 0) { 11567 he_ar_gi = 0x02; 11568 } else if (strcmp(val, "1.6") == 0) { 11569 he_ar_gi = 0x04; 11570 } else if (strcmp(val, "3.2") == 0) { 11571 he_ar_gi = 0x08; 11572 } else { 11573 send_resp(dut, conn, SIGMA_ERROR, 11574 "errorCode,Unsupported shortGI"); 11575 return STATUS_SENT_ERROR; 11576 } 11577 11578 if (dut->ar_ltf && strcmp(dut->ar_ltf, "6.4") == 0) { 11579 he_ar_ltf = 0x02; 11580 } else if (dut->ar_ltf && strcmp(dut->ar_ltf, "12.8") == 0) { 11581 he_ar_ltf = 0x04; 11582 } else if (dut->ar_ltf && strcmp(dut->ar_ltf, "3.2") == 0) { 11583 he_ar_ltf = 0x01; 11584 } else { 11585 send_resp(dut, conn, SIGMA_ERROR, 11586 "errorCode,Unsupported LTF"); 11587 return STATUS_SENT_ERROR; 11588 } 11589 11590 he_ar_gi_ltf = (he_ar_gi << 8) | he_ar_ltf; 11591 run_iwpriv(dut, ifname, "he_ar_gi_ltf %lu", he_ar_gi_ltf); 11592 11593 return SUCCESS_SEND_STATUS; 11594 } 11595 11596 11597 static enum sigma_cmd_result he_rualloctones(struct sigma_dut *dut, 11598 struct sigma_conn *conn, 11599 const char *ifname, 11600 const char *val) 11601 { 11602 char *token, *result; 11603 int value; 11604 char *saveptr; 11605 int rualloc_type; 11606 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS; 11607 11608 token = strdup(val); 11609 if (!token) 11610 return -1; 11611 result = strtok_r(token, ":", &saveptr); 11612 if (!result) { 11613 free(token); 11614 send_resp(dut, conn, SIGMA_ERROR, 11615 "errorCode,RUAllocTones not specified"); 11616 return STATUS_SENT_ERROR; 11617 } 11618 11619 /* 11620 * ru_allocation_type can take the values of: 11621 * 1 - DL OFDMA data RU allocation 11622 * 3 - UL OFDMA data RU allocation 11623 */ 11624 rualloc_type = dut->ap_he_ulofdma == VALUE_ENABLED ? 3 : 1; 11625 11626 11627 value = atoi(result); 11628 if (value == 106) { 11629 enum value_not_set_enabled_disabled ap_he_rualloc_106_80 = 11630 VALUE_NOT_SET; 11631 11632 result = strtok_r(NULL, ":", &saveptr); 11633 if (result) { 11634 result = strtok_r(NULL, ":", &saveptr); 11635 if (result) 11636 ap_he_rualloc_106_80 = VALUE_ENABLED; 11637 else 11638 ap_he_rualloc_106_80 = VALUE_DISABLED; 11639 } 11640 if (ap_he_rualloc_106_80 == VALUE_ENABLED) { 11641 run_system_wrapper(dut, 11642 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 2 1 2 2 2 3 2", 11643 ifname, rualloc_type); 11644 } else { 11645 run_system_wrapper(dut, 11646 "wifitool %s setUnitTestCmd 0x4b 5 %d 0 2 1 2", 11647 ifname, rualloc_type); 11648 } 11649 } else if (value == 242) { 11650 run_system_wrapper( 11651 dut, 11652 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 3 1 3 2 3 3 3", 11653 ifname, rualloc_type); 11654 } else if (value == 26) { 11655 run_system_wrapper( 11656 dut, 11657 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 0 2 0 5 0 7 0", 11658 ifname, rualloc_type); 11659 } else if (value == 52) { 11660 run_system_wrapper( 11661 dut, 11662 "wifitool %s setUnitTestCmd 0x4b 9 %d 0 1 1 1 2 1 3 1", 11663 ifname, rualloc_type); 11664 } else if (value == 484) { 11665 run_system_wrapper( 11666 dut, 11667 "wifitool %s setUnitTestCmd 0x4b 5 %d 0 4 1 4", 11668 ifname, rualloc_type); 11669 } else if (value == 996) { 11670 run_system_wrapper(dut, 11671 "wifitool %s setUnitTestCmd 0x4b 3 %d 0 5", 11672 ifname, rualloc_type); 11673 } else { 11674 send_resp(dut, conn, SIGMA_ERROR, 11675 "errorCode,Unsupported RUAllocTones"); 11676 ret = STATUS_SENT_ERROR; 11677 } 11678 11679 free(token); 11680 return ret; 11681 } 11682 11683 11684 static void ath_set_trigger_type_0(struct sigma_dut *dut, const char *ifname) 11685 { 11686 /* TriggerType "0" for Basic trigger */ 11687 if (dut->ap_channel >= 36) { 11688 /* 1 and 2 here is interpreted to 5g and 2g (bitmasks) */ 11689 run_system_wrapper(dut, 11690 "wifitool %s setUnitTestCmd 0x47 2 42 1", 11691 ifname); 11692 } else { 11693 run_system_wrapper(dut, 11694 "wifitool %s setUnitTestCmd 0x47 2 42 2", 11695 ifname); 11696 } 11697 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 6", 11698 ifname); 11699 } 11700 11701 11702 static void ath_set_trigger_type_1(struct sigma_dut *dut, const char *ifname) 11703 { 11704 /* TriggerType "1" for MU BRP */ 11705 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 7 1", 11706 ifname); 11707 mubrp_commands(dut, ifname); 11708 } 11709 11710 11711 static void ath_set_trigger_type_2(struct sigma_dut *dut, const char *ifname) 11712 { 11713 /* TriggerType "2" for MU BAR */ 11714 if (dut->ap_channel >= 36) { 11715 /* RU allocation RU 242 - DL OFDMA data */ 11716 run_system_wrapper(dut, 11717 "wifitool %s setUnitTestCmd 0x4b 5 9 0 3 1 3 2 3 3 3", 11718 ifname); 11719 /* RU allocation RU 52 - UL BA */ 11720 run_system_wrapper(dut, 11721 "wifitool %s setUnitTestCmd 0x4b 5 9 0 2 1 2 2 2 3 2", 11722 ifname); 11723 } else { 11724 /* RU allocation RU 52 - DL ofdma data */ 11725 run_system_wrapper(dut, 11726 "wifitool %s setUnitTestCmd 0x4b 5 9 0 1 1 1 2 1 3 1", 11727 ifname); 11728 } 11729 /* Force TBPPDU duration to 400 us */ 11730 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 400", 11731 ifname); 11732 /* 0 to enable MU BAR, 1 to enable SU BAR */ 11733 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 49 0", 11734 ifname); 11735 /* MU BAR */ 11736 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 64 0", 11737 ifname); 11738 } 11739 11740 11741 static void ath_set_trigger_type_3(struct sigma_dut *dut, const char *ifname) 11742 { 11743 /* TriggerType "3" for MU RTS */ 11744 /* Send MU RTS Trigger - '1' is to enable MU RTS */ 11745 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 101 1", 11746 ifname); 11747 } 11748 11749 11750 static void ath_set_trigger_type_4(struct sigma_dut *dut, const char *ifname, 11751 const char *basedev) 11752 { 11753 /* TriggerType "4" for BSRP */ 11754 run_system_wrapper(dut, "cfg80211tool %s he_ul_trig_int 200", basedev); 11755 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x48 2 63 1000", 11756 ifname); 11757 if (dut->ap_channel >= 36) { 11758 run_system_wrapper(dut, 11759 "wifitool %s setUnitTestCmd 0x47 2 42 1", 11760 ifname); 11761 } else { 11762 run_system_wrapper(dut, 11763 "wifitool %s setUnitTestCmd 0x47 2 42 2", 11764 ifname); 11765 } 11766 /* Send BSRP command */ 11767 run_system_wrapper(dut, "wifitool %s setUnitTestCmd 0x47 2 43 7", 11768 ifname); 11769 } 11770 11771 11772 static enum sigma_cmd_result ath_ap_set_rfeature(struct sigma_dut *dut, 11773 struct sigma_conn *conn, 11774 struct sigma_cmd *cmd) 11775 { 11776 const char *val; 11777 const char *ifname; 11778 enum sigma_cmd_result res; 11779 const char *basedev = "wifi0"; 11780 int trigtype; 11781 int he_ackpolicymac = 0; 11782 char *num_ss = NULL; 11783 char *nss[4] = { NULL, NULL, NULL, NULL }; 11784 char *aid[4] = { NULL, NULL, NULL, NULL }; 11785 char *aid_ss = NULL; 11786 int omctrl_rxnss = 0, omctrl_chwidth = 0; 11787 int param; 11788 unsigned char mac_addr[ETH_ALEN]; 11789 11790 memset(mac_addr, 0x00, ETH_ALEN); 11791 11792 ifname = get_main_ifname(dut); 11793 11794 if (sigma_radio_ifname[0]) 11795 basedev = sigma_radio_ifname[0]; 11796 11797 /* Disable vap reset between the commands */ 11798 novap_reset(dut, ifname, 1); 11799 11800 val = get_param(cmd, "Opt_md_notif_ie"); 11801 if (val && ath_vht_op_mode_notif(dut, ifname, val) < 0) 11802 return ERROR_SEND_STATUS; 11803 11804 /* TODO: Optional arguments */ 11805 11806 val = get_param(cmd, "nss_mcs_opt"); 11807 if (val && ath_vht_nss_mcs(dut, ifname, val) < 0) 11808 return ERROR_SEND_STATUS; 11809 11810 val = get_param(cmd, "chnum_band"); 11811 if (val && ath_vht_chnum_band(dut, ifname, val) < 0) 11812 return ERROR_SEND_STATUS; 11813 11814 val = get_param(cmd, "RTS_FORCE"); 11815 if (val) 11816 ath_config_rts_force(dut, ifname, val); 11817 11818 val = get_param(cmd, "DYN_BW_SGNL"); 11819 if (val) 11820 ath_config_dyn_bw_sig(dut, ifname, val); 11821 11822 val = get_param(cmd, "CTS_WIDTH"); 11823 if (val) 11824 ath_set_cts_width(dut, ifname, val); 11825 11826 val = get_param(cmd, "Ndpa_stainfo_mac"); 11827 if (val && ath_ndpa_stainfo_mac(dut, ifname, val) < 0) 11828 return ERROR_SEND_STATUS; 11829 11830 val = get_param(cmd, "txBandwidth"); 11831 if (val && ath_set_width(dut, conn, ifname, val) < 0) 11832 return ERROR_SEND_STATUS; 11833 11834 val = get_param(cmd, "Assoc_Disallow"); 11835 if (val) 11836 ath_set_assoc_disallow(dut, ifname, val); 11837 11838 11839 ath_set_nebor_bssid(dut, ifname, cmd); 11840 val = get_param(cmd, "BTMReq_DisAssoc_Imnt"); 11841 if (val) { 11842 dut->ap_btmreq_disassoc_imnt = atoi(val); 11843 dut->ap_disassoc_timer = 1000; 11844 } 11845 11846 val = get_param(cmd, "BTMReq_Term_Bit"); 11847 if (val) 11848 dut->ap_btmreq_term_bit = atoi(val); 11849 11850 val = get_param(cmd, "Assoc_Delay"); 11851 if (val) { 11852 dut->ap_assoc_delay = 1; 11853 run_iwpriv(dut, ifname, "mbo_asoc_ret %s", val); 11854 } 11855 11856 val = get_param(cmd, "Disassoc_Timer"); 11857 if (val) 11858 dut->ap_disassoc_timer = atoi(val); 11859 11860 val = get_param(cmd, "BSS_Term_Duration"); 11861 if (val) 11862 dut->ap_btmreq_bss_term_dur = atoi(val); 11863 11864 val = get_param(cmd, "BSS_Term_TSF"); 11865 if (val) 11866 dut->ap_btmreq_bss_term_tsf = atoi(val); 11867 11868 val = get_param(cmd, "TxPower"); 11869 if (val) 11870 ath_set_txpower(dut, ifname, val); 11871 11872 val = get_param(cmd, "DownlinkAvailCap"); 11873 if (val) 11874 dut->ap_dl_availcap = atoi(val); 11875 11876 val = get_param(cmd, "UplinkAvailCap"); 11877 if (val) { 11878 dut->ap_ul_availcap = atoi(val); 11879 run_iwpriv(dut, ifname, "oce_wan_mtr %d %d", 11880 dut->ap_dl_availcap, dut->ap_ul_availcap); 11881 } 11882 11883 val = get_param(cmd, "RSSIthreshold"); 11884 if (val) { 11885 int rssithreshold; 11886 11887 run_iwpriv(dut, ifname, "oce_asoc_rej 1"); 11888 rssithreshold = atoi(val); 11889 run_iwpriv(dut, ifname, "oce_asoc_rssi %d", rssithreshold); 11890 } 11891 11892 val = get_param(cmd, "RetryDelay"); 11893 if (val) { 11894 int retrydelay; 11895 11896 run_iwpriv(dut, ifname, "oce_asoc_rej 1"); 11897 retrydelay = atoi(val); 11898 run_iwpriv(dut, ifname, "oce_asoc_dly %d", retrydelay); 11899 } 11900 11901 val = get_param(cmd, "LTF"); 11902 if (val) { 11903 if (dut->ap_fixed_rate) { 11904 res = he_ltf(dut, conn, ifname, val); 11905 if (res != SUCCESS_SEND_STATUS) 11906 return res; 11907 } else { 11908 free(dut->ar_ltf); 11909 dut->ar_ltf = strdup(val); 11910 if (!dut->ar_ltf) 11911 return ERROR_SEND_STATUS; 11912 } 11913 } 11914 11915 val = get_param(cmd, "GI"); 11916 if (val) { 11917 if (dut->ap_fixed_rate) 11918 res = he_shortgi(dut, conn, ifname, val); 11919 else 11920 res = he_ar_gi_ltf_mask(dut, conn, ifname, val); 11921 if (res != SUCCESS_SEND_STATUS) 11922 return res; 11923 } 11924 11925 val = get_param(cmd, "RUAllocTones"); 11926 if (val) { 11927 res = he_rualloctones(dut, conn, ifname, val); 11928 if (res != SUCCESS_SEND_STATUS) 11929 return res; 11930 } 11931 11932 val = get_param(cmd, "MPDU_MU_SpacingFactor"); 11933 if (val) 11934 run_system_wrapper(dut, 11935 "wifitool %s setUnitTestCmd 0x48 2 119, %s", 11936 ifname, val); 11937 11938 val = get_param(cmd, "PPDUTxType"); 11939 if (val) { 11940 if (strcasecmp(val, "HE-SU") == 0) { 11941 /* Change PPDU format type to HE-SU MCS 1 */ 11942 run_system_wrapper(dut, 11943 "wifitool %s setUnitTestCmd 0x48 2 89 0x401", 11944 ifname); 11945 } else if (strcasecmp(val, "legacy") == 0) { 11946 /* Change PPDU format type to non-HT */ 11947 run_system_wrapper(dut, 11948 "wifitool %s setUnitTestCmd 0x48 2 89 3", 11949 ifname); 11950 } else { 11951 send_resp(dut, conn, SIGMA_ERROR, 11952 "errorCode,Unsupported PPDUTxType"); 11953 return STATUS_SENT_ERROR; 11954 } 11955 } 11956 11957 val = get_param(cmd, "TXOPDuration"); 11958 if (val) { 11959 if (strcasecmp(val, "UNSPECIFIED") == 0) { 11960 /* The hardware is hardcoded with 0x7f; do nothing */ 11961 } else { 11962 send_resp(dut, conn, SIGMA_ERROR, 11963 "errorCode,Unsupported TXOPDuration"); 11964 return STATUS_SENT_ERROR; 11965 } 11966 } 11967 11968 val = get_param(cmd, "Trig_Usrinfo_UL-MCS"); 11969 if (val) 11970 run_iwpriv(dut, ifname, "he_ul_mcs %d", atoi(val)); 11971 11972 val = get_param(cmd, "Trig_Usrinfo_UL-Target-RSSI"); 11973 if (val) { 11974 /* Set target RSSI to -55 dBm */ 11975 run_system_wrapper(dut, 11976 "wifitool %s setUnitTestCmd 0x4b 2 7 %d", 11977 ifname, atoi(val) - 110); 11978 } 11979 11980 val = get_param(cmd, "Trig_Interval"); 11981 if (val) 11982 run_iwpriv(dut, basedev, "he_ul_trig_int %d", atoi(val)); 11983 11984 val = get_param(cmd, "Trig_ComInfo_ULLength"); 11985 if (val) 11986 run_system_wrapper(dut, 11987 "wifitool %s setUnitTestCmd 0x48 2 141 %d", 11988 ifname, atoi(val)); 11989 11990 val = get_param(cmd, "DisableTriggerType"); 11991 if (val) { 11992 trigtype = atoi(val); 11993 switch (trigtype) { 11994 case 0: 11995 /* DisableTriggerType "0" for basic trigger */ 11996 run_system_wrapper(dut, 11997 "wifitool %s setUnitTestCmd 0x47 2 42 0", 11998 ifname); 11999 break; 12000 default: 12001 /* Nothing to be done for now */ 12002 break; 12003 } 12004 } 12005 12006 val = get_param(cmd, "Trigger_TxBF"); 12007 if (val) { 12008 if (strcasecmp(val, "enable") == 0) { 12009 run_iwpriv(dut, ifname, "he_sounding_mode 0x9"); 12010 } else if (strcasecmp(val, "disable") == 0) { 12011 run_iwpriv(dut, ifname, "he_sounding_mode 0x1"); 12012 } else { 12013 send_resp(dut, conn, SIGMA_ERROR, 12014 "errorCode,Unsupported trigger_txbf"); 12015 return STATUS_SENT_ERROR; 12016 } 12017 } 12018 12019 val = get_param(cmd, "Trig_UsrInfo_RUAlloc"); 12020 if (val) { 12021 res = he_rualloctones(dut, conn, ifname, val); 12022 if (res != SUCCESS_SEND_STATUS) 12023 return res; 12024 } 12025 12026 val = get_param(cmd, "TriggerCoding"); 12027 if (val) { 12028 if (strcasecmp(val, "BCC") == 0) { 12029 /* In case of LDPC enable this command can force BCC if 12030 * RU size <= 242 */ 12031 run_iwpriv(dut, ifname, "he_ul_ldpc 0"); 12032 } else if (strcasecmp(val, "LDPC") == 0) { 12033 novap_reset(dut, ifname, 0); 12034 run_iwpriv(dut, ifname, "he_ul_ldpc 1"); 12035 novap_reset(dut, ifname, 1); 12036 } else { 12037 send_resp(dut, conn, SIGMA_ERROR, 12038 "errorCode,Unsupported TriggerCoding"); 12039 return STATUS_SENT_ERROR; 12040 } 12041 } 12042 12043 val = get_param(cmd, "AckPolicy_MAC"); 12044 if (val) { 12045 if (parse_mac_address(dut, val, mac_addr) < 0) { 12046 send_resp(dut, conn, SIGMA_ERROR, 12047 "errorCode,MAC Address not in proper format"); 12048 return STATUS_SENT_ERROR; 12049 } 12050 he_ackpolicymac = 1; 12051 } 12052 12053 val = get_param(cmd, "AckPolicy"); 12054 if (val) { 12055 int ap_he_ackpolicy; 12056 12057 ap_he_ackpolicy = atoi(val); 12058 if (ap_he_ackpolicy == 0 && he_ackpolicymac) { 12059 /* Disable all-BAR ackpolicy for MU-MIMO */ 12060 run_system_wrapper(dut, 12061 "wifitool %s setUnitTestCmd 0x48 2 62 0", 12062 ifname); 12063 /* Disable all-BAR ackpolicy first */ 12064 run_system_wrapper(dut, 12065 "wifitool %s setUnitTestCmd 0x48 2 64 0", 12066 ifname); 12067 /* Set normal ack policy for the STA with the specified 12068 * MAC address in DL-TX case */ 12069 run_system_wrapper(dut, 12070 "wifitool %s setUnitTestCmd 0x4b 8 8 1 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", 12071 ifname, mac_addr[0], mac_addr[1], 12072 mac_addr[2], mac_addr[3], 12073 mac_addr[4], mac_addr[5]); 12074 } else if (ap_he_ackpolicy == 3) { 12075 /* Enable all-BAR ackpolicy for MU-MIMO DL */ 12076 run_system_wrapper(dut, 12077 "wifitool %s setUnitTestCmd 0x48 2 62 1", 12078 ifname); 12079 /* Enable all-BAR ackpolicy */ 12080 run_system_wrapper(dut, 12081 "wifitool %s setUnitTestCmd 0x48 2 64 1", 12082 ifname); 12083 } else if (ap_he_ackpolicy == 4) { 12084 /* Enable htp-ack ackpolicy */ 12085 run_system_wrapper(dut, 12086 "wifitool %s setUnitTestCmd 0x47 2 99 1", 12087 ifname); 12088 } else { 12089 send_resp(dut, conn, SIGMA_ERROR, 12090 "errorCode,Invalid AckPolicy setting"); 12091 return STATUS_SENT_ERROR; 12092 } 12093 } 12094 12095 val = get_param(cmd, "Trig_ComInfo_GI-LTF"); 12096 if (val) { 12097 int trig_gi_ltf; 12098 12099 trig_gi_ltf = atoi(val); 12100 if (trig_gi_ltf == 0) { 12101 he_ltf(dut, conn, ifname, "3.2"); 12102 he_shortgi(dut, conn, ifname, "1.6"); 12103 } else if (trig_gi_ltf == 1) { 12104 he_ltf(dut, conn, ifname, "6.4"); 12105 he_shortgi(dut, conn, ifname, "1.6"); 12106 } else if (trig_gi_ltf == 2) { 12107 he_ltf(dut, conn, ifname, "12.8"); 12108 he_shortgi(dut, conn, ifname, "3.2"); 12109 } else { 12110 send_resp(dut, conn, SIGMA_ERROR, 12111 "errorCode,Unsupported Trig_ComInfo_GI-LTF"); 12112 return STATUS_SENT_ERROR; 12113 } 12114 } 12115 12116 val = get_param(cmd, "Trig_ComInfo_BW"); 12117 if (val) { 12118 int chwidth; 12119 12120 chwidth = atoi(val); 12121 /* Set the channel width */ 12122 run_iwpriv(dut, ifname, "chwidth %d", chwidth); 12123 } 12124 12125 val = get_param(cmd, "NumSS"); 12126 if (val) { 12127 int i = 0; 12128 char *numss_val; 12129 char *saveptr; 12130 12131 num_ss = strdup(val); 12132 if (!num_ss) 12133 return ERROR_SEND_STATUS; 12134 12135 numss_val = strtok_r(num_ss, " ", &saveptr); 12136 for (i = 0; numss_val && i < 4; i++) { 12137 nss[i] = numss_val; 12138 numss_val = strtok_r(NULL, " ", &saveptr); 12139 } 12140 } 12141 12142 val = get_param(cmd, "NumSS_MAC"); 12143 if (val) { 12144 char *sta_mac_str; 12145 char *saveptr; 12146 char *sta_mac_list_str; 12147 12148 sta_mac_list_str = strdup(val); 12149 if (!sta_mac_list_str) { 12150 free(num_ss); 12151 return ERROR_SEND_STATUS; 12152 } 12153 12154 sta_mac_str = strtok_r(sta_mac_list_str, " ", &saveptr); 12155 if (sta_mac_str && nss[0]) { 12156 run_system_wrapper(dut, 12157 "wifitool %s chmask_persta %s %s", 12158 ifname, sta_mac_str, nss[0]); 12159 } 12160 12161 sta_mac_str = strtok_r(NULL, " ", &saveptr); 12162 if (sta_mac_str && nss[1]) { 12163 run_system_wrapper(dut, 12164 "wifitool %s chmask_persta %s %s", 12165 ifname, sta_mac_str, nss[1]); 12166 } 12167 12168 sta_mac_str = strtok_r(NULL, " ", &saveptr); 12169 if (sta_mac_str && nss[2]) { 12170 run_system_wrapper(dut, 12171 "wifitool %s chmask_persta %s %s", 12172 ifname, sta_mac_str, nss[2]); 12173 } 12174 12175 sta_mac_str = strtok_r(NULL, " ", &saveptr); 12176 if (sta_mac_str && nss[3]) { 12177 run_system_wrapper(dut, 12178 "wifitool %s chmask_persta %s %s", 12179 ifname, sta_mac_str, nss[3]); 12180 } 12181 12182 free(sta_mac_list_str); 12183 } 12184 12185 free(num_ss); 12186 num_ss = NULL; 12187 12188 val = get_param(cmd, "AID"); 12189 if (val) { 12190 int i = 0; 12191 char *aid_val; 12192 char *saveptr; 12193 12194 aid_ss = strdup(val); 12195 if (!aid_ss) 12196 return ERROR_SEND_STATUS; 12197 12198 aid_val = strtok_r(aid_ss, " ", &saveptr); 12199 for (i = 0; aid_val && i < 4; i++) { 12200 aid[i] = aid_val; 12201 aid_val = strtok_r(NULL, " ", &saveptr); 12202 } 12203 } 12204 12205 val = get_param(cmd, "AddbaReq"); 12206 if (val) { 12207 if (strcasecmp(val, "enable") == 0) { 12208 run_iwpriv(dut, ifname, "setaddbaoper 1"); 12209 run_system_wrapper(dut, 12210 "wifitool %s sendaddba %s 0 64", 12211 ifname, aid[0]); 12212 } else { 12213 send_resp(dut, conn, SIGMA_ERROR, 12214 "errorCode,Unsupported AddbaReq value"); 12215 free(aid_ss); 12216 return STATUS_SENT_ERROR; 12217 } 12218 } 12219 12220 val = get_param(cmd, "AddbaResp"); 12221 if (val) { 12222 if (aid_ss && strcasecmp(val, "accepted") == 0) { 12223 int aid_1 = atoi(aid_ss); 12224 12225 if (aid_1 == 1) 12226 aid_1 = 2; 12227 else 12228 aid_1 = aid_1 - 1; 12229 12230 /* There is no mechanism in place to reject Add BA Req 12231 * from all STAs and selectively accept Add BA Req from 12232 * a specified STA. Instead, it can accept Add BA Req 12233 * from all STAs and selectively reject from specified 12234 * STAs. Make changes for the same using the below 12235 * commands. */ 12236 run_system_wrapper(dut, ifname, "setaddbaoper 1"); 12237 run_system_wrapper(dut, "wifitool %s refusealladdbas 0", 12238 ifname); 12239 run_system_wrapper(dut, 12240 "wifitool %s setaddbaresp %d 0 37", 12241 ifname, aid_1); 12242 } else { 12243 send_resp(dut, conn, SIGMA_ERROR, 12244 "errorCode,Unsupported Addbaresp value"); 12245 free(aid_ss); 12246 return STATUS_SENT_ERROR; 12247 } 12248 } 12249 12250 val = get_param(cmd, "Trig_UsrInfo_SSAlloc_RA-RU"); 12251 if (val) { 12252 char *ssalloc_str; 12253 char *saveptr; 12254 char *ssalloc_list_str; 12255 12256 ssalloc_list_str = strdup(val); 12257 if (!ssalloc_list_str) { 12258 free(aid_ss); 12259 return ERROR_SEND_STATUS; 12260 } 12261 12262 ssalloc_str = strtok_r(ssalloc_list_str, ":", &saveptr); 12263 if (ssalloc_str && aid[0]) { 12264 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12265 ifname, aid[0], ssalloc_str); 12266 } 12267 12268 ssalloc_str = strtok_r(NULL, " ", &saveptr); 12269 if (ssalloc_str && aid[1]) { 12270 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12271 ifname, aid[1], ssalloc_str); 12272 } 12273 12274 ssalloc_str = strtok_r(NULL, " ", &saveptr); 12275 if (ssalloc_str && aid[2]) { 12276 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12277 ifname, aid[2], ssalloc_str); 12278 } 12279 12280 ssalloc_str = strtok_r(NULL, " ", &saveptr); 12281 if (ssalloc_str && aid[3]) { 12282 run_system_wrapper(dut, "wifitool %s peer_nss %s %s", 12283 ifname, aid[3], ssalloc_str); 12284 } 12285 12286 free(ssalloc_list_str); 12287 } 12288 12289 free(aid_ss); 12290 aid_ss = NULL; 12291 12292 val = get_param(cmd, "OMCtrl_RxNSS"); 12293 if (val) 12294 omctrl_rxnss = atoi(val); 12295 12296 val = get_param(cmd, "OMCtrl_ChnlWidth"); 12297 if (val) 12298 omctrl_chwidth = atoi(val); 12299 12300 val = get_param(cmd, "Client_mac"); 12301 if (val) { 12302 if (parse_mac_address(dut, val, mac_addr) < 0) { 12303 send_resp(dut, conn, SIGMA_ERROR, 12304 "errorCode,MAC Address not in proper format"); 12305 return STATUS_SENT_ERROR; 12306 } 12307 12308 /* setUnitTestCmd 13 7 1 mac3mac2mac1mac0 mac5mac4 <rx_nss> 12309 * <bw> <ulmu> <tx_nss> */ 12310 run_system_wrapper(dut, 12311 "wifitool %s setUnitTestCmd 13 7 1 0x%02x%02x%02x%02x 0x%02x%02x %d %d 1 %d", 12312 ifname, mac_addr[3], mac_addr[2], 12313 mac_addr[1], mac_addr[0], mac_addr[5], 12314 mac_addr[4], omctrl_rxnss, 12315 omctrl_chwidth, omctrl_rxnss); 12316 } 12317 12318 val = get_param(cmd, "TriggerType"); 12319 if (val) { 12320 trigtype = atoi(val); 12321 switch (trigtype) { 12322 case 0: 12323 ath_set_trigger_type_0(dut, ifname); 12324 break; 12325 case 1: 12326 ath_set_trigger_type_1(dut, ifname); 12327 break; 12328 case 2: 12329 ath_set_trigger_type_2(dut, ifname); 12330 break; 12331 case 3: 12332 ath_set_trigger_type_3(dut, ifname); 12333 break; 12334 case 4: 12335 ath_set_trigger_type_4(dut, ifname, basedev); 12336 break; 12337 default: 12338 send_resp(dut, conn, SIGMA_ERROR, 12339 "errorCode,TriggerType not supported"); 12340 return STATUS_SENT_ERROR; 12341 } 12342 } 12343 12344 val = get_param(cmd, "HE_TXOPDurRTSThr"); 12345 if (val) 12346 run_iwpriv(dut, ifname, "he_rtsthrshld %d", atoi(val)); 12347 12348 val = get_param(cmd, "NAV_Update"); 12349 if (val) { 12350 if (strcasecmp(val, "disable") == 0) { 12351 run_iwpriv(dut, basedev, "nav_config 1 0"); 12352 } else if (strcasecmp(val, "enable") == 0) { 12353 /* Do nothing */ 12354 } else { 12355 send_resp(dut, conn, SIGMA_ERROR, 12356 "errorCode,Unsupported NAV update"); 12357 return STATUS_SENT_ERROR; 12358 } 12359 } 12360 12361 /* Configure WMM Parameter Elements */ 12362 val = get_param(cmd, "STA_WMMPE_ECWmin_BE"); 12363 if (val) { 12364 param = atoi(val); 12365 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BE, param); 12366 } 12367 12368 val = get_param(cmd, "STA_WMMPE_ECWmin_BK"); 12369 if (val) { 12370 param = atoi(val); 12371 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_BK, param); 12372 } 12373 12374 val = get_param(cmd, "STA_WMMPE_ECWmin_VI"); 12375 if (val) { 12376 param = atoi(val); 12377 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VI, param); 12378 } 12379 12380 val = get_param(cmd, "STA_WMMPE_ECWmin_VO"); 12381 if (val) { 12382 param = atoi(val); 12383 run_iwpriv(dut, ifname, "cwmin %d 1 %d", AP_AC_VO, param); 12384 } 12385 12386 val = get_param(cmd, "STA_WMMPE_ECWmax_BE"); 12387 if (val) { 12388 param = atoi(val); 12389 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BE, param); 12390 } 12391 12392 val = get_param(cmd, "STA_WMMPE_ECWmax_BK"); 12393 if (val) { 12394 param = atoi(val); 12395 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_BK, param); 12396 } 12397 12398 val = get_param(cmd, "STA_WMMPE_ECWmax_VI"); 12399 if (val) { 12400 param = atoi(val); 12401 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VI, param); 12402 } 12403 12404 val = get_param(cmd, "STA_WMMPE_ECWmax_VO"); 12405 if (val) { 12406 param = atoi(val); 12407 run_iwpriv(dut, ifname, "cwmax %d 1 %d", AP_AC_VO, param); 12408 } 12409 12410 val = get_param(cmd, "STA_WMMPE_AIFSN_BE"); 12411 if (val) { 12412 param = atoi(val); 12413 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BE, param); 12414 } 12415 12416 val = get_param(cmd, "STA_WMMPE_AIFSN_BK"); 12417 if (val) { 12418 param = atoi(val); 12419 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_BK, param); 12420 } 12421 12422 val = get_param(cmd, "STA_WMMPE_AIFSN_VI"); 12423 if (val) { 12424 param = atoi(val); 12425 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VI, param); 12426 } 12427 12428 val = get_param(cmd, "STA_WMMPE_AIFSN_VO"); 12429 if (val) { 12430 param = atoi(val); 12431 run_iwpriv(dut, ifname, "aifs %d 1 %d", AP_AC_VO, param); 12432 } 12433 12434 12435 val = get_param(cmd, "STA_WMMPE_TXOP_BE"); 12436 if (val) { 12437 param = atoi(val); 12438 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BE, param); 12439 } 12440 12441 val = get_param(cmd, "STA_WMMPE_TOXP_BK"); 12442 if (val) { 12443 param = atoi(val); 12444 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_BK, param); 12445 } 12446 12447 val = get_param(cmd, "STA_WMMPE_TXOP_VI"); 12448 if (val) { 12449 param = atoi(val); 12450 run_iwpriv(dut, ifname, "txoplimit %d %d", AP_AC_VI, param); 12451 } 12452 12453 val = get_param(cmd, "STA_WMMPE_TXOP_VO"); 12454 if (val) { 12455 param = atoi(val); 12456 run_iwpriv(dut, ifname, "txoplimit %d 1 %d", AP_AC_VO, param); 12457 } 12458 12459 /* Configure MU EDCA */ 12460 val = get_param(cmd, "STA_MUEDCA_ECWmin_BE"); 12461 if (val) { 12462 param = atoi(val); 12463 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BE, param); 12464 } 12465 12466 val = get_param(cmd, "STA_MUEDCA_ECWmin_BK"); 12467 if (val) { 12468 param = atoi(val); 12469 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_BK, param); 12470 } 12471 12472 val = get_param(cmd, "STA_MUEDCA_ECWmin_VI"); 12473 if (val) { 12474 param = atoi(val); 12475 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VI, param); 12476 } 12477 12478 val = get_param(cmd, "STA_MUEDCA_ECWmin_VO"); 12479 if (val) { 12480 param = atoi(val); 12481 run_iwpriv(dut, ifname, "muedca_ecwmin %d %d", AP_AC_VO, param); 12482 } 12483 12484 val = get_param(cmd, "STA_MUEDCA_ECWmax_BE"); 12485 if (val) { 12486 param = atoi(val); 12487 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BE, param); 12488 } 12489 12490 val = get_param(cmd, "STA_MUEDCA_ECWmax_BK"); 12491 if (val) { 12492 param = atoi(val); 12493 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_BK, param); 12494 } 12495 12496 val = get_param(cmd, "STA_MUEDCA_ECWmax_VI"); 12497 if (val) { 12498 param = atoi(val); 12499 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VI, param); 12500 } 12501 12502 val = get_param(cmd, "STA_MUEDCA_ECWmax_VO"); 12503 if (val) { 12504 param = atoi(val); 12505 run_iwpriv(dut, ifname, "muedca_ecwmax %d %d", AP_AC_VO, param); 12506 } 12507 12508 val = get_param(cmd, "STA_MUEDCA_AIFSN_BE"); 12509 if (val) { 12510 param = atoi(val); 12511 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BE, param); 12512 } 12513 12514 val = get_param(cmd, "STA_MUEDCA_AIFSN_BK"); 12515 if (val) { 12516 param = atoi(val); 12517 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_BK, param); 12518 } 12519 12520 val = get_param(cmd, "STA_MUEDCA_AIFSN_VI"); 12521 if (val) { 12522 param = atoi(val); 12523 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VI, param); 12524 } 12525 12526 val = get_param(cmd, "STA_MUEDCA_AIFSN_VO"); 12527 if (val) { 12528 param = atoi(val); 12529 run_iwpriv(dut, ifname, "muedca_aifsn %d %d", AP_AC_VO, param); 12530 } 12531 12532 val = get_param(cmd, "STA_MUEDCA_Timer_BE"); 12533 if (val) { 12534 param = atoi(val); 12535 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BE, param); 12536 } 12537 12538 val = get_param(cmd, "STA_MUEDCA_Timer_BK"); 12539 if (val) { 12540 param = atoi(val); 12541 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_BK, param); 12542 } 12543 12544 val = get_param(cmd, "STA_MUEDCA_Timer_VI"); 12545 if (val) { 12546 param = atoi(val); 12547 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VI, param); 12548 } 12549 12550 val = get_param(cmd, "STA_MUEDCA_Timer_VO"); 12551 if (val) { 12552 param = atoi(val); 12553 run_iwpriv(dut, ifname, "muedca_timer %d %d", AP_AC_VO, param); 12554 } 12555 12556 return SUCCESS_SEND_STATUS; 12557 } 12558 12559 12560 static int wcn_vht_chnum_band(struct sigma_dut *dut, const char *ifname, 12561 const char *val) 12562 { 12563 char *token, *result; 12564 int channel = 36; 12565 char *saveptr; 12566 12567 /* Extract the channel info */ 12568 token = strdup(val); 12569 if (!token) 12570 return -1; 12571 result = strtok_r(token, ";", &saveptr); 12572 if (result) 12573 channel = atoi(result); 12574 12575 /* Issue the channel switch command */ 12576 run_iwpriv(dut, ifname, "setChanChange %d", channel); 12577 12578 free(token); 12579 return 0; 12580 } 12581 12582 12583 static enum sigma_cmd_result wcn_ap_set_rfeature(struct sigma_dut *dut, 12584 struct sigma_conn *conn, 12585 struct sigma_cmd *cmd) 12586 { 12587 const char *val; 12588 const char *ifname; 12589 12590 ifname = get_main_ifname(dut); 12591 12592 val = get_param(cmd, "chnum_band"); 12593 if (val && wcn_vht_chnum_band(dut, ifname, val) < 0) 12594 return ERROR_SEND_STATUS; 12595 12596 val = get_param(cmd, "txBandwidth"); 12597 if (val) { 12598 int old_ch_bw = dut->ap_chwidth; 12599 12600 if (strcasecmp(val, "Auto") == 0) { 12601 dut->ap_chwidth = 0; 12602 } else if (strcasecmp(val, "20") == 0) { 12603 dut->ap_chwidth = 0; 12604 } else if (strcasecmp(val, "40") == 0) { 12605 dut->ap_chwidth = 1; 12606 } else if (strcasecmp(val, "80") == 0) { 12607 dut->ap_chwidth = 2; 12608 } else if (strcasecmp(val, "160") == 0) { 12609 dut->ap_chwidth = 3; 12610 } else { 12611 send_resp(dut, conn, SIGMA_ERROR, 12612 "ErrorCode,WIDTH not supported"); 12613 return STATUS_SENT_ERROR; 12614 } 12615 if (old_ch_bw != dut->ap_chwidth) { 12616 if (cmd_ap_config_commit(dut, conn, cmd) <= 0) 12617 return STATUS_SENT_ERROR; 12618 } else { 12619 sigma_dut_print(dut, DUT_MSG_DEBUG, "No change in BW"); 12620 } 12621 } 12622 12623 val = get_param(cmd, "GI"); 12624 if (val) { 12625 int fix_rate_sgi; 12626 12627 if (strcmp(val, "0.8") == 0) { 12628 run_iwpriv(dut, ifname, "enable_short_gi 9"); 12629 fix_rate_sgi = 1; 12630 } else if (strcmp(val, "1.6") == 0) { 12631 run_iwpriv(dut, ifname, "enable_short_gi 10"); 12632 fix_rate_sgi = 2; 12633 } else if (strcmp(val, "3.2") == 0) { 12634 run_iwpriv(dut, ifname, "enable_short_gi 11"); 12635 fix_rate_sgi = 3; 12636 } else { 12637 send_resp(dut, conn, SIGMA_ERROR, 12638 "errorCode,GI value not supported"); 12639 return STATUS_SENT_ERROR; 12640 } 12641 run_iwpriv(dut, ifname, "enable_short_gi %d", fix_rate_sgi); 12642 } 12643 12644 val = get_param(cmd, "LTF"); 12645 if (val) { 12646 #ifdef NL80211_SUPPORT 12647 if (strcmp(val, "3.2") == 0) { 12648 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_1X); 12649 } if (strcmp(val, "6.4") == 0) { 12650 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_2X); 12651 } else if (strcmp(val, "12.8") == 0) { 12652 wcn_set_he_ltf(dut, ifname, QCA_WLAN_HE_LTF_4X); 12653 } else { 12654 send_resp(dut, conn, SIGMA_ERROR, 12655 "errorCode,LTF value not supported"); 12656 return STATUS_SENT; 12657 } 12658 #else /* NL80211_SUPPORT */ 12659 sigma_dut_print(dut, DUT_MSG_ERROR, 12660 "LTF cannot be set without NL80211_SUPPORT defined"); 12661 return ERROR_SEND_STATUS; 12662 #endif /* NL80211_SUPPORT */ 12663 } 12664 12665 return SUCCESS_SEND_STATUS; 12666 } 12667 12668 12669 static int mac80211_vht_chnum_band(struct sigma_dut *dut, const char *ifname, 12670 const char *val) 12671 { 12672 char *token, *result; 12673 int channel = 36, chwidth = 80, center_freq_idx, center_freq, 12674 channel_freq; 12675 char buf[100]; 12676 char *saveptr; 12677 int res; 12678 12679 /* Extract the channel info */ 12680 token = strdup(val); 12681 if (!token) 12682 return -1; 12683 result = strtok_r(token, ";", &saveptr); 12684 if (result) 12685 channel = atoi(result); 12686 12687 /* Extract the channel width info */ 12688 result = strtok_r(NULL, ";", &saveptr); 12689 if (result) 12690 chwidth = atoi(result); 12691 12692 center_freq_idx = get_oper_centr_freq_seq_idx(chwidth, channel); 12693 if (center_freq_idx < 0) { 12694 free(token); 12695 return -1; 12696 } 12697 12698 center_freq = get_5g_channel_freq(center_freq_idx); 12699 channel_freq = get_5g_channel_freq(channel); 12700 12701 /* Issue the channel switch command */ 12702 res = snprintf(buf, sizeof(buf), 12703 " -i %s chan_switch 10 %d sec_channel_offset=1 center_freq1=%d bandwidth=%d blocktx vht", 12704 ifname, channel_freq, center_freq, chwidth); 12705 if (res < 0 || res >= sizeof(buf) || run_hostapd_cli(dut, buf) != 0) { 12706 sigma_dut_print(dut, DUT_MSG_ERROR, 12707 "hostapd_cli chan_switch failed"); 12708 } 12709 12710 free(token); 12711 return 0; 12712 } 12713 12714 12715 static int mac80211_ap_set_rfeature(struct sigma_dut *dut, 12716 struct sigma_conn *conn, 12717 struct sigma_cmd *cmd) 12718 { 12719 const char *val; 12720 const char *ifname; 12721 12722 ifname = get_main_ifname(dut); 12723 12724 val = get_param(cmd, "RTS_FORCE"); 12725 if (val) 12726 mac80211_config_rts_force(dut, ifname, val); 12727 12728 val = get_param(cmd, "chnum_band"); 12729 if (val && mac80211_vht_chnum_band(dut, ifname, val) < 0) 12730 return -1; 12731 12732 return 1; 12733 } 12734 12735 12736 #ifdef __linux__ 12737 static int wil6210_ap_set_rfeature(struct sigma_dut *dut, 12738 struct sigma_conn *conn, 12739 struct sigma_cmd *cmd) 12740 { 12741 const char *val; 12742 12743 val = get_param(cmd, "ExtSchIE"); 12744 if (val && !strcasecmp(val, "Enable")) { 12745 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS]; 12746 int count = MAX_ESE_ALLOCS; 12747 12748 if (sta_extract_60g_ese(dut, cmd, allocs, &count)) 12749 return -1; 12750 if (wil6210_set_ese(dut, count, allocs)) 12751 return -1; 12752 return 1; 12753 } 12754 12755 send_resp(dut, conn, SIGMA_ERROR, 12756 "errorCode,Invalid ap_set_rfeature(60G)"); 12757 return 0; 12758 } 12759 #endif /* __linux__ */ 12760 12761 12762 static enum sigma_cmd_result cmd_ap_set_rfeature(struct sigma_dut *dut, 12763 struct sigma_conn *conn, 12764 struct sigma_cmd *cmd) 12765 { 12766 /* const char *name = get_param(cmd, "NAME"); */ 12767 /* const char *type = get_param(cmd, "Type"); */ 12768 const char *val, *oci_chan, *oci_frametype; 12769 char buf[100]; 12770 const char *ifname = get_hostapd_ifname(dut); 12771 12772 val = get_param(cmd, "ReassocResp_RSNXE_Used"); 12773 if (val) { 12774 if (atoi(val) == 0) 12775 snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 2"); 12776 else 12777 snprintf(buf, sizeof(buf), "SET ft_rsnxe_used 1"); 12778 if (hapd_command(ifname, buf) < 0) { 12779 send_resp(dut, conn, SIGMA_ERROR, 12780 "ErrorCode,Failed to set ft_rsnxe_used"); 12781 return STATUS_SENT_ERROR; 12782 } 12783 } 12784 12785 oci_chan = get_param(cmd, "OCIChannel"); 12786 oci_frametype = get_param(cmd, "OCIFrameType"); 12787 if (oci_chan && oci_frametype) { 12788 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan)); 12789 12790 if (!oci_freq) { 12791 send_resp(dut, conn, SIGMA_ERROR, 12792 "errorCode,Invalid OCIChannel number"); 12793 return STATUS_SENT_ERROR; 12794 } 12795 12796 if (strcasecmp(oci_frametype, "eapolM3") == 0) { 12797 snprintf(buf, sizeof(buf), 12798 "SET oci_freq_override_eapol_m3 %d", oci_freq); 12799 } else if (strcasecmp(oci_frametype, "eapolG1") == 0) { 12800 snprintf(buf, sizeof(buf), 12801 "SET oci_freq_override_eapol_g1 %d", oci_freq); 12802 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) { 12803 snprintf(buf, sizeof(buf), 12804 "SET oci_freq_override_saquery_req %d", 12805 oci_freq); 12806 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) { 12807 snprintf(buf, sizeof(buf), 12808 "SET oci_freq_override_saquery_resp %d", 12809 oci_freq); 12810 } else { 12811 send_resp(dut, conn, SIGMA_ERROR, 12812 "errorCode,Unsupported OCIFrameType"); 12813 return STATUS_SENT_ERROR; 12814 } 12815 if (hapd_command(ifname, buf) < 0) { 12816 send_resp(dut, conn, SIGMA_ERROR, 12817 "errorCode,Failed to set oci_freq_override"); 12818 return STATUS_SENT_ERROR; 12819 } 12820 return SUCCESS_SEND_STATUS; 12821 } 12822 12823 switch (get_driver_type(dut)) { 12824 case DRIVER_ATHEROS: 12825 return ath_ap_set_rfeature(dut, conn, cmd); 12826 case DRIVER_OPENWRT: 12827 switch (get_openwrt_driver_type()) { 12828 case OPENWRT_DRIVER_ATHEROS: 12829 return ath_ap_set_rfeature(dut, conn, cmd); 12830 default: 12831 send_resp(dut, conn, SIGMA_ERROR, 12832 "errorCode,Unsupported ap_set_rfeature with the current openwrt driver"); 12833 return 0; 12834 } 12835 case DRIVER_LINUX_WCN: 12836 case DRIVER_WCN: 12837 return wcn_ap_set_rfeature(dut, conn, cmd); 12838 case DRIVER_MAC80211: 12839 return mac80211_ap_set_rfeature(dut, conn, cmd); 12840 #ifdef __linux__ 12841 case DRIVER_WIL6210: 12842 return wil6210_ap_set_rfeature(dut, conn, cmd); 12843 #endif /* __linux__ */ 12844 default: 12845 send_resp(dut, conn, SIGMA_ERROR, 12846 "errorCode,Unsupported ap_set_rfeature with the current driver"); 12847 return 0; 12848 } 12849 } 12850 12851 12852 static enum sigma_cmd_result cmd_accesspoint(struct sigma_dut *dut, 12853 struct sigma_conn *conn, 12854 struct sigma_cmd *cmd) 12855 { 12856 /* const char *name = get_param(cmd, "NAME"); */ 12857 return 1; 12858 } 12859 12860 12861 static enum sigma_cmd_result 12862 cmd_ap_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn, 12863 struct sigma_cmd *cmd) 12864 { 12865 const char *val; 12866 12867 val = get_param(cmd, "Oper_Chn"); 12868 if (val) { 12869 dut->ap_oper_chn = 1; 12870 dut->ap_channel = atoi(val); 12871 } 12872 12873 val = get_param(cmd, "DPPConfiguratorAddress"); 12874 if (val) { 12875 free(dut->ap_dpp_conf_addr); 12876 dut->ap_dpp_conf_addr = strdup(val); 12877 } 12878 12879 val = get_param(cmd, "DPPConfiguratorPKHash"); 12880 if (val) { 12881 free(dut->ap_dpp_conf_pkhash); 12882 dut->ap_dpp_conf_pkhash = strdup(val); 12883 } 12884 12885 return 1; 12886 } 12887 12888 12889 void ap_register_cmds(void) 12890 { 12891 sigma_dut_reg_cmd("ap_ca_version", NULL, cmd_ap_ca_version); 12892 sigma_dut_reg_cmd("ap_set_wireless", NULL, cmd_ap_set_wireless); 12893 sigma_dut_reg_cmd("ap_send_addba_req", NULL, cmd_ap_send_addba_req); 12894 sigma_dut_reg_cmd("ap_set_11n_wireless", NULL, cmd_ap_set_wireless); 12895 sigma_dut_reg_cmd("ap_set_11n", NULL, cmd_ap_set_wireless); 12896 sigma_dut_reg_cmd("ap_set_11d", NULL, cmd_ap_set_wireless); 12897 sigma_dut_reg_cmd("ap_set_11h", NULL, cmd_ap_set_wireless); 12898 sigma_dut_reg_cmd("ap_set_security", NULL, cmd_ap_set_security); 12899 sigma_dut_reg_cmd("ap_set_apqos", NULL, cmd_ap_set_apqos); 12900 sigma_dut_reg_cmd("ap_set_staqos", NULL, cmd_ap_set_staqos); 12901 sigma_dut_reg_cmd("ap_set_radius", NULL, cmd_ap_set_radius); 12902 sigma_dut_reg_cmd("ap_reboot", NULL, cmd_ap_reboot); 12903 sigma_dut_reg_cmd("ap_config_commit", NULL, cmd_ap_config_commit); 12904 sigma_dut_reg_cmd("ap_reset_default", NULL, cmd_ap_reset_default); 12905 sigma_dut_reg_cmd("ap_get_info", NULL, cmd_ap_get_info); 12906 sigma_dut_reg_cmd("ap_deauth_sta", NULL, cmd_ap_deauth_sta); 12907 sigma_dut_reg_cmd("ap_send_frame", NULL, cmd_ap_send_frame); 12908 sigma_dut_reg_cmd("ap_get_mac_address", NULL, cmd_ap_get_mac_address); 12909 sigma_dut_reg_cmd("ap_set_pmf", NULL, cmd_ap_set_pmf); 12910 sigma_dut_reg_cmd("ap_set_hs2", NULL, cmd_ap_set_hs2); 12911 sigma_dut_reg_cmd("ap_set_rfeature", NULL, cmd_ap_set_rfeature); 12912 sigma_dut_reg_cmd("ap_nfc_action", NULL, cmd_ap_nfc_action); 12913 sigma_dut_reg_cmd("ap_wps_read_pin", NULL, cmd_ap_wps_read_pin); 12914 sigma_dut_reg_cmd("ap_wps_enter_pin", NULL, cmd_ap_wps_enter_pin); 12915 sigma_dut_reg_cmd("ap_wps_set_pbc", NULL, cmd_ap_wps_set_pbc); 12916 sigma_dut_reg_cmd("ap_get_parameter", NULL, cmd_ap_get_parameter); 12917 sigma_dut_reg_cmd("AccessPoint", NULL, cmd_accesspoint); 12918 sigma_dut_reg_cmd("ap_preset_testparameters", NULL, 12919 cmd_ap_preset_testparameters); 12920 } 12921