1 /* 2 * Sigma Control API DUT (station/AP/sniffer) 3 * Copyright (c) 2011-2013, 2017, Qualcomm Atheros, Inc. 4 * Copyright (c) 2018-2019, The Linux Foundation 5 * All Rights Reserved. 6 * Licensed under the Clear BSD license. See README for more details. 7 */ 8 9 #include "sigma_dut.h" 10 #include <ctype.h> 11 #include "miracast.h" 12 #include <sys/wait.h> 13 #include "wpa_ctrl.h" 14 #include "wpa_helpers.h" 15 16 17 extern char *sigma_cert_path; 18 19 20 static enum sigma_cmd_result cmd_dev_send_frame(struct sigma_dut *dut, 21 struct sigma_conn *conn, 22 struct sigma_cmd *cmd) 23 { 24 #ifdef MIRACAST 25 const char *program = get_param(cmd, "Program"); 26 27 if (program && (strcasecmp(program, "WFD") == 0 || 28 strcasecmp(program, "DisplayR2") == 0)) 29 return miracast_dev_send_frame(dut, conn, cmd); 30 #endif /* MIRACAST */ 31 32 if (dut->mode == SIGMA_MODE_STATION || 33 dut->mode == SIGMA_MODE_UNKNOWN) { 34 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert " 35 "dev_send_frame to sta_send_frame"); 36 return cmd_sta_send_frame(dut, conn, cmd); 37 } 38 39 if (dut->mode == SIGMA_MODE_AP) { 40 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert " 41 "dev_send_frame to ap_send_frame"); 42 return cmd_ap_send_frame(dut, conn, cmd); 43 } 44 45 #ifdef CONFIG_WLANTEST 46 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert dev_send_frame to " 47 "wlantest_send_frame"); 48 return cmd_wlantest_send_frame(dut, conn, cmd); 49 #else /* CONFIG_WLANTEST */ 50 send_resp(dut, conn, SIGMA_ERROR, 51 "errorCode,Unsupported dev_send_frame"); 52 return STATUS_SENT; 53 #endif /* CONFIG_WLANTEST */ 54 } 55 56 57 static enum sigma_cmd_result cmd_dev_set_parameter(struct sigma_dut *dut, 58 struct sigma_conn *conn, 59 struct sigma_cmd *cmd) 60 { 61 const char *device = get_param(cmd, "Device"); 62 63 if (device && strcasecmp(device, "STA") == 0) { 64 sigma_dut_print(dut, DUT_MSG_DEBUG, "Convert " 65 "dev_set_parameter to sta_set_parameter"); 66 return cmd_sta_set_parameter(dut, conn, cmd); 67 } 68 69 return INVALID_SEND_STATUS; 70 } 71 72 73 static enum sigma_cmd_result sta_server_cert_trust(struct sigma_dut *dut, 74 struct sigma_conn *conn, 75 const char *val) 76 { 77 char buf[200]; 78 struct wpa_ctrl *ctrl = NULL; 79 int e; 80 char resp[200]; 81 int num_disconnected = 0; 82 83 strlcpy(resp, "ServerCertTrustResult,Accepted", sizeof(resp)); 84 85 if (strcasecmp(val, "Accept") != 0 && strcasecmp(val, "Reject") != 0) { 86 sigma_dut_print(dut, DUT_MSG_INFO, 87 "Unknown ServerCertTrust value '%s'", val); 88 return INVALID_SEND_STATUS; 89 } 90 91 snprintf(buf, sizeof(buf), "%s/uosc-disabled", sigma_cert_path); 92 if (file_exists(buf)) { 93 strlcpy(resp, 94 "ServerCertTrustResult,OverrideNotAllowed,Reason,UOSC disabled on device", 95 sizeof(resp)); 96 goto done; 97 } 98 99 if (!dut->server_cert_hash[0]) { 100 strlcpy(resp, 101 "ServerCertTrustResult,OverrideNotAllowed,Reason,No server certificate stored", 102 sizeof(resp)); 103 goto done; 104 } 105 106 if (dut->sta_tod_policy) { 107 strlcpy(resp, 108 "ServerCertTrustResult,OverrideNotAllowed,Reason,TOD policy", 109 sizeof(resp)); 110 goto done; 111 } 112 113 if (dut->server_cert_tod == 1) { 114 strlcpy(resp, 115 "ServerCertTrustResult,OverrideNotAllowed,Reason,TOD-STRICT policy in received server certificate", 116 sizeof(resp)); 117 goto done; 118 } 119 120 if (strcasecmp(val, "Accept") != 0) { 121 strlcpy(resp, "ServerCertTrustResult,Rejected", sizeof(resp)); 122 goto done; 123 } 124 125 snprintf(buf, sizeof(buf), "hash://server/sha256/%s", 126 dut->server_cert_hash); 127 if (set_network_quoted(get_station_ifname(), dut->infra_network_id, 128 "ca_cert", buf) < 0) { 129 strlcpy(resp, 130 "ServerCertTrustResult,OverrideNotAllowed,Reason,Could not configure server certificate hash for the network profile", 131 sizeof(resp)); 132 goto done; 133 } 134 135 if (set_network(get_station_ifname(), dut->infra_network_id, 136 "domain_match", "NULL") < 0 || 137 set_network(get_station_ifname(), dut->infra_network_id, 138 "domain_suffix_match", "NULL") < 0) { 139 strlcpy(resp, 140 "ServerCertTrustResult,OverrideNotAllowed,Reason,Could not clear domain matching rules", 141 sizeof(resp)); 142 goto done; 143 } 144 145 wpa_command(get_station_ifname(), "DISCONNECT"); 146 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", dut->infra_network_id); 147 if (wpa_command(get_station_ifname(), buf) < 0) { 148 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select " 149 "network id %d on %s", 150 dut->infra_network_id, 151 get_station_ifname()); 152 strlcpy(resp, 153 "ServerCertTrustResult,Accepted,Result,Could not request reconnection", 154 sizeof(resp)); 155 goto done; 156 } 157 158 ctrl = open_wpa_mon(get_station_ifname()); 159 if (!ctrl) 160 goto done; 161 162 for (e = 0; e < 20; e++) { 163 const char *events[] = { 164 "CTRL-EVENT-EAP-TLS-CERT-ERROR", 165 "CTRL-EVENT-DISCONNECTED", 166 "CTRL-EVENT-CONNECTED", 167 NULL 168 }; 169 char buf[1024]; 170 int res; 171 172 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf)); 173 if (res < 0) { 174 strlcpy(resp, 175 "ServerCertTrustResult,Accepted,Result,Association did not complete", 176 sizeof(resp)); 177 goto done; 178 } 179 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s", 180 buf); 181 182 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) { 183 strlcpy(resp, 184 "ServerCertTrustResult,Accepted,Result,TLS server certificate validation failed with updated profile", 185 sizeof(resp)); 186 goto done; 187 } 188 189 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) { 190 num_disconnected++; 191 192 if (num_disconnected > 2) { 193 strlcpy(resp, 194 "ServerCertTrustResult,Accepted,Result,Connection failed", 195 sizeof(resp)); 196 goto done; 197 } 198 } 199 200 if (strstr(buf, "CTRL-EVENT-CONNECTED")) { 201 strlcpy(resp, 202 "ServerCertTrustResult,Accepted,Result,Connected", 203 sizeof(resp)); 204 break; 205 } 206 } 207 208 done: 209 if (ctrl) { 210 wpa_ctrl_detach(ctrl); 211 wpa_ctrl_close(ctrl); 212 } 213 214 send_resp(dut, conn, SIGMA_COMPLETE, resp); 215 return STATUS_SENT; 216 } 217 218 219 static enum sigma_cmd_result cmd_dev_exec_action(struct sigma_dut *dut, 220 struct sigma_conn *conn, 221 struct sigma_cmd *cmd) 222 { 223 const char *program = get_param(cmd, "Program"); 224 const char *val; 225 226 #ifdef MIRACAST 227 if (program && (strcasecmp(program, "WFD") == 0 || 228 strcasecmp(program, "DisplayR2") == 0)) { 229 if (get_param(cmd, "interface") == NULL) 230 return INVALID_SEND_STATUS; 231 return miracast_dev_exec_action(dut, conn, cmd); 232 } 233 #endif /* MIRACAST */ 234 235 if (program && strcasecmp(program, "DPP") == 0) 236 return dpp_dev_exec_action(dut, conn, cmd); 237 238 val = get_param(cmd, "ServerCertTrust"); 239 if (val) 240 return sta_server_cert_trust(dut, conn, val); 241 242 return ERROR_SEND_STATUS; 243 } 244 245 246 static enum sigma_cmd_result cmd_dev_configure_ie(struct sigma_dut *dut, 247 struct sigma_conn *conn, 248 struct sigma_cmd *cmd) 249 { 250 const char *ie_name = get_param(cmd, "IE_Name"); 251 const char *contents = get_param(cmd, "Contents"); 252 253 if (!ie_name || !contents) 254 return INVALID_SEND_STATUS; 255 256 if (strcasecmp(ie_name, "RSNE") != 0) { 257 send_resp(dut, conn, SIGMA_ERROR, 258 "errorCode,Unsupported IE_Name value"); 259 return STATUS_SENT; 260 } 261 262 free(dut->rsne_override); 263 dut->rsne_override = strdup(contents); 264 265 return dut->rsne_override ? SUCCESS_SEND_STATUS : ERROR_SEND_STATUS; 266 } 267 268 269 static enum sigma_cmd_result cmd_dev_ble_action(struct sigma_dut *dut, 270 struct sigma_conn *conn, 271 struct sigma_cmd *cmd) 272 { 273 #ifdef ANDROID 274 const char *ble_op = get_param(cmd, "BLEOp"); 275 const char *prog = get_param(cmd, "Prog"); 276 const char *service_name = get_param(cmd, "ServiceName"); 277 const char *ble_role = get_param(cmd, "BLERole"); 278 const char *discovery_type = get_param(cmd, "DiscoveryType"); 279 const char *msg_type = get_param(cmd, "messagetype"); 280 const char *action = get_param(cmd, "action"); 281 const char *M2Transmit = get_param(cmd, "M2Transmit"); 282 char *argv[17]; 283 pid_t pid; 284 285 if (prog && ble_role && action && msg_type) { 286 send_resp(dut, conn, SIGMA_COMPLETE, 287 "OrgID,0x00,TransDataHeader,0x00,BloomFilterElement,NULL"); 288 return STATUS_SENT; 289 } 290 if (!ble_op || !prog || !service_name || !ble_role || !discovery_type) { 291 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid arguments"); 292 return INVALID_SEND_STATUS; 293 } 294 295 if ((strcasecmp(prog, "NAN") != 0)) { 296 sigma_dut_print(dut, DUT_MSG_ERROR, "Program %s not supported", 297 prog); 298 return INVALID_SEND_STATUS; 299 } 300 301 if (strcasecmp(ble_role, "seeker") != 0 && 302 strcasecmp(ble_role, "provider") != 0 && 303 strcasecmp(ble_role, "browser") != 0) { 304 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid BLERole: %s", 305 ble_role); 306 return INVALID_SEND_STATUS; 307 } 308 309 if (strcasecmp(discovery_type, "active") != 0 && 310 strcasecmp(discovery_type, "passive") != 0) { 311 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid DiscoveryType: %s", 312 discovery_type); 313 return INVALID_SEND_STATUS; 314 } 315 316 if (!M2Transmit) 317 M2Transmit = "disable"; 318 319 argv[0] = "am"; 320 argv[1] = "start"; 321 argv[2] = "-n"; 322 argv[3] = "org.codeaurora.nanservicediscovery/org.codeaurora.nanservicediscovery.MainActivity"; 323 argv[4] = "--es"; 324 argv[5] = "service"; 325 argv[6] = (char *) service_name; 326 argv[7] = "--es"; 327 argv[8] = "role"; 328 argv[9] = (char *) ble_role; 329 argv[10] = "--es"; 330 argv[11] = "scantype"; 331 argv[12] = (char *) discovery_type; 332 argv[13] = "--es"; 333 argv[14] = "M2Transmit"; 334 argv[15] = (char *) M2Transmit; 335 argv[16] = NULL; 336 337 pid = fork(); 338 if (pid == -1) { 339 sigma_dut_print(dut, DUT_MSG_ERROR, "fork: %s", 340 strerror(errno)); 341 return ERROR_SEND_STATUS; 342 } 343 344 if (pid == 0) { 345 execv("/system/bin/am", argv); 346 sigma_dut_print(dut, DUT_MSG_ERROR, "execv: %s", 347 strerror(errno)); 348 exit(0); 349 return ERROR_SEND_STATUS; 350 } 351 352 dut->nanservicediscoveryinprogress = 1; 353 #endif /* ANDROID */ 354 355 return SUCCESS_SEND_STATUS; 356 } 357 358 359 /* Runtime ID must contain only numbers */ 360 static int is_runtime_id_valid(struct sigma_dut *dut, const char *val) 361 { 362 int i; 363 364 for (i = 0; val[i] != '\0'; i++) { 365 if (!isdigit(val[i])) { 366 sigma_dut_print(dut, DUT_MSG_DEBUG, 367 "Invalid Runtime_ID %s", val); 368 return 0; 369 } 370 } 371 372 return 1; 373 } 374 375 376 static int build_log_dir(struct sigma_dut *dut, char *dir, size_t dir_size) 377 { 378 int res; 379 const char *vendor = dut->vendor_name; 380 int i; 381 382 if (!vendor) 383 return -1; 384 385 if (dut->log_file_dir) { 386 res = snprintf(dir, dir_size, "%s/%s", dut->log_file_dir, 387 vendor); 388 } else { 389 #ifdef ANDROID 390 res = snprintf(dir, dir_size, "/data/vendor/wifi/%s", 391 vendor); 392 #else /* ANDROID */ 393 res = snprintf(dir, dir_size, "/var/log/%s", vendor); 394 #endif /* ANDROID */ 395 } 396 397 if (res < 0 || res >= dir_size) 398 return -1; 399 400 /* Check for valid vendor name in log dir path since the log dir 401 * (/var/log/vendor) is deleted in dev_stop routine. This check is to 402 * avoid any unintended file deletion. 403 */ 404 for (i = 0; vendor[i] != '\0'; i++) { 405 if (!isalpha(vendor[i])) { 406 sigma_dut_print(dut, DUT_MSG_DEBUG, 407 "Invalid char %c in vendor name %s", 408 vendor[i], vendor); 409 return -1; 410 } 411 } 412 413 return 0; 414 } 415 416 417 /* User has to redirect wpa_supplicant logs to the following file. */ 418 #ifndef WPA_SUPPLICANT_LOG_FILE 419 #define WPA_SUPPLICANT_LOG_FILE "/var/log/supplicant_log/wpa_log.txt" 420 #endif /* WPA_SUPPLICANT_LOG_FILE */ 421 422 static enum sigma_cmd_result cmd_dev_start_test(struct sigma_dut *dut, 423 struct sigma_conn *conn, 424 struct sigma_cmd *cmd) 425 { 426 const char *val; 427 char buf[250]; 428 char dir[200]; 429 FILE *supp_log; 430 int res; 431 432 val = get_param(cmd, "Runtime_ID"); 433 if (!(val && is_runtime_id_valid(dut, val))) 434 return INVALID_SEND_STATUS; 435 436 if (!dut->vendor_name) { 437 sigma_dut_print(dut, DUT_MSG_INFO, 438 "Log collection not supported without vendor name specified on the command line (-N)"); 439 return SUCCESS_SEND_STATUS; 440 } 441 442 if (build_log_dir(dut, dir, sizeof(dir)) < 0) 443 return ERROR_SEND_STATUS; 444 445 supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r"); 446 if (!supp_log) { 447 sigma_dut_print(dut, DUT_MSG_ERROR, 448 "Failed to open wpa_log file %s", 449 WPA_SUPPLICANT_LOG_FILE); 450 } else { 451 /* Get the wpa_supplicant log file size */ 452 if (fseek(supp_log, 0, SEEK_END)) 453 sigma_dut_print(dut, DUT_MSG_ERROR, 454 "Failed to get file size for read"); 455 else 456 dut->wpa_log_size = ftell(supp_log); 457 458 fclose(supp_log); 459 } 460 461 strlcpy(dut->dev_start_test_runtime_id, val, 462 sizeof(dut->dev_start_test_runtime_id)); 463 sigma_dut_print(dut, DUT_MSG_DEBUG, "Runtime_ID %s", 464 dut->dev_start_test_runtime_id); 465 466 run_system_wrapper(dut, "rm -rf %s", dir); 467 run_system_wrapper(dut, "mkdir -p %s", dir); 468 469 #ifdef ANDROID 470 run_system_wrapper(dut, "logcat -v time > %s/logcat_%s.txt &", 471 dir, dut->dev_start_test_runtime_id); 472 #else /* ANDROID */ 473 /* Open log file for sigma_dut logs. This is not needed for Android, as 474 * we are already collecting logcat. */ 475 res = snprintf(buf, sizeof(buf), "%s/sigma_%s.txt", dir, 476 dut->dev_start_test_runtime_id); 477 if (res >= 0 && res < sizeof(buf)) { 478 if (dut->log_file_fd) 479 fclose(dut->log_file_fd); 480 481 dut->log_file_fd = fopen(buf, "a"); 482 if (!dut->log_file_fd) 483 sigma_dut_print(dut, DUT_MSG_ERROR, 484 "Failed to create sigma_dut log %s", 485 buf); 486 } 487 488 run_system_wrapper(dut, "killall -9 cnss_diag_lite"); 489 run_system_wrapper(dut, 490 "cnss_diag_lite -c -x 31 > %s/cnss_diag_id_%s.txt &", 491 dir, dut->dev_start_test_runtime_id); 492 #endif /* ANDROID */ 493 494 return SUCCESS_SEND_STATUS; 495 } 496 497 498 static int is_allowed_char(char ch) 499 { 500 return strchr("./-_", ch) != NULL; 501 } 502 503 504 static int is_destpath_valid(struct sigma_dut *dut, const char *val) 505 { 506 int i; 507 508 for (i = 0; val[i] != '\0'; i++) { 509 if (!(isalnum(val[i]) || is_allowed_char(val[i]))) { 510 sigma_dut_print(dut, DUT_MSG_DEBUG, 511 "Invalid char %c in destpath %s", 512 val[i], val); 513 return 0; 514 } 515 } 516 517 return 1; 518 } 519 520 521 #ifndef ANDROID 522 #define SUPP_LOG_BUFF_SIZE 4 * 1024 523 524 static int save_supplicant_log(struct sigma_dut *dut) 525 { 526 char dir[200]; 527 char buf[300]; 528 FILE *wpa_log = NULL; 529 FILE *supp_log; 530 char *buff_ptr = NULL; 531 unsigned int file_size; 532 unsigned int file_size_orig; 533 int status = -1, res; 534 535 if (build_log_dir(dut, dir, sizeof(dir)) < 0) 536 return -1; 537 538 res = snprintf(buf, sizeof(buf), "%s/wpa_supplicant_log_%s.txt", dir, 539 dut->dev_start_test_runtime_id); 540 if (res < 0 || res >= sizeof(buf)) 541 return -1; 542 543 supp_log = fopen(WPA_SUPPLICANT_LOG_FILE, "r"); 544 if (!supp_log) { 545 sigma_dut_print(dut, DUT_MSG_ERROR, 546 "Failed to open wpa_log file %s", 547 WPA_SUPPLICANT_LOG_FILE); 548 return -1; 549 } 550 551 /* Get the wpa_supplicant log file size */ 552 if (fseek(supp_log, 0, SEEK_END)) { 553 sigma_dut_print(dut, DUT_MSG_ERROR, 554 "Failed to get file size for read"); 555 goto exit; 556 } 557 file_size_orig = ftell(supp_log); 558 559 if (file_size_orig < dut->wpa_log_size) { 560 sigma_dut_print(dut, DUT_MSG_ERROR, 561 "file size err, new size %u, old size %u", 562 file_size_orig, dut->wpa_log_size); 563 goto exit; 564 } 565 566 /* Get the wpa_supplicant file size for current test */ 567 file_size = file_size_orig - dut->wpa_log_size; 568 569 wpa_log = fopen(buf, "w"); 570 if (!wpa_log) { 571 sigma_dut_print(dut, DUT_MSG_ERROR, 572 "Failed to create tmp wpa_log file %s", buf); 573 goto exit; 574 } 575 576 if (fseek(supp_log, dut->wpa_log_size, SEEK_SET)) { 577 sigma_dut_print(dut, DUT_MSG_ERROR, 578 "Failed to set wpa_log file ptr for read"); 579 goto exit; 580 } 581 582 buff_ptr = malloc(SUPP_LOG_BUFF_SIZE); 583 if (!buff_ptr) { 584 sigma_dut_print(dut, DUT_MSG_ERROR, 585 "Failed to alloc buffer of size %d", 586 SUPP_LOG_BUFF_SIZE); 587 goto exit; 588 } 589 590 /* Read wpa_supplicant log file in 4K byte chunks */ 591 do { 592 unsigned int num_bytes_to_read; 593 unsigned int bytes_read; 594 595 num_bytes_to_read = (file_size > SUPP_LOG_BUFF_SIZE) ? 596 SUPP_LOG_BUFF_SIZE : file_size; 597 bytes_read = fread(buff_ptr, 1, num_bytes_to_read, supp_log); 598 if (!bytes_read) { 599 sigma_dut_print(dut, DUT_MSG_ERROR, 600 "Failed to read wpa_supplicant log"); 601 goto exit; 602 } 603 if (bytes_read != num_bytes_to_read) { 604 sigma_dut_print(dut, DUT_MSG_DEBUG, 605 "wpa_supplicant log read err, read %d, num_bytes_to_read %d", 606 bytes_read, num_bytes_to_read); 607 goto exit; 608 } 609 fwrite(buff_ptr, 1, bytes_read, wpa_log); 610 file_size -= bytes_read; 611 } while (file_size > 0); 612 status = 0; 613 614 exit: 615 if (wpa_log) 616 fclose(wpa_log); 617 fclose(supp_log); 618 free(buff_ptr); 619 620 return status; 621 } 622 #endif /* !ANDROID */ 623 624 625 static enum sigma_cmd_result cmd_dev_stop_test(struct sigma_dut *dut, 626 struct sigma_conn *conn, 627 struct sigma_cmd *cmd) 628 { 629 const char *val; 630 char buf[300]; 631 char out_file[100]; 632 char dir[200]; 633 int res; 634 635 if (!dut->vendor_name) { 636 sigma_dut_print(dut, DUT_MSG_INFO, 637 "Log collection not supported without vendor name specified on the command line (-N)"); 638 return SUCCESS_SEND_STATUS; 639 } 640 641 val = get_param(cmd, "Runtime_ID"); 642 if (!val || strcmp(val, dut->dev_start_test_runtime_id) != 0) { 643 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid runtime id"); 644 return ERROR_SEND_STATUS; 645 } 646 647 if (build_log_dir(dut, dir, sizeof(dir)) < 0) 648 return ERROR_SEND_STATUS; 649 650 #ifdef ANDROID 651 /* Copy all cnss_diag logs to dir */ 652 run_system_wrapper(dut, "cp -a /data/vendor/wifi/wlan_logs/* %s", dir); 653 #else /* ANDROID */ 654 if (dut->log_file_fd) { 655 fclose(dut->log_file_fd); 656 dut->log_file_fd = NULL; 657 } 658 if (save_supplicant_log(dut)) 659 sigma_dut_print(dut, DUT_MSG_ERROR, 660 "Failed to save wpa_supplicant log"); 661 #endif /* ANDROID */ 662 663 res = snprintf(out_file, sizeof(out_file), "%s_%s_%s.tar.gz", 664 dut->vendor_name, 665 dut->model_name ? dut->model_name : "Unknown", 666 dut->dev_start_test_runtime_id); 667 if (res < 0 || res >= sizeof(out_file)) 668 return ERROR_SEND_STATUS; 669 670 if (run_system_wrapper(dut, "tar -czvf %s/../%s %s", dir, out_file, 671 dir) < 0) { 672 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to create tar: %s", 673 buf); 674 return ERROR_SEND_STATUS; 675 } 676 677 val = get_param(cmd, "destpath"); 678 if (!(val && is_destpath_valid(dut, val))) { 679 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid path for TFTP %s", 680 val); 681 return ERROR_SEND_STATUS; 682 } 683 684 res = snprintf(buf, sizeof(buf), "tftp %s -c put %s/%s %s/%s", 685 inet_ntoa(conn->addr.sin_addr), dir, out_file, val, 686 out_file); 687 if (res < 0 || res >= sizeof(buf)) 688 return ERROR_SEND_STATUS; 689 if (run_system_wrapper(dut, buf) < 0) { 690 sigma_dut_print(dut, DUT_MSG_ERROR, 691 "TFTP file transfer failed: %s", buf); 692 return ERROR_SEND_STATUS; 693 } 694 sigma_dut_print(dut, DUT_MSG_DEBUG, "TFTP file transfer: %s", buf); 695 snprintf(buf, sizeof(buf), "filename,%s", out_file); 696 send_resp(dut, conn, SIGMA_COMPLETE, buf); 697 run_system_wrapper(dut, "rm -f %s/../%s", dir, out_file); 698 run_system_wrapper(dut, "rm -rf %s", dir); 699 700 return SUCCESS_SEND_STATUS; 701 } 702 703 704 static enum sigma_cmd_result cmd_dev_get_log(struct sigma_dut *dut, 705 struct sigma_conn *conn, 706 struct sigma_cmd *cmd) 707 { 708 return SUCCESS_SEND_STATUS; 709 } 710 711 712 static int req_intf(struct sigma_cmd *cmd) 713 { 714 return get_param(cmd, "interface") == NULL ? -1 : 0; 715 } 716 717 718 static int req_role_svcname(struct sigma_cmd *cmd) 719 { 720 if (!get_param(cmd, "BLERole")) 721 return -1; 722 if (get_param(cmd, "BLEOp") && !get_param(cmd, "ServiceName")) 723 return -1; 724 return 0; 725 } 726 727 728 static int req_intf_prog(struct sigma_cmd *cmd) 729 { 730 if (get_param(cmd, "interface") == NULL) 731 return -1; 732 if (get_param(cmd, "program") == NULL) 733 return -1; 734 return 0; 735 } 736 737 738 static int req_prog(struct sigma_cmd *cmd) 739 { 740 if (get_param(cmd, "program") == NULL) 741 return -1; 742 return 0; 743 } 744 745 746 void dev_register_cmds(void) 747 { 748 sigma_dut_reg_cmd("dev_send_frame", req_prog, cmd_dev_send_frame); 749 sigma_dut_reg_cmd("dev_set_parameter", req_intf_prog, 750 cmd_dev_set_parameter); 751 sigma_dut_reg_cmd("dev_exec_action", req_prog, 752 cmd_dev_exec_action); 753 sigma_dut_reg_cmd("dev_configure_ie", req_intf, cmd_dev_configure_ie); 754 sigma_dut_reg_cmd("dev_start_test", NULL, cmd_dev_start_test); 755 sigma_dut_reg_cmd("dev_stop_test", NULL, cmd_dev_stop_test); 756 sigma_dut_reg_cmd("dev_get_log", NULL, cmd_dev_get_log); 757 sigma_dut_reg_cmd("dev_ble_action", req_role_svcname, 758 cmd_dev_ble_action); 759 } 760