1254159Shselasky/* $FreeBSD$ */
2254159Shselasky/*-
3254159Shselasky * Copyright (c) 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 <err.h>
30254159Shselasky#include <string.h>
31254159Shselasky#include <errno.h>
32254159Shselasky#include <stdarg.h>
33254159Shselasky#include <stdlib.h>
34254159Shselasky
35254159Shselasky#include <sys/types.h>
36254159Shselasky#include <sys/sysctl.h>
37254159Shselasky
38254159Shselasky#include <dev/usb/usb_ioctl.h>
39254159Shselasky
40254159Shselasky#include "usbtest.h"
41254159Shselasky
42254159Shselasky#include <g_keyboard.h>
43254159Shselasky#include <g_mouse.h>
44254159Shselasky#include <g_modem.h>
45254159Shselasky#include <g_audio.h>
46254159Shselasky
47254159Shselaskystatic uint8_t usb_ts_select[USB_TS_MAX_LEVELS];
48254159Shselasky
49254159Shselaskyconst char *indent[USB_TS_MAX_LEVELS] = {
50254159Shselasky	" ",
51254159Shselasky	"   ",
52254159Shselasky	"     ",
53254159Shselasky	"       ",
54254159Shselasky	"         ",
55254159Shselasky	"           ",
56254159Shselasky	"             ",
57254159Shselasky	"               ",
58254159Shselasky};
59254159Shselasky
60254159Shselasky/* a perceptual white noise generator (after HPS' invention) */
61254159Shselasky
62254159Shselaskyint32_t
63254159Shselaskyusb_ts_rand_noise(void)
64254159Shselasky{
65254159Shselasky	uint32_t temp;
66254159Shselasky	const uint32_t prime = 0xFFFF1D;
67254159Shselasky	static uint32_t noise_rem = 1;
68254159Shselasky
69254159Shselasky	if (noise_rem & 1) {
70254159Shselasky		noise_rem += prime;
71254159Shselasky	}
72254159Shselasky	noise_rem /= 2;
73254159Shselasky
74254159Shselasky	temp = noise_rem;
75254159Shselasky
76254159Shselasky	/* unsigned to signed conversion */
77254159Shselasky
78254159Shselasky	temp ^= 0x800000;
79254159Shselasky	if (temp & 0x800000) {
80254159Shselasky		temp |= (-0x800000);
81254159Shselasky	}
82254159Shselasky	return temp;
83254159Shselasky}
84254159Shselasky
85254159Shselaskyuint8_t
86254159Shselaskyusb_ts_show_menu(uint8_t level, const char *title, const char *fmt,...)
87254159Shselasky{
88254159Shselasky	va_list args;
89254159Shselasky	uint8_t x;
90254159Shselasky	uint8_t retval;
91254159Shselasky	char *pstr;
92254159Shselasky	char buf[16];
93254159Shselasky	char menu[80 * 20];
94254159Shselasky
95254159Shselasky	va_start(args, fmt);
96254159Shselasky	vsnprintf(menu, sizeof(menu), fmt, args);
97254159Shselasky	va_end(args);
98254159Shselasky
99254159Shselasky	printf("[");
100254159Shselasky
101254159Shselasky	for (x = 0; x != level; x++) {
102254159Shselasky		if ((x + 1) == level)
103254159Shselasky			printf("%d", usb_ts_select[x]);
104254159Shselasky		else
105254159Shselasky			printf("%d.", usb_ts_select[x]);
106254159Shselasky	}
107254159Shselasky
108254159Shselasky	printf("] - %s:\n\n", title);
109254159Shselasky
110254159Shselasky	x = 1;
111254159Shselasky	for (pstr = menu; *pstr; pstr++) {
112254159Shselasky		if (x != 0) {
113254159Shselasky			printf("%s", indent[level]);
114254159Shselasky			x = 0;
115254159Shselasky		}
116254159Shselasky		printf("%c", *pstr);
117254159Shselasky
118254159Shselasky		if (*pstr == '\n')
119254159Shselasky			x = 1;
120254159Shselasky	}
121254159Shselasky
122254159Shselasky	printf("\n>");
123254159Shselasky
124254159Shselasky	if (fgets(buf, sizeof(buf), stdin) == NULL)
125254159Shselasky		err(1, "Cannot read input");
126254159Shselasky
127254159Shselasky	if (buf[0] == 'x')
128254159Shselasky		retval = 255;
129254159Shselasky	else
130254159Shselasky		retval = atoi(buf);
131254159Shselasky
132254159Shselasky	usb_ts_select[level] = retval;
133254159Shselasky
134254159Shselasky	return (retval);
135254159Shselasky}
136254159Shselasky
137254159Shselaskyvoid
138254159Shselaskyget_string(char *ptr, int size)
139254159Shselasky{
140254159Shselasky	printf("\nEnter string>");
141254159Shselasky
142254159Shselasky	if (fgets(ptr, size, stdin) == NULL)
143254159Shselasky		err(1, "Cannot read input");
144254159Shselasky
145254159Shselasky	ptr[size - 1] = 0;
146254159Shselasky
147254159Shselasky	size = strlen(ptr);
148254159Shselasky
149254159Shselasky	/* strip trailing newline, if any */
150254159Shselasky	if (size == 0)
151254159Shselasky		return;
152254159Shselasky	else if (ptr[size - 1] == '\n')
153254159Shselasky		ptr[size - 1] = 0;
154254159Shselasky}
155254159Shselasky
156254159Shselaskyint
157254159Shselaskyget_integer(void)
158254159Shselasky{
159254159Shselasky	char buf[32];
160254159Shselasky
161254159Shselasky	printf("\nEnter integer value>");
162254159Shselasky
163254159Shselasky	if (fgets(buf, sizeof(buf), stdin) == NULL)
164254159Shselasky		err(1, "Cannot read input");
165254159Shselasky
166254159Shselasky	if (strcmp(buf, "x\n") == 0)
167254159Shselasky		return (-1);
168254159Shselasky	if (strcmp(buf, "r\n") == 0)
169254159Shselasky		return (-2);
170254159Shselasky
171254159Shselasky	return ((int)strtol(buf, 0, 0));
172254159Shselasky}
173254159Shselasky
174254159Shselaskystatic void
175254159Shselaskyset_template(int template)
176254159Shselasky{
177254159Shselasky	int error;
178254159Shselasky
179254159Shselasky	error = sysctlbyname("hw.usb.template", NULL, NULL,
180254159Shselasky	    &template, sizeof(template));
181254159Shselasky
182254159Shselasky	if (error != 0) {
183254159Shselasky		printf("WARNING: Could not set USB template "
184254159Shselasky		    "to %d (error=%d)\n", template, errno);
185254159Shselasky	}
186254159Shselasky}
187254159Shselasky
188254159Shselaskystatic void
189254159Shselaskyshow_default_audio_select(uint8_t level)
190254159Shselasky{
191254159Shselasky	int error;
192254159Shselasky	int retval;
193254159Shselasky	int mode = 0;
194254159Shselasky	int pattern_interval = 128;
195254159Shselasky	int throughput = 0;
196254159Shselasky	size_t len;
197254159Shselasky	char pattern[G_AUDIO_MAX_STRLEN] = {"0123456789abcdef"};
198254159Shselasky
199254159Shselasky	set_template(USB_TEMP_AUDIO);
200254159Shselasky
201254159Shselasky	while (1) {
202254159Shselasky
203254159Shselasky		error = sysctlbyname("hw.usb.g_audio.mode", NULL, NULL,
204254159Shselasky		    &mode, sizeof(mode));
205254159Shselasky
206254159Shselasky		if (error != 0) {
207254159Shselasky			printf("WARNING: Could not set audio mode "
208254159Shselasky			    "to %d (error=%d)\n", mode, errno);
209254159Shselasky		}
210254159Shselasky		error = sysctlbyname("hw.usb.g_audio.pattern_interval", NULL, NULL,
211254159Shselasky		    &pattern_interval, sizeof(pattern_interval));
212254159Shselasky
213254159Shselasky		if (error != 0) {
214254159Shselasky			printf("WARNING: Could not set pattern interval "
215254159Shselasky			    "to %d (error=%d)\n", pattern_interval, errno);
216254159Shselasky		}
217254159Shselasky		len = sizeof(throughput);
218254159Shselasky
219254159Shselasky		error = sysctlbyname("hw.usb.g_audio.throughput",
220254159Shselasky		    &throughput, &len, 0, 0);
221254159Shselasky
222254159Shselasky		if (error != 0) {
223254159Shselasky			printf("WARNING: Could not get throughput "
224254159Shselasky			    "(error=%d)\n", errno);
225254159Shselasky		}
226254159Shselasky		error = sysctlbyname("hw.usb.g_audio.pattern", NULL, NULL,
227254159Shselasky		    &pattern, strlen(pattern));
228254159Shselasky
229254159Shselasky		if (error != 0) {
230254159Shselasky			printf("WARNING: Could not set audio pattern "
231254159Shselasky			    "to '%s' (error=%d)\n", pattern, errno);
232254159Shselasky		}
233254159Shselasky		retval = usb_ts_show_menu(level, "Default Audio Settings",
234254159Shselasky		    "1) Set Silent mode %s\n"
235254159Shselasky		    "2) Set Dump mode %s\n"
236254159Shselasky		    "3) Set Loop mode %s\n"
237254159Shselasky		    "4) Set Pattern mode %s\n"
238254159Shselasky		    "5) Change DTMF pattern: '%s'\n"
239254159Shselasky		    "6) Change pattern advance interval: %d ms\n"
240254159Shselasky		    "x) Return to previous menu\n"
241254159Shselasky		    "s: Ready for enumeration\n"
242254159Shselasky		    "t: Throughput: %d bytes/second\n",
243254159Shselasky		    (mode == G_AUDIO_MODE_SILENT) ? "(selected)" : "",
244254159Shselasky		    (mode == G_AUDIO_MODE_DUMP) ? "(selected)" : "",
245254159Shselasky		    (mode == G_AUDIO_MODE_LOOP) ? "(selected)" : "",
246254159Shselasky		    (mode == G_AUDIO_MODE_PATTERN) ? "(selected)" : "",
247254159Shselasky		    pattern, pattern_interval, throughput);
248254159Shselasky
249254159Shselasky		switch (retval) {
250254159Shselasky		case 0:
251254159Shselasky			break;
252254159Shselasky		case 1:
253254159Shselasky			mode = G_AUDIO_MODE_SILENT;
254254159Shselasky			break;
255254159Shselasky		case 2:
256254159Shselasky			mode = G_AUDIO_MODE_DUMP;
257254159Shselasky			break;
258254159Shselasky		case 3:
259254159Shselasky			mode = G_AUDIO_MODE_LOOP;
260254159Shselasky			break;
261254159Shselasky		case 4:
262254159Shselasky			mode = G_AUDIO_MODE_PATTERN;
263254159Shselasky			break;
264254159Shselasky		case 5:
265254159Shselasky			get_string(pattern, sizeof(pattern));
266254159Shselasky			break;
267254159Shselasky		case 6:
268254159Shselasky			pattern_interval = get_integer();
269254159Shselasky			break;
270254159Shselasky		default:
271254159Shselasky			return;
272254159Shselasky		}
273254159Shselasky	}
274254159Shselasky}
275254159Shselasky
276254159Shselaskystatic void
277254159Shselaskyshow_device_audio_select(uint8_t level)
278254159Shselasky{
279254159Shselasky	uint8_t retval;
280254159Shselasky
281254159Shselasky	while (1) {
282254159Shselasky
283254159Shselasky		retval = usb_ts_show_menu(level, "Select Audio Device Model",
284254159Shselasky		    "1) Generic Audio Device\n"
285254159Shselasky		    "x) Return to previous menu\n");
286254159Shselasky
287254159Shselasky		switch (retval) {
288254159Shselasky		case 0:
289254159Shselasky			break;
290254159Shselasky		case 1:
291254159Shselasky			show_default_audio_select(level + 1);
292254159Shselasky			break;
293254159Shselasky		default:
294254159Shselasky			return;
295254159Shselasky		}
296254159Shselasky	}
297254159Shselasky}
298254159Shselasky
299254159Shselaskystatic void
300254159Shselaskyshow_device_msc_select(uint8_t level)
301254159Shselasky{
302254159Shselasky	set_template(USB_TEMP_MSC);
303254159Shselasky}
304254159Shselasky
305254159Shselaskystatic void
306254159Shselaskyshow_device_ethernet_select(uint8_t level)
307254159Shselasky{
308254159Shselasky	set_template(USB_TEMP_CDCE);
309254159Shselasky}
310254159Shselasky
311254159Shselaskystatic void
312254159Shselaskyshow_default_keyboard_select(uint8_t level)
313254159Shselasky{
314254159Shselasky	int error;
315254159Shselasky	int retval;
316254159Shselasky	int mode = 0;
317254159Shselasky	int interval = 1023;
318254159Shselasky	char pattern[G_KEYBOARD_MAX_STRLEN] = {"abcdefpattern"};
319254159Shselasky
320254159Shselasky	set_template(USB_TEMP_KBD);
321254159Shselasky
322254159Shselasky	while (1) {
323254159Shselasky
324254159Shselasky		error = sysctlbyname("hw.usb.g_keyboard.mode", NULL, NULL,
325254159Shselasky		    &mode, sizeof(mode));
326254159Shselasky
327254159Shselasky		if (error != 0) {
328254159Shselasky			printf("WARNING: Could not set keyboard mode "
329254159Shselasky			    " to %d (error=%d) \n", mode, errno);
330254159Shselasky		}
331254159Shselasky		error = sysctlbyname("hw.usb.g_keyboard.key_press_interval", NULL, NULL,
332254159Shselasky		    &interval, sizeof(interval));
333254159Shselasky
334254159Shselasky		if (error != 0) {
335254159Shselasky			printf("WARNING: Could not set key press interval "
336254159Shselasky			    "to %d (error=%d)\n", interval, errno);
337254159Shselasky		}
338254159Shselasky		error = sysctlbyname("hw.usb.g_keyboard.key_press_pattern", NULL, NULL,
339254159Shselasky		    &pattern, strlen(pattern));
340254159Shselasky
341254159Shselasky		if (error != 0) {
342254159Shselasky			printf("WARNING: Could not set key pattern "
343254159Shselasky			    "to '%s' (error=%d)\n", pattern, errno);
344254159Shselasky		}
345254159Shselasky		retval = usb_ts_show_menu(level, "Default Keyboard Settings",
346254159Shselasky		    "1) Set silent mode %s\n"
347254159Shselasky		    "2) Set pattern mode %s\n"
348254159Shselasky		    "3) Change pattern: '%s'\n"
349254159Shselasky		    "4) Change key press interval: %d ms\n"
350254159Shselasky		    "x) Return to previous menu\n"
351254159Shselasky		    "s: Ready for enumeration\n",
352254159Shselasky		    (mode == G_KEYBOARD_MODE_SILENT) ? "(selected)" : "",
353254159Shselasky		    (mode == G_KEYBOARD_MODE_PATTERN) ? "(selected)" : "",
354254159Shselasky		    pattern, interval);
355254159Shselasky
356254159Shselasky		switch (retval) {
357254159Shselasky		case 0:
358254159Shselasky			break;
359254159Shselasky		case 1:
360254159Shselasky			mode = G_KEYBOARD_MODE_SILENT;
361254159Shselasky			break;
362254159Shselasky		case 2:
363254159Shselasky			mode = G_KEYBOARD_MODE_PATTERN;
364254159Shselasky			break;
365254159Shselasky		case 3:
366254159Shselasky			get_string(pattern, sizeof(pattern));
367254159Shselasky			break;
368254159Shselasky		case 4:
369254159Shselasky			interval = get_integer();
370254159Shselasky			break;
371254159Shselasky		default:
372254159Shselasky			return;
373254159Shselasky		}
374254159Shselasky	}
375254159Shselasky}
376254159Shselasky
377254159Shselaskystatic void
378254159Shselaskyshow_device_keyboard_select(uint8_t level)
379254159Shselasky{
380254159Shselasky	uint8_t retval;
381254159Shselasky
382254159Shselasky	while (1) {
383254159Shselasky
384254159Shselasky		retval = usb_ts_show_menu(level, "Select Keyboard Model",
385254159Shselasky		    "1) Generic Keyboard \n"
386254159Shselasky		    "x) Return to previous menu \n");
387254159Shselasky
388254159Shselasky		switch (retval) {
389254159Shselasky		case 0:
390254159Shselasky			break;
391254159Shselasky		case 1:
392254159Shselasky			show_default_keyboard_select(level + 1);
393254159Shselasky			break;
394254159Shselasky		default:
395254159Shselasky			return;
396254159Shselasky		}
397254159Shselasky	}
398254159Shselasky}
399254159Shselasky
400254159Shselaskystatic void
401254159Shselaskyshow_default_mouse_select(uint8_t level)
402254159Shselasky{
403254159Shselasky	int error;
404254159Shselasky	int retval;
405254159Shselasky	int mode = 0;
406254159Shselasky	int cursor_interval = 128;
407254159Shselasky	int cursor_radius = 75;
408254159Shselasky	int button_interval = 0;
409254159Shselasky
410254159Shselasky	set_template(USB_TEMP_MOUSE);
411254159Shselasky
412254159Shselasky	while (1) {
413254159Shselasky
414254159Shselasky		error = sysctlbyname("hw.usb.g_mouse.mode", NULL, NULL,
415254159Shselasky		    &mode, sizeof(mode));
416254159Shselasky
417254159Shselasky		if (error != 0) {
418254159Shselasky			printf("WARNING: Could not set mouse mode "
419254159Shselasky			    "to %d (error=%d)\n", mode, errno);
420254159Shselasky		}
421254159Shselasky		error = sysctlbyname("hw.usb.g_mouse.cursor_update_interval", NULL, NULL,
422254159Shselasky		    &cursor_interval, sizeof(cursor_interval));
423254159Shselasky
424254159Shselasky		if (error != 0) {
425254159Shselasky			printf("WARNING: Could not set cursor update interval "
426254159Shselasky			    "to %d (error=%d)\n", cursor_interval, errno);
427254159Shselasky		}
428254159Shselasky		error = sysctlbyname("hw.usb.g_mouse.button_press_interval", NULL, NULL,
429254159Shselasky		    &button_interval, sizeof(button_interval));
430254159Shselasky
431254159Shselasky		if (error != 0) {
432254159Shselasky			printf("WARNING: Could not set button press interval "
433254159Shselasky			    "to %d (error=%d)\n", button_interval, errno);
434254159Shselasky		}
435254159Shselasky		error = sysctlbyname("hw.usb.g_mouse.cursor_radius", NULL, NULL,
436254159Shselasky		    &cursor_radius, sizeof(cursor_radius));
437254159Shselasky
438254159Shselasky		if (error != 0) {
439254159Shselasky			printf("WARNING: Could not set cursor radius "
440254159Shselasky			    "to %d (error=%d)\n", cursor_radius, errno);
441254159Shselasky		}
442254159Shselasky		retval = usb_ts_show_menu(level, "Default Mouse Settings",
443254159Shselasky		    "1) Set Silent mode %s\n"
444254159Shselasky		    "2) Set Circle mode %s\n"
445254159Shselasky		    "3) Set Square mode %s\n"
446254159Shselasky		    "4) Set Spiral mode %s\n"
447254159Shselasky		    "5) Change cursor radius: %d pixels\n"
448254159Shselasky		    "6) Change cursor update interval: %d ms\n"
449254159Shselasky		    "7) Change button[0] press interval: %d ms\n"
450254159Shselasky		    "x) Return to previous menu\n"
451254159Shselasky		    "s: Ready for enumeration\n",
452254159Shselasky		    (mode == G_MOUSE_MODE_SILENT) ? "(selected)" : "",
453254159Shselasky		    (mode == G_MOUSE_MODE_CIRCLE) ? "(selected)" : "",
454254159Shselasky		    (mode == G_MOUSE_MODE_BOX) ? "(selected)" : "",
455254159Shselasky		    (mode == G_MOUSE_MODE_SPIRAL) ? "(selected)" : "",
456254159Shselasky		    cursor_radius, cursor_interval, button_interval);
457254159Shselasky
458254159Shselasky		switch (retval) {
459254159Shselasky		case 0:
460254159Shselasky			break;
461254159Shselasky		case 1:
462254159Shselasky			mode = G_MOUSE_MODE_SILENT;
463254159Shselasky			break;
464254159Shselasky		case 2:
465254159Shselasky			mode = G_MOUSE_MODE_CIRCLE;
466254159Shselasky			break;
467254159Shselasky		case 3:
468254159Shselasky			mode = G_MOUSE_MODE_BOX;
469254159Shselasky			break;
470254159Shselasky		case 4:
471254159Shselasky			mode = G_MOUSE_MODE_SPIRAL;
472254159Shselasky			break;
473254159Shselasky		case 5:
474254159Shselasky			cursor_radius = get_integer();
475254159Shselasky			break;
476254159Shselasky		case 6:
477254159Shselasky			cursor_interval = get_integer();
478254159Shselasky			break;
479254159Shselasky		case 7:
480254159Shselasky			button_interval = get_integer();
481254159Shselasky			break;
482254159Shselasky		default:
483254159Shselasky			return;
484254159Shselasky		}
485254159Shselasky	}
486254159Shselasky}
487254159Shselasky
488254159Shselaskystatic void
489254159Shselaskyshow_device_mouse_select(uint8_t level)
490254159Shselasky{
491254159Shselasky	uint8_t retval;
492254159Shselasky
493254159Shselasky	while (1) {
494254159Shselasky
495254159Shselasky		retval = usb_ts_show_menu(level, "Select Mouse Model",
496254159Shselasky		    "1) Generic Mouse\n"
497254159Shselasky		    "x) Return to previous menu\n");
498254159Shselasky
499254159Shselasky		switch (retval) {
500254159Shselasky		case 0:
501254159Shselasky			break;
502254159Shselasky		case 1:
503254159Shselasky			show_default_mouse_select(level + 1);
504254159Shselasky			break;
505254159Shselasky		default:
506254159Shselasky			return;
507254159Shselasky		}
508254159Shselasky	}
509254159Shselasky}
510254159Shselasky
511254159Shselaskystatic void
512254159Shselaskyshow_device_mtp_select(uint8_t level)
513254159Shselasky{
514254159Shselasky	set_template(USB_TEMP_MTP);
515254159Shselasky}
516254159Shselasky
517254159Shselaskystatic void
518254159Shselaskyshow_default_modem_select(uint8_t level)
519254159Shselasky{
520254159Shselasky	int error;
521254159Shselasky	int retval;
522254159Shselasky	int mode = 0;
523254159Shselasky	int pattern_interval = 128;
524254159Shselasky	int throughput = 0;
525254159Shselasky	size_t len;
526254159Shselasky	char pattern[G_MODEM_MAX_STRLEN] = {"abcdefpattern"};
527254159Shselasky
528254159Shselasky	set_template(USB_TEMP_MODEM);
529254159Shselasky
530254159Shselasky	while (1) {
531254159Shselasky
532254159Shselasky		error = sysctlbyname("hw.usb.g_modem.mode", NULL, NULL,
533254159Shselasky		    &mode, sizeof(mode));
534254159Shselasky
535254159Shselasky		if (error != 0) {
536254159Shselasky			printf("WARNING: Could not set modem mode "
537254159Shselasky			    "to %d (error=%d)\n", mode, errno);
538254159Shselasky		}
539254159Shselasky		error = sysctlbyname("hw.usb.g_modem.pattern_interval", NULL, NULL,
540254159Shselasky		    &pattern_interval, sizeof(pattern_interval));
541254159Shselasky
542254159Shselasky		if (error != 0) {
543254159Shselasky			printf("WARNING: Could not set pattern interval "
544254159Shselasky			    "to %d (error=%d)\n", pattern_interval, errno);
545254159Shselasky		}
546254159Shselasky		len = sizeof(throughput);
547254159Shselasky
548254159Shselasky		error = sysctlbyname("hw.usb.g_modem.throughput",
549254159Shselasky		    &throughput, &len, 0, 0);
550254159Shselasky
551254159Shselasky		if (error != 0) {
552254159Shselasky			printf("WARNING: Could not get throughput "
553254159Shselasky			    "(error=%d)\n", errno);
554254159Shselasky		}
555254159Shselasky		error = sysctlbyname("hw.usb.g_modem.pattern", NULL, NULL,
556254159Shselasky		    &pattern, strlen(pattern));
557254159Shselasky
558254159Shselasky		if (error != 0) {
559254159Shselasky			printf("WARNING: Could not set modem pattern "
560254159Shselasky			    "to '%s' (error=%d)\n", pattern, errno);
561254159Shselasky		}
562254159Shselasky		retval = usb_ts_show_menu(level, "Default Modem Settings",
563254159Shselasky		    "1) Set Silent mode %s\n"
564254159Shselasky		    "2) Set Dump mode %s\n"
565254159Shselasky		    "3) Set Loop mode %s\n"
566254159Shselasky		    "4) Set Pattern mode %s\n"
567254159Shselasky		    "5) Change test pattern: '%s'\n"
568254159Shselasky		    "6) Change data transmit interval: %d ms\n"
569254159Shselasky		    "x) Return to previous menu\n"
570254159Shselasky		    "s: Ready for enumeration\n"
571254159Shselasky		    "t: Throughput: %d bytes/second\n",
572254159Shselasky		    (mode == G_MODEM_MODE_SILENT) ? "(selected)" : "",
573254159Shselasky		    (mode == G_MODEM_MODE_DUMP) ? "(selected)" : "",
574254159Shselasky		    (mode == G_MODEM_MODE_LOOP) ? "(selected)" : "",
575254159Shselasky		    (mode == G_MODEM_MODE_PATTERN) ? "(selected)" : "",
576254159Shselasky		    pattern, pattern_interval, throughput);
577254159Shselasky
578254159Shselasky		switch (retval) {
579254159Shselasky		case 0:
580254159Shselasky			break;
581254159Shselasky		case 1:
582254159Shselasky			mode = G_MODEM_MODE_SILENT;
583254159Shselasky			break;
584254159Shselasky		case 2:
585254159Shselasky			mode = G_MODEM_MODE_DUMP;
586254159Shselasky			break;
587254159Shselasky		case 3:
588254159Shselasky			mode = G_MODEM_MODE_LOOP;
589254159Shselasky			break;
590254159Shselasky		case 4:
591254159Shselasky			mode = G_MODEM_MODE_PATTERN;
592254159Shselasky			break;
593254159Shselasky		case 5:
594254159Shselasky			get_string(pattern, sizeof(pattern));
595254159Shselasky			break;
596254159Shselasky		case 6:
597254159Shselasky			pattern_interval = get_integer();
598254159Shselasky			break;
599254159Shselasky		default:
600254159Shselasky			return;
601254159Shselasky		}
602254159Shselasky	}
603254159Shselasky}
604254159Shselasky
605254159Shselaskystatic void
606254159Shselaskyshow_device_modem_select(uint8_t level)
607254159Shselasky{
608254159Shselasky	uint8_t retval;
609254159Shselasky
610254159Shselasky	while (1) {
611254159Shselasky
612254159Shselasky		retval = usb_ts_show_menu(level, "Select Modem Model",
613254159Shselasky		    "1) Generic Modem\n"
614254159Shselasky		    "x) Return to previous menu\n");
615254159Shselasky
616254159Shselasky		switch (retval) {
617254159Shselasky		case 0:
618254159Shselasky			break;
619254159Shselasky		case 1:
620254159Shselasky			show_default_modem_select(level + 1);
621254159Shselasky			break;
622254159Shselasky		default:
623254159Shselasky			return;
624254159Shselasky		}
625254159Shselasky	}
626254159Shselasky}
627254159Shselasky
628254159Shselaskystatic void
629254159Shselaskyshow_device_generic_select(uint8_t level)
630254159Shselasky{
631254159Shselasky}
632254159Shselasky
633254159Shselaskystatic void
634254159Shselaskyshow_device_select(uint8_t level)
635254159Shselasky{
636254159Shselasky	uint8_t retval;
637254159Shselasky
638254159Shselasky	while (1) {
639254159Shselasky
640254159Shselasky		retval = usb_ts_show_menu(level, "Select Device Mode Test Group",
641254159Shselasky		    "1) Audio (UAUDIO)\n"
642254159Shselasky		    "2) Mass Storage (MSC)\n"
643254159Shselasky		    "3) Ethernet (CDCE)\n"
644254159Shselasky		    "4) Keyboard Input Device (UKBD)\n"
645254159Shselasky		    "5) Mouse Input Device (UMS)\n"
646254159Shselasky		    "6) Message Transfer Protocol (MTP)\n"
647254159Shselasky		    "7) Modem (CDC)\n"
648254159Shselasky		    "8) Generic Endpoint Loopback (GENERIC)\n"
649254159Shselasky		    "x) Return to previous menu\n");
650254159Shselasky
651254159Shselasky		switch (retval) {
652254159Shselasky		case 0:
653254159Shselasky			break;
654254159Shselasky		case 1:
655254159Shselasky			show_device_audio_select(level + 1);
656254159Shselasky			break;
657254159Shselasky		case 2:
658254159Shselasky			show_device_msc_select(level + 1);
659254159Shselasky			break;
660254159Shselasky		case 3:
661254159Shselasky			show_device_ethernet_select(level + 1);
662254159Shselasky			break;
663254159Shselasky		case 4:
664254159Shselasky			show_device_keyboard_select(level + 1);
665254159Shselasky			break;
666254159Shselasky		case 5:
667254159Shselasky			show_device_mouse_select(level + 1);
668254159Shselasky			break;
669254159Shselasky		case 6:
670254159Shselasky			show_device_mtp_select(level + 1);
671254159Shselasky			break;
672254159Shselasky		case 7:
673254159Shselasky			show_device_modem_select(level + 1);
674254159Shselasky			break;
675254159Shselasky		case 8:
676254159Shselasky			show_device_generic_select(level + 1);
677254159Shselasky			break;
678254159Shselasky		default:
679254159Shselasky			return;
680254159Shselasky		}
681254159Shselasky	}
682254159Shselasky}
683254159Shselasky
684254159Shselaskystatic void
685254159Shselaskyshow_host_select(uint8_t level)
686254159Shselasky{
687254159Shselasky	int force_fs = 0;
688254159Shselasky	int error;
689254159Shselasky	uint32_t duration = 60;
690254159Shselasky
691254159Shselasky	uint16_t dev_vid = 0;
692254159Shselasky	uint16_t dev_pid = 0;
693254159Shselasky	uint8_t retval;
694254159Shselasky
695254159Shselasky	while (1) {
696254159Shselasky
697254159Shselasky		error = sysctlbyname("hw.usb.ehci.no_hs", NULL, NULL,
698254159Shselasky		    &force_fs, sizeof(force_fs));
699254159Shselasky
700254159Shselasky		if (error != 0) {
701254159Shselasky			printf("WARNING: Could not set non-FS mode "
702254159Shselasky			    "to %d (error=%d)\n", force_fs, errno);
703254159Shselasky		}
704254159Shselasky		retval = usb_ts_show_menu(level, "Select Host Mode Test (via LibUSB)",
705254159Shselasky		    " 1) Select USB device (VID=0x%04x, PID=0x%04x)\n"
706254159Shselasky		    " 2) Manually enter USB vendor and product ID\n"
707254159Shselasky		    " 3) Force FULL speed operation: <%s>\n"
708254159Shselasky		    " 4) Mass Storage (UMASS)\n"
709254159Shselasky		    " 5) Modem (UMODEM)\n"
710254159Shselasky		    "10) Start String Descriptor Test\n"
711254159Shselasky		    "11) Start Port Reset Test\n"
712254159Shselasky		    "12) Start Set Config Test\n"
713254159Shselasky		    "13) Start Get Descriptor Test\n"
714254159Shselasky		    "14) Start Suspend and Resume Test\n"
715254159Shselasky		    "15) Start Set and Clear Endpoint Stall Test\n"
716254159Shselasky		    "16) Start Set Alternate Interface Setting Test\n"
717254159Shselasky		    "17) Start Invalid Control Request Test\n"
718254159Shselasky		    "30) Duration: <%d> seconds\n"
719254159Shselasky		    "x) Return to previous menu\n",
720254159Shselasky		    dev_vid, dev_pid,
721254159Shselasky		    force_fs ? "YES" : "NO",
722254159Shselasky		    (int)duration);
723254159Shselasky
724254159Shselasky		switch (retval) {
725254159Shselasky		case 0:
726254159Shselasky			break;
727254159Shselasky		case 1:
728254159Shselasky			show_host_device_selection(level + 1, &dev_vid, &dev_pid);
729254159Shselasky			break;
730254159Shselasky		case 2:
731254159Shselasky			dev_vid = get_integer() & 0xFFFF;
732254159Shselasky			dev_pid = get_integer() & 0xFFFF;
733254159Shselasky			break;
734254159Shselasky		case 3:
735254159Shselasky			force_fs ^= 1;
736254159Shselasky			break;
737254159Shselasky		case 4:
738254159Shselasky			show_host_msc_test(level + 1, dev_vid, dev_pid, duration);
739254159Shselasky			break;
740254159Shselasky		case 5:
741254159Shselasky			show_host_modem_test(level + 1, dev_vid, dev_pid, duration);
742254159Shselasky			break;
743254159Shselasky		case 10:
744254159Shselasky			usb_get_string_desc_test(dev_vid, dev_pid);
745254159Shselasky			break;
746254159Shselasky		case 11:
747254159Shselasky			usb_port_reset_test(dev_vid, dev_pid, duration);
748254159Shselasky			break;
749254159Shselasky		case 12:
750254159Shselasky			usb_set_config_test(dev_vid, dev_pid, duration);
751254159Shselasky			break;
752254159Shselasky		case 13:
753254159Shselasky			usb_get_descriptor_test(dev_vid, dev_pid, duration);
754254159Shselasky			break;
755254159Shselasky		case 14:
756254159Shselasky			usb_suspend_resume_test(dev_vid, dev_pid, duration);
757254159Shselasky			break;
758254159Shselasky		case 15:
759254159Shselasky			usb_set_and_clear_stall_test(dev_vid, dev_pid);
760254159Shselasky			break;
761254159Shselasky		case 16:
762254159Shselasky			usb_set_alt_interface_test(dev_vid, dev_pid);
763254159Shselasky			break;
764254159Shselasky		case 17:
765254159Shselasky			usb_control_ep_error_test(dev_vid, dev_pid);
766254159Shselasky			break;
767254159Shselasky		case 30:
768254159Shselasky			duration = get_integer();
769254159Shselasky			break;
770254159Shselasky		default:
771254159Shselasky			return;
772254159Shselasky		}
773254159Shselasky	}
774254159Shselasky}
775254159Shselasky
776254159Shselaskystatic void
777254159Shselaskyshow_mode_select(uint8_t level)
778254159Shselasky{
779254159Shselasky	uint8_t retval;
780254159Shselasky
781254159Shselasky	while (1) {
782254159Shselasky
783254159Shselasky		retval = usb_ts_show_menu(level, "Select Computer Mode",
784254159Shselasky		    "1) This computer is Running the Device Side\n"
785254159Shselasky		    "2) This computer is Running the Host Side\n"
786254159Shselasky		    "x) Return to previous menu\n");
787254159Shselasky
788254159Shselasky		switch (retval) {
789254159Shselasky		case 0:
790254159Shselasky			break;
791254159Shselasky		case 1:
792254159Shselasky			show_device_select(level + 1);
793254159Shselasky			break;
794254159Shselasky		case 2:
795254159Shselasky			show_host_select(level + 1);
796254159Shselasky			break;
797254159Shselasky		default:
798254159Shselasky			return;
799254159Shselasky		}
800254159Shselasky	}
801254159Shselasky}
802254159Shselasky
803254159Shselaskyint
804254159Shselaskymain(int argc, char **argv)
805254159Shselasky{
806254159Shselasky	show_mode_select(1);
807254159Shselasky
808254159Shselasky	return (0);
809254159Shselasky}
810