3 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/types.h>
36 #include <sys/sysctl.h>
38 #include <dev/usb/usb_ioctl.h>
42 #include <g_keyboard.h>
47 static uint8_t usb_ts_select[USB_TS_MAX_LEVELS];
49 const char *indent[USB_TS_MAX_LEVELS] = {
60 /* a perceptual white noise generator (after HPS' invention) */
63 usb_ts_rand_noise(void)
66 const uint32_t prime = 0xFFFF1D;
67 static uint32_t noise_rem = 1;
76 /* unsigned to signed conversion */
79 if (temp & 0x800000) {
86 usb_ts_show_menu(uint8_t level, const char *title, const char *fmt,...)
96 vsnprintf(menu, sizeof(menu), fmt, args);
101 for (x = 0; x != level; x++) {
102 if ((x + 1) == level)
103 printf("%d", usb_ts_select[x]);
105 printf("%d.", usb_ts_select[x]);
108 printf("] - %s:\n\n", title);
111 for (pstr = menu; *pstr; pstr++) {
113 printf("%s", indent[level]);
124 if (fgets(buf, sizeof(buf), stdin) == NULL)
125 err(1, "Cannot read input");
132 usb_ts_select[level] = retval;
138 get_string(char *ptr, int size)
140 printf("\nEnter string>");
142 if (fgets(ptr, size, stdin) == NULL)
143 err(1, "Cannot read input");
149 /* strip trailing newline, if any */
152 else if (ptr[size - 1] == '\n')
161 printf("\nEnter integer value>");
163 if (fgets(buf, sizeof(buf), stdin) == NULL)
164 err(1, "Cannot read input");
166 if (strcmp(buf, "x\n") == 0)
168 if (strcmp(buf, "r\n") == 0)
171 return ((int)strtol(buf, 0, 0));
175 set_template(int template)
179 error = sysctlbyname("hw.usb.template", NULL, NULL,
180 &template, sizeof(template));
183 printf("WARNING: Could not set USB template "
184 "to %d (error=%d)\n", template, errno);
189 show_default_audio_select(uint8_t level)
194 int pattern_interval = 128;
197 char pattern[G_AUDIO_MAX_STRLEN] = {"0123456789abcdef"};
199 set_template(USB_TEMP_AUDIO);
203 error = sysctlbyname("hw.usb.g_audio.mode", NULL, NULL,
204 &mode, sizeof(mode));
207 printf("WARNING: Could not set audio mode "
208 "to %d (error=%d)\n", mode, errno);
210 error = sysctlbyname("hw.usb.g_audio.pattern_interval", NULL, NULL,
211 &pattern_interval, sizeof(pattern_interval));
214 printf("WARNING: Could not set pattern interval "
215 "to %d (error=%d)\n", pattern_interval, errno);
217 len = sizeof(throughput);
219 error = sysctlbyname("hw.usb.g_audio.throughput",
220 &throughput, &len, 0, 0);
223 printf("WARNING: Could not get throughput "
224 "(error=%d)\n", errno);
226 error = sysctlbyname("hw.usb.g_audio.pattern", NULL, NULL,
227 &pattern, strlen(pattern));
230 printf("WARNING: Could not set audio pattern "
231 "to '%s' (error=%d)\n", pattern, errno);
233 retval = usb_ts_show_menu(level, "Default Audio Settings",
234 "1) Set Silent mode %s\n"
235 "2) Set Dump mode %s\n"
236 "3) Set Loop mode %s\n"
237 "4) Set Pattern mode %s\n"
238 "5) Change DTMF pattern: '%s'\n"
239 "6) Change pattern advance interval: %d ms\n"
240 "x) Return to previous menu\n"
241 "s: Ready for enumeration\n"
242 "t: Throughput: %d bytes/second\n",
243 (mode == G_AUDIO_MODE_SILENT) ? "(selected)" : "",
244 (mode == G_AUDIO_MODE_DUMP) ? "(selected)" : "",
245 (mode == G_AUDIO_MODE_LOOP) ? "(selected)" : "",
246 (mode == G_AUDIO_MODE_PATTERN) ? "(selected)" : "",
247 pattern, pattern_interval, throughput);
253 mode = G_AUDIO_MODE_SILENT;
256 mode = G_AUDIO_MODE_DUMP;
259 mode = G_AUDIO_MODE_LOOP;
262 mode = G_AUDIO_MODE_PATTERN;
265 get_string(pattern, sizeof(pattern));
268 pattern_interval = get_integer();
277 show_device_audio_select(uint8_t level)
283 retval = usb_ts_show_menu(level, "Select Audio Device Model",
284 "1) Generic Audio Device\n"
285 "x) Return to previous menu\n");
291 show_default_audio_select(level + 1);
300 show_device_msc_select(uint8_t level)
302 set_template(USB_TEMP_MSC);
306 show_device_ethernet_select(uint8_t level)
308 set_template(USB_TEMP_CDCE);
312 show_default_keyboard_select(uint8_t level)
318 char pattern[G_KEYBOARD_MAX_STRLEN] = {"abcdefpattern"};
320 set_template(USB_TEMP_KBD);
324 error = sysctlbyname("hw.usb.g_keyboard.mode", NULL, NULL,
325 &mode, sizeof(mode));
328 printf("WARNING: Could not set keyboard mode "
329 " to %d (error=%d) \n", mode, errno);
331 error = sysctlbyname("hw.usb.g_keyboard.key_press_interval", NULL, NULL,
332 &interval, sizeof(interval));
335 printf("WARNING: Could not set key press interval "
336 "to %d (error=%d)\n", interval, errno);
338 error = sysctlbyname("hw.usb.g_keyboard.key_press_pattern", NULL, NULL,
339 &pattern, strlen(pattern));
342 printf("WARNING: Could not set key pattern "
343 "to '%s' (error=%d)\n", pattern, errno);
345 retval = usb_ts_show_menu(level, "Default Keyboard Settings",
346 "1) Set silent mode %s\n"
347 "2) Set pattern mode %s\n"
348 "3) Change pattern: '%s'\n"
349 "4) Change key press interval: %d ms\n"
350 "x) Return to previous menu\n"
351 "s: Ready for enumeration\n",
352 (mode == G_KEYBOARD_MODE_SILENT) ? "(selected)" : "",
353 (mode == G_KEYBOARD_MODE_PATTERN) ? "(selected)" : "",
360 mode = G_KEYBOARD_MODE_SILENT;
363 mode = G_KEYBOARD_MODE_PATTERN;
366 get_string(pattern, sizeof(pattern));
369 interval = get_integer();
378 show_device_keyboard_select(uint8_t level)
384 retval = usb_ts_show_menu(level, "Select Keyboard Model",
385 "1) Generic Keyboard \n"
386 "x) Return to previous menu \n");
392 show_default_keyboard_select(level + 1);
401 show_default_mouse_select(uint8_t level)
406 int cursor_interval = 128;
407 int cursor_radius = 75;
408 int button_interval = 0;
410 set_template(USB_TEMP_MOUSE);
414 error = sysctlbyname("hw.usb.g_mouse.mode", NULL, NULL,
415 &mode, sizeof(mode));
418 printf("WARNING: Could not set mouse mode "
419 "to %d (error=%d)\n", mode, errno);
421 error = sysctlbyname("hw.usb.g_mouse.cursor_update_interval", NULL, NULL,
422 &cursor_interval, sizeof(cursor_interval));
425 printf("WARNING: Could not set cursor update interval "
426 "to %d (error=%d)\n", cursor_interval, errno);
428 error = sysctlbyname("hw.usb.g_mouse.button_press_interval", NULL, NULL,
429 &button_interval, sizeof(button_interval));
432 printf("WARNING: Could not set button press interval "
433 "to %d (error=%d)\n", button_interval, errno);
435 error = sysctlbyname("hw.usb.g_mouse.cursor_radius", NULL, NULL,
436 &cursor_radius, sizeof(cursor_radius));
439 printf("WARNING: Could not set cursor radius "
440 "to %d (error=%d)\n", cursor_radius, errno);
442 retval = usb_ts_show_menu(level, "Default Mouse Settings",
443 "1) Set Silent mode %s\n"
444 "2) Set Circle mode %s\n"
445 "3) Set Square mode %s\n"
446 "4) Set Spiral mode %s\n"
447 "5) Change cursor radius: %d pixels\n"
448 "6) Change cursor update interval: %d ms\n"
449 "7) Change button[0] press interval: %d ms\n"
450 "x) Return to previous menu\n"
451 "s: Ready for enumeration\n",
452 (mode == G_MOUSE_MODE_SILENT) ? "(selected)" : "",
453 (mode == G_MOUSE_MODE_CIRCLE) ? "(selected)" : "",
454 (mode == G_MOUSE_MODE_BOX) ? "(selected)" : "",
455 (mode == G_MOUSE_MODE_SPIRAL) ? "(selected)" : "",
456 cursor_radius, cursor_interval, button_interval);
462 mode = G_MOUSE_MODE_SILENT;
465 mode = G_MOUSE_MODE_CIRCLE;
468 mode = G_MOUSE_MODE_BOX;
471 mode = G_MOUSE_MODE_SPIRAL;
474 cursor_radius = get_integer();
477 cursor_interval = get_integer();
480 button_interval = get_integer();
489 show_device_mouse_select(uint8_t level)
495 retval = usb_ts_show_menu(level, "Select Mouse Model",
497 "x) Return to previous menu\n");
503 show_default_mouse_select(level + 1);
512 show_device_mtp_select(uint8_t level)
514 set_template(USB_TEMP_MTP);
518 show_default_modem_select(uint8_t level)
523 int pattern_interval = 128;
526 char pattern[G_MODEM_MAX_STRLEN] = {"abcdefpattern"};
528 set_template(USB_TEMP_MODEM);
532 error = sysctlbyname("hw.usb.g_modem.mode", NULL, NULL,
533 &mode, sizeof(mode));
536 printf("WARNING: Could not set modem mode "
537 "to %d (error=%d)\n", mode, errno);
539 error = sysctlbyname("hw.usb.g_modem.pattern_interval", NULL, NULL,
540 &pattern_interval, sizeof(pattern_interval));
543 printf("WARNING: Could not set pattern interval "
544 "to %d (error=%d)\n", pattern_interval, errno);
546 len = sizeof(throughput);
548 error = sysctlbyname("hw.usb.g_modem.throughput",
549 &throughput, &len, 0, 0);
552 printf("WARNING: Could not get throughput "
553 "(error=%d)\n", errno);
555 error = sysctlbyname("hw.usb.g_modem.pattern", NULL, NULL,
556 &pattern, strlen(pattern));
559 printf("WARNING: Could not set modem pattern "
560 "to '%s' (error=%d)\n", pattern, errno);
562 retval = usb_ts_show_menu(level, "Default Modem Settings",
563 "1) Set Silent mode %s\n"
564 "2) Set Dump mode %s\n"
565 "3) Set Loop mode %s\n"
566 "4) Set Pattern mode %s\n"
567 "5) Change test pattern: '%s'\n"
568 "6) Change data transmit interval: %d ms\n"
569 "x) Return to previous menu\n"
570 "s: Ready for enumeration\n"
571 "t: Throughput: %d bytes/second\n",
572 (mode == G_MODEM_MODE_SILENT) ? "(selected)" : "",
573 (mode == G_MODEM_MODE_DUMP) ? "(selected)" : "",
574 (mode == G_MODEM_MODE_LOOP) ? "(selected)" : "",
575 (mode == G_MODEM_MODE_PATTERN) ? "(selected)" : "",
576 pattern, pattern_interval, throughput);
582 mode = G_MODEM_MODE_SILENT;
585 mode = G_MODEM_MODE_DUMP;
588 mode = G_MODEM_MODE_LOOP;
591 mode = G_MODEM_MODE_PATTERN;
594 get_string(pattern, sizeof(pattern));
597 pattern_interval = get_integer();
606 show_device_modem_select(uint8_t level)
612 retval = usb_ts_show_menu(level, "Select Modem Model",
614 "x) Return to previous menu\n");
620 show_default_modem_select(level + 1);
629 show_device_generic_select(uint8_t level)
634 show_device_select(uint8_t level)
640 retval = usb_ts_show_menu(level, "Select Device Mode Test Group",
641 "1) Audio (UAUDIO)\n"
642 "2) Mass Storage (MSC)\n"
643 "3) Ethernet (CDCE)\n"
644 "4) Keyboard Input Device (UKBD)\n"
645 "5) Mouse Input Device (UMS)\n"
646 "6) Message Transfer Protocol (MTP)\n"
648 "8) Generic Endpoint Loopback (GENERIC)\n"
649 "x) Return to previous menu\n");
655 show_device_audio_select(level + 1);
658 show_device_msc_select(level + 1);
661 show_device_ethernet_select(level + 1);
664 show_device_keyboard_select(level + 1);
667 show_device_mouse_select(level + 1);
670 show_device_mtp_select(level + 1);
673 show_device_modem_select(level + 1);
676 show_device_generic_select(level + 1);
685 show_host_select(uint8_t level)
689 uint32_t duration = 60;
691 uint16_t dev_vid = 0;
692 uint16_t dev_pid = 0;
697 error = sysctlbyname("hw.usb.ehci.no_hs", NULL, NULL,
698 &force_fs, sizeof(force_fs));
701 printf("WARNING: Could not set non-FS mode "
702 "to %d (error=%d)\n", force_fs, errno);
704 retval = usb_ts_show_menu(level, "Select Host Mode Test (via LibUSB)",
705 " 1) Select USB device (VID=0x%04x, PID=0x%04x)\n"
706 " 2) Manually enter USB vendor and product ID\n"
707 " 3) Force FULL speed operation: <%s>\n"
708 " 4) Mass Storage (UMASS)\n"
709 " 5) Modem (UMODEM)\n"
710 "10) Start String Descriptor Test\n"
711 "11) Start Port Reset Test\n"
712 "12) Start Set Config Test\n"
713 "13) Start Get Descriptor Test\n"
714 "14) Start Suspend and Resume Test\n"
715 "15) Start Set and Clear Endpoint Stall Test\n"
716 "16) Start Set Alternate Interface Setting Test\n"
717 "17) Start Invalid Control Request Test\n"
718 "30) Duration: <%d> seconds\n"
719 "x) Return to previous menu\n",
721 force_fs ? "YES" : "NO",
728 show_host_device_selection(level + 1, &dev_vid, &dev_pid);
731 dev_vid = get_integer() & 0xFFFF;
732 dev_pid = get_integer() & 0xFFFF;
738 show_host_msc_test(level + 1, dev_vid, dev_pid, duration);
741 show_host_modem_test(level + 1, dev_vid, dev_pid, duration);
744 usb_get_string_desc_test(dev_vid, dev_pid);
747 usb_port_reset_test(dev_vid, dev_pid, duration);
750 usb_set_config_test(dev_vid, dev_pid, duration);
753 usb_get_descriptor_test(dev_vid, dev_pid, duration);
756 usb_suspend_resume_test(dev_vid, dev_pid, duration);
759 usb_set_and_clear_stall_test(dev_vid, dev_pid);
762 usb_set_alt_interface_test(dev_vid, dev_pid);
765 usb_control_ep_error_test(dev_vid, dev_pid);
768 duration = get_integer();
777 show_mode_select(uint8_t level)
783 retval = usb_ts_show_menu(level, "Select Computer Mode",
784 "1) This computer is Running the Device Side\n"
785 "2) This computer is Running the Host Side\n"
786 "x) Return to previous menu\n");
792 show_device_select(level + 1);
795 show_host_select(level + 1);
804 main(int argc, char **argv)