1254159Shselasky/* $FreeBSD$ */ 2254159Shselasky/*- 3254159Shselasky * Copyright (c) 2007-2010 Hans Petter Selasky. All rights reserved. 4254159Shselasky * 5254159Shselasky * Redistribution and use in source and binary forms, with or without 6254159Shselasky * modification, are permitted provided that the following conditions 7254159Shselasky * are met: 8254159Shselasky * 1. Redistributions of source code must retain the above copyright 9254159Shselasky * notice, this list of conditions and the following disclaimer. 10254159Shselasky * 2. Redistributions in binary form must reproduce the above copyright 11254159Shselasky * notice, this list of conditions and the following disclaimer in the 12254159Shselasky * documentation and/or other materials provided with the distribution. 13254159Shselasky * 14254159Shselasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15254159Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16254159Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17254159Shselasky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18254159Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19254159Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20254159Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21254159Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22254159Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23254159Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24254159Shselasky * SUCH DAMAGE. 25254159Shselasky */ 26254159Shselasky 27254159Shselasky#include <stdio.h> 28254159Shselasky#include <stdint.h> 29254159Shselasky#include <stdlib.h> 30254159Shselasky#include <err.h> 31254159Shselasky#include <string.h> 32254159Shselasky#include <errno.h> 33254159Shselasky#include <unistd.h> 34254159Shselasky 35254159Shselasky#include <sys/sysctl.h> 36254159Shselasky#include <sys/time.h> 37254159Shselasky 38254159Shselasky#include <libusb20.h> 39254159Shselasky#include <libusb20_desc.h> 40254159Shselasky 41254159Shselasky#include <dev/usb/usb_endian.h> 42254159Shselasky#include <dev/usb/usb.h> 43254159Shselasky#include <dev/usb/usb_cdc.h> 44254159Shselasky 45254159Shselasky#include "usbtest.h" 46254159Shselasky 47254159Shselaskystatic struct modem { 48254159Shselasky struct libusb20_transfer *xfer_in; 49254159Shselasky struct libusb20_transfer *xfer_out; 50254159Shselasky struct libusb20_device *usb_dev; 51254159Shselasky 52254159Shselasky struct bps rx_bytes; 53254159Shselasky struct bps tx_bytes; 54254159Shselasky uint32_t c0; 55254159Shselasky uint32_t c1; 56254159Shselasky uint32_t out_state; 57254159Shselasky uint32_t in_last; 58254159Shselasky uint32_t in_synced; 59254159Shselasky uint32_t duration; 60254159Shselasky uint32_t errors; 61254159Shselasky 62254159Shselasky uint8_t use_vendor_specific; 63254159Shselasky uint8_t loop_data; 64254159Shselasky uint8_t modem_at_mode; 65254159Shselasky uint8_t data_stress_test; 66254159Shselasky uint8_t control_ep_test; 67254159Shselasky uint8_t usb_iface; 68254159Shselasky uint8_t random_tx_length; 69254159Shselasky uint8_t random_tx_delay; 70254159Shselasky 71254159Shselasky} modem; 72254159Shselasky 73254159Shselaskystatic void 74254159Shselaskyset_defaults(struct modem *p) 75254159Shselasky{ 76254159Shselasky memset(p, 0, sizeof(*p)); 77254159Shselasky 78254159Shselasky p->data_stress_test = 1; 79254159Shselasky p->control_ep_test = 1; 80254159Shselasky p->duration = 60; /* seconds */ 81254159Shselasky} 82254159Shselasky 83254159Shselaskyvoid 84254159Shselaskydo_bps(const char *desc, struct bps *bps, uint32_t len) 85254159Shselasky{ 86254159Shselasky bps->bytes += len; 87254159Shselasky} 88254159Shselasky 89254159Shselaskystatic void 90254159Shselaskymodem_out_state(uint8_t *buf) 91254159Shselasky{ 92254159Shselasky if (modem.modem_at_mode) { 93254159Shselasky switch (modem.out_state & 3) { 94254159Shselasky case 0: 95254159Shselasky *buf = 'A'; 96254159Shselasky break; 97254159Shselasky case 1: 98254159Shselasky *buf = 'T'; 99254159Shselasky break; 100254159Shselasky case 2: 101254159Shselasky *buf = '\r'; 102254159Shselasky break; 103254159Shselasky default: 104254159Shselasky *buf = '\n'; 105254159Shselasky modem.c0++; 106254159Shselasky break; 107254159Shselasky } 108254159Shselasky modem.out_state++; 109254159Shselasky } else { 110254159Shselasky *buf = modem.out_state; 111254159Shselasky modem.out_state++; 112254159Shselasky modem.out_state %= 255; 113254159Shselasky } 114254159Shselasky} 115254159Shselasky 116254159Shselaskystatic void 117254159Shselaskymodem_in_state(uint8_t buf, uint32_t counter) 118254159Shselasky{ 119254159Shselasky if ((modem.in_last == 'O') && (buf == 'K')) { 120254159Shselasky modem.c1++; 121254159Shselasky modem.in_last = buf; 122254159Shselasky } else if (buf == modem.in_last) { 123254159Shselasky modem.c1++; 124254159Shselasky modem.in_last++; 125254159Shselasky modem.in_last %= 255; 126254159Shselasky if (modem.in_synced == 0) { 127254159Shselasky if (modem.errors < 64) { 128254159Shselasky printf("Got sync\n"); 129254159Shselasky } 130254159Shselasky modem.in_synced = 1; 131254159Shselasky } 132254159Shselasky } else { 133254159Shselasky if (modem.in_synced) { 134254159Shselasky if (modem.errors < 64) { 135254159Shselasky printf("Lost sync @ %d, 0x%02x != 0x%02x\n", 136254159Shselasky counter % 512, buf, modem.in_last); 137254159Shselasky } 138254159Shselasky modem.in_synced = 0; 139254159Shselasky modem.errors++; 140254159Shselasky } 141254159Shselasky modem.in_last = buf; 142254159Shselasky modem.in_last++; 143254159Shselasky modem.in_last %= 255; 144254159Shselasky } 145254159Shselasky} 146254159Shselasky 147254159Shselaskystatic void 148254159Shselaskymodem_write(uint8_t *buf, uint32_t len) 149254159Shselasky{ 150254159Shselasky uint32_t n; 151254159Shselasky 152254159Shselasky for (n = 0; n != len; n++) { 153254159Shselasky modem_out_state(buf + n); 154254159Shselasky } 155254159Shselasky 156254159Shselasky do_bps("transmitted", &modem.tx_bytes, len); 157254159Shselasky} 158254159Shselasky 159254159Shselaskystatic void 160254159Shselaskymodem_read(uint8_t *buf, uint32_t len) 161254159Shselasky{ 162254159Shselasky uint32_t n; 163254159Shselasky 164254159Shselasky for (n = 0; n != len; n++) { 165254159Shselasky modem_in_state(buf[n], n); 166254159Shselasky } 167254159Shselasky 168254159Shselasky do_bps("received", &modem.rx_bytes, len); 169254159Shselasky} 170254159Shselasky 171254159Shselaskystatic void 172254159Shselaskyusb_modem_control_ep_test(struct modem *p, uint32_t duration, uint8_t flag) 173254159Shselasky{ 174254159Shselasky struct timeval sub_tv; 175254159Shselasky struct timeval ref_tv; 176254159Shselasky struct timeval res_tv; 177254159Shselasky struct LIBUSB20_CONTROL_SETUP_DECODED setup; 178254159Shselasky struct usb_cdc_abstract_state ast; 179254159Shselasky struct usb_cdc_line_state ls; 180254159Shselasky uint16_t feature = UCDC_ABSTRACT_STATE; 181254159Shselasky uint16_t state = UCDC_DATA_MULTIPLEXED; 182254159Shselasky uint8_t iface_no; 183254159Shselasky uint8_t buf[4]; 184254159Shselasky int id = 0; 185254159Shselasky int iter = 0; 186254159Shselasky 187254159Shselasky time_t last_sec; 188254159Shselasky 189254159Shselasky iface_no = p->usb_iface - 1; 190254159Shselasky 191254159Shselasky gettimeofday(&ref_tv, 0); 192254159Shselasky 193254159Shselasky last_sec = ref_tv.tv_sec; 194254159Shselasky 195254159Shselasky printf("\nTest=%d\n", (int)flag); 196254159Shselasky 197254159Shselasky while (1) { 198254159Shselasky 199254159Shselasky gettimeofday(&sub_tv, 0); 200254159Shselasky 201254159Shselasky if (last_sec != sub_tv.tv_sec) { 202254159Shselasky 203254159Shselasky printf("STATUS: ID=%u, COUNT=%u tests/sec ERR=%u\n", 204254159Shselasky (int)id, 205254159Shselasky (int)iter, 206254159Shselasky (int)p->errors); 207254159Shselasky 208254159Shselasky fflush(stdout); 209254159Shselasky 210254159Shselasky last_sec = sub_tv.tv_sec; 211254159Shselasky 212254159Shselasky id++; 213254159Shselasky 214254159Shselasky iter = 0; 215254159Shselasky } 216254159Shselasky timersub(&sub_tv, &ref_tv, &res_tv); 217254159Shselasky 218254241Shselasky if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration)) 219254159Shselasky break; 220254159Shselasky 221254159Shselasky LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup); 222254159Shselasky 223254159Shselasky if (flag & 1) { 224254159Shselasky setup.bmRequestType = UT_READ_CLASS_INTERFACE; 225254159Shselasky setup.bRequest = 0x03; 226254159Shselasky setup.wValue = 0x0001; 227254159Shselasky setup.wIndex = iface_no; 228254159Shselasky setup.wLength = 0x0002; 229254159Shselasky 230254159Shselasky if (libusb20_dev_request_sync(p->usb_dev, &setup, buf, NULL, 250, 0)) { 231254159Shselasky p->errors++; 232254159Shselasky } 233254159Shselasky } 234254159Shselasky if (flag & 2) { 235254159Shselasky setup.bmRequestType = UT_WRITE_CLASS_INTERFACE; 236254159Shselasky setup.bRequest = UCDC_SET_COMM_FEATURE; 237254159Shselasky setup.wValue = feature; 238254159Shselasky setup.wIndex = iface_no; 239254159Shselasky setup.wLength = UCDC_ABSTRACT_STATE_LENGTH; 240254159Shselasky USETW(ast.wState, state); 241254159Shselasky 242254159Shselasky if (libusb20_dev_request_sync(p->usb_dev, &setup, &ast, NULL, 250, 0)) { 243254159Shselasky p->errors++; 244254159Shselasky } 245254159Shselasky } 246254159Shselasky if (flag & 4) { 247254159Shselasky USETDW(ls.dwDTERate, 115200); 248254159Shselasky ls.bCharFormat = UCDC_STOP_BIT_1; 249254159Shselasky ls.bParityType = UCDC_PARITY_NONE; 250254159Shselasky ls.bDataBits = 8; 251254159Shselasky 252254159Shselasky setup.bmRequestType = UT_WRITE_CLASS_INTERFACE; 253254159Shselasky setup.bRequest = UCDC_SET_LINE_CODING; 254254159Shselasky setup.wValue = 0; 255254159Shselasky setup.wIndex = iface_no; 256254159Shselasky setup.wLength = sizeof(ls); 257254159Shselasky 258254159Shselasky if (libusb20_dev_request_sync(p->usb_dev, &setup, &ls, NULL, 250, 0)) { 259254159Shselasky p->errors++; 260254159Shselasky } 261254159Shselasky } 262254159Shselasky iter++; 263254159Shselasky } 264254159Shselasky 265254159Shselasky printf("\nModem control endpoint test done!\n"); 266254159Shselasky} 267254159Shselasky 268254159Shselaskystatic void 269254159Shselaskyusb_modem_data_stress_test(struct modem *p, uint32_t duration) 270254159Shselasky{ 271254159Shselasky struct timeval sub_tv; 272254159Shselasky struct timeval ref_tv; 273254159Shselasky struct timeval res_tv; 274254159Shselasky 275254159Shselasky time_t last_sec; 276254159Shselasky 277254159Shselasky uint8_t in_pending = 0; 278254159Shselasky uint8_t in_ready = 0; 279254159Shselasky uint8_t out_pending = 0; 280254159Shselasky 281254159Shselasky uint32_t id = 0; 282254159Shselasky 283254159Shselasky uint32_t in_max; 284254159Shselasky uint32_t out_max; 285254159Shselasky uint32_t io_max; 286254159Shselasky 287254159Shselasky uint8_t *in_buffer = 0; 288254159Shselasky uint8_t *out_buffer = 0; 289254159Shselasky 290254159Shselasky gettimeofday(&ref_tv, 0); 291254159Shselasky 292254159Shselasky last_sec = ref_tv.tv_sec; 293254159Shselasky 294254159Shselasky printf("\n"); 295254159Shselasky 296254159Shselasky in_max = libusb20_tr_get_max_total_length(p->xfer_in); 297254159Shselasky out_max = libusb20_tr_get_max_total_length(p->xfer_out); 298254159Shselasky 299254159Shselasky /* get the smallest buffer size and use that */ 300254159Shselasky io_max = (in_max < out_max) ? in_max : out_max; 301254159Shselasky 302254159Shselasky if (in_max != out_max) 303254159Shselasky printf("WARNING: Buffer sizes are un-equal: %u vs %u\n", in_max, out_max); 304254159Shselasky 305254159Shselasky in_buffer = malloc(io_max); 306254159Shselasky if (in_buffer == NULL) 307254159Shselasky goto fail; 308254159Shselasky 309254159Shselasky out_buffer = malloc(io_max); 310254159Shselasky if (out_buffer == NULL) 311254159Shselasky goto fail; 312254159Shselasky 313254159Shselasky while (1) { 314254159Shselasky 315254159Shselasky gettimeofday(&sub_tv, 0); 316254159Shselasky 317254159Shselasky if (last_sec != sub_tv.tv_sec) { 318254159Shselasky 319254159Shselasky printf("STATUS: ID=%u, RX=%u bytes/sec, TX=%u bytes/sec, ERR=%d\n", 320254159Shselasky (int)id, 321254159Shselasky (int)p->rx_bytes.bytes, 322254159Shselasky (int)p->tx_bytes.bytes, 323254159Shselasky (int)p->errors); 324254159Shselasky 325254159Shselasky p->rx_bytes.bytes = 0; 326254159Shselasky p->tx_bytes.bytes = 0; 327254159Shselasky 328254159Shselasky fflush(stdout); 329254159Shselasky 330254159Shselasky last_sec = sub_tv.tv_sec; 331254159Shselasky 332254159Shselasky id++; 333254159Shselasky } 334254159Shselasky timersub(&sub_tv, &ref_tv, &res_tv); 335254159Shselasky 336254241Shselasky if ((res_tv.tv_sec < 0) || (res_tv.tv_sec >= (int)duration)) 337254159Shselasky break; 338254159Shselasky 339254159Shselasky libusb20_dev_process(p->usb_dev); 340254159Shselasky 341254159Shselasky if (!libusb20_tr_pending(p->xfer_in)) { 342254159Shselasky if (in_pending) { 343254159Shselasky if (libusb20_tr_get_status(p->xfer_in) == 0) { 344254159Shselasky modem_read(in_buffer, libusb20_tr_get_length(p->xfer_in, 0)); 345254159Shselasky } else { 346254159Shselasky p->errors++; 347254159Shselasky usleep(10000); 348254159Shselasky } 349254159Shselasky in_pending = 0; 350254159Shselasky in_ready = 1; 351254159Shselasky } 352254159Shselasky if (p->loop_data == 0) { 353254159Shselasky libusb20_tr_setup_bulk(p->xfer_in, in_buffer, io_max, 0); 354254159Shselasky libusb20_tr_start(p->xfer_in); 355254159Shselasky in_pending = 1; 356254159Shselasky in_ready = 0; 357254159Shselasky } 358254159Shselasky } 359254159Shselasky if (!libusb20_tr_pending(p->xfer_out)) { 360254159Shselasky 361254159Shselasky uint32_t len; 362254159Shselasky uint32_t dly; 363254159Shselasky 364254159Shselasky if (out_pending) { 365254159Shselasky if (libusb20_tr_get_status(p->xfer_out) != 0) { 366254159Shselasky p->errors++; 367254159Shselasky usleep(10000); 368254159Shselasky } 369254159Shselasky } 370254159Shselasky if (p->random_tx_length) { 371254159Shselasky len = ((uint32_t)usb_ts_rand_noise()) % ((uint32_t)io_max); 372254159Shselasky } else { 373254159Shselasky len = io_max; 374254159Shselasky } 375254159Shselasky 376254159Shselasky if (p->random_tx_delay) { 377254159Shselasky dly = ((uint32_t)usb_ts_rand_noise()) % 16000U; 378254159Shselasky } else { 379254159Shselasky dly = 0; 380254159Shselasky } 381254159Shselasky 382254159Shselasky if (p->loop_data != 0) { 383254159Shselasky if (in_ready != 0) { 384254159Shselasky len = libusb20_tr_get_length(p->xfer_in, 0); 385254159Shselasky memcpy(out_buffer, in_buffer, len); 386254159Shselasky in_ready = 0; 387254159Shselasky } else { 388254159Shselasky len = io_max + 1; 389254159Shselasky } 390254159Shselasky if (!libusb20_tr_pending(p->xfer_in)) { 391254159Shselasky libusb20_tr_setup_bulk(p->xfer_in, in_buffer, io_max, 0); 392254159Shselasky libusb20_tr_start(p->xfer_in); 393254159Shselasky in_pending = 1; 394254159Shselasky } 395254159Shselasky } else { 396254159Shselasky modem_write(out_buffer, len); 397254159Shselasky } 398254159Shselasky 399254159Shselasky if (len <= io_max) { 400254159Shselasky libusb20_tr_setup_bulk(p->xfer_out, out_buffer, len, 0); 401254159Shselasky 402254159Shselasky if (dly != 0) 403254159Shselasky usleep(dly); 404254159Shselasky 405254159Shselasky libusb20_tr_start(p->xfer_out); 406254159Shselasky 407254159Shselasky out_pending = 1; 408254159Shselasky } 409254159Shselasky } 410254159Shselasky libusb20_dev_wait_process(p->usb_dev, 500); 411254159Shselasky 412254159Shselasky if (libusb20_dev_check_connected(p->usb_dev) != 0) { 413254159Shselasky printf("Device disconnected\n"); 414254159Shselasky break; 415254159Shselasky } 416254159Shselasky } 417254159Shselasky 418254159Shselasky libusb20_tr_stop(p->xfer_in); 419254159Shselasky libusb20_tr_stop(p->xfer_out); 420254159Shselasky 421254159Shselasky printf("\nData stress test done!\n"); 422254159Shselasky 423254159Shselaskyfail: 424254159Shselasky if (in_buffer) 425254159Shselasky free(in_buffer); 426254159Shselasky if (out_buffer) 427254159Shselasky free(out_buffer); 428254159Shselasky} 429254159Shselasky 430254159Shselaskystatic void 431254159Shselaskyexec_host_modem_test(struct modem *p, uint16_t vid, uint16_t pid) 432254159Shselasky{ 433254159Shselasky struct libusb20_device *pdev; 434254159Shselasky 435254159Shselasky uint8_t ntest = 0; 436254159Shselasky uint8_t x; 437254159Shselasky uint8_t in_ep; 438254159Shselasky uint8_t out_ep; 439254159Shselasky uint8_t iface; 440254159Shselasky 441254159Shselasky int error; 442254159Shselasky 443254159Shselasky pdev = find_usb_device(vid, pid); 444254159Shselasky if (pdev == NULL) { 445254159Shselasky printf("USB device not found\n"); 446254159Shselasky return; 447254159Shselasky } 448254159Shselasky 449254159Shselasky if (p->use_vendor_specific) 450254159Shselasky find_usb_endpoints(pdev, 255, 255, 255, 0, &iface, &in_ep, &out_ep, 0); 451254159Shselasky else 452254159Shselasky find_usb_endpoints(pdev, 2, 2, 1, 0, &iface, &in_ep, &out_ep, 1); 453254159Shselasky 454254159Shselasky if ((in_ep == 0) || (out_ep == 0)) { 455254159Shselasky printf("Could not find USB endpoints\n"); 456254159Shselasky libusb20_dev_free(pdev); 457254159Shselasky return; 458254159Shselasky } 459254159Shselasky printf("Attaching to: %s @ iface %d\n", 460254159Shselasky libusb20_dev_get_desc(pdev), iface); 461254159Shselasky 462254159Shselasky if (libusb20_dev_open(pdev, 2)) { 463254159Shselasky printf("Could not open USB device\n"); 464254159Shselasky libusb20_dev_free(pdev); 465254159Shselasky return; 466254159Shselasky } 467254159Shselasky if (libusb20_dev_detach_kernel_driver(pdev, iface)) { 468254159Shselasky printf("WARNING: Could not detach kernel driver\n"); 469254159Shselasky } 470254159Shselasky p->xfer_in = libusb20_tr_get_pointer(pdev, 0); 471254159Shselasky error = libusb20_tr_open(p->xfer_in, 65536 / 4, 1, in_ep); 472254159Shselasky if (error) { 473254159Shselasky printf("Could not open USB endpoint %d\n", in_ep); 474254159Shselasky libusb20_dev_free(pdev); 475254159Shselasky return; 476254159Shselasky } 477254159Shselasky p->xfer_out = libusb20_tr_get_pointer(pdev, 1); 478254159Shselasky error = libusb20_tr_open(p->xfer_out, 65536 / 4, 1, out_ep); 479254159Shselasky if (error) { 480254159Shselasky printf("Could not open USB endpoint %d\n", out_ep); 481254159Shselasky libusb20_dev_free(pdev); 482254159Shselasky return; 483254159Shselasky } 484254159Shselasky p->usb_dev = pdev; 485254159Shselasky p->usb_iface = iface; 486254159Shselasky p->errors = 0; 487254159Shselasky 488254159Shselasky if (p->control_ep_test) 489254159Shselasky ntest += 7; 490254159Shselasky 491254159Shselasky if (p->data_stress_test) 492254159Shselasky ntest += 1; 493254159Shselasky 494254159Shselasky if (ntest == 0) { 495254159Shselasky printf("No tests selected\n"); 496254159Shselasky } else { 497254159Shselasky 498254159Shselasky if (p->control_ep_test) { 499254159Shselasky for (x = 1; x != 8; x++) { 500254159Shselasky usb_modem_control_ep_test(p, 501254159Shselasky (p->duration + ntest - 1) / ntest, x); 502254159Shselasky } 503254159Shselasky } 504254159Shselasky if (p->data_stress_test) { 505254159Shselasky usb_modem_data_stress_test(p, 506254159Shselasky (p->duration + ntest - 1) / ntest); 507254159Shselasky } 508254159Shselasky } 509254159Shselasky 510254159Shselasky printf("\nDone\n"); 511254159Shselasky 512254159Shselasky libusb20_dev_free(pdev); 513254159Shselasky} 514254159Shselasky 515254159Shselaskyvoid 516254159Shselaskyshow_host_modem_test(uint8_t level, uint16_t vid, uint16_t pid, uint32_t duration) 517254159Shselasky{ 518254159Shselasky uint8_t retval; 519254159Shselasky 520254159Shselasky set_defaults(&modem); 521254159Shselasky 522254159Shselasky modem.duration = duration; 523254159Shselasky 524254159Shselasky while (1) { 525254159Shselasky 526254159Shselasky retval = usb_ts_show_menu(level, "Modem Test Parameters", 527254159Shselasky " 1) Execute Data Stress Test: <%s>\n" 528254159Shselasky " 2) Execute Modem Control Endpoint Test: <%s>\n" 529254159Shselasky " 3) Use random transmit length: <%s>\n" 530254159Shselasky " 4) Use random transmit delay: <%s> ms\n" 531254159Shselasky " 5) Use vendor specific interface: <%s>\n" 532254159Shselasky "10) Loop data: <%s>\n" 533254159Shselasky "13) Set test duration: <%d> seconds\n" 534254159Shselasky "20) Reset parameters\n" 535254159Shselasky "30) Start test (VID=0x%04x, PID=0x%04x)\n" 536254159Shselasky "40) Select another device\n" 537254159Shselasky " x) Return to previous menu \n", 538254159Shselasky (modem.data_stress_test ? "YES" : "NO"), 539254159Shselasky (modem.control_ep_test ? "YES" : "NO"), 540254159Shselasky (modem.random_tx_length ? "YES" : "NO"), 541254159Shselasky (modem.random_tx_delay ? "16" : "0"), 542254159Shselasky (modem.use_vendor_specific ? "YES" : "NO"), 543254159Shselasky (modem.loop_data ? "YES" : "NO"), 544254159Shselasky (int)(modem.duration), 545254159Shselasky (int)vid, (int)pid); 546254159Shselasky 547254159Shselasky switch (retval) { 548254159Shselasky case 0: 549254159Shselasky break; 550254159Shselasky case 1: 551254159Shselasky modem.data_stress_test ^= 1; 552254159Shselasky break; 553254159Shselasky case 2: 554254159Shselasky modem.control_ep_test ^= 1; 555254159Shselasky break; 556254159Shselasky case 3: 557254159Shselasky modem.random_tx_length ^= 1; 558254159Shselasky break; 559254159Shselasky case 4: 560254159Shselasky modem.random_tx_delay ^= 1; 561254159Shselasky break; 562254159Shselasky case 5: 563254159Shselasky modem.use_vendor_specific ^= 1; 564254159Shselasky modem.control_ep_test = 0; 565254159Shselasky break; 566254159Shselasky case 10: 567254159Shselasky modem.loop_data ^= 1; 568254159Shselasky break; 569254159Shselasky case 13: 570254159Shselasky modem.duration = get_integer(); 571254159Shselasky break; 572254159Shselasky case 20: 573254159Shselasky set_defaults(&modem); 574254159Shselasky break; 575254159Shselasky case 30: 576254159Shselasky exec_host_modem_test(&modem, vid, pid); 577254159Shselasky break; 578254159Shselasky case 40: 579254159Shselasky show_host_device_selection(level + 1, &vid, &pid); 580254159Shselasky break; 581254159Shselasky default: 582254159Shselasky return; 583254159Shselasky } 584254159Shselasky } 585254159Shselasky} 586