usbtest.c revision 4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <errno.h>
33
34#include <sys/time.h>
35
36#include "usb.h"
37
38static unsigned arg_size = 4096;
39static unsigned arg_count = 4096;
40
41long long NOW(void)
42{
43    struct timeval tv;
44    gettimeofday(&tv, 0);
45
46    return (((long long) tv.tv_sec) * ((long long) 1000000)) +
47        (((long long) tv.tv_usec));
48}
49
50int printifc(usb_ifc_info *info)
51{
52    printf("dev: csp=%02x/%02x/%02x v=%04x p=%04x  ",
53           info->dev_class, info->dev_subclass, info->dev_protocol,
54           info->dev_vendor, info->dev_product);
55    printf("ifc: csp=%02x/%02x/%02x%s%s\n",
56           info->ifc_class, info->ifc_subclass, info->ifc_protocol,
57           info->has_bulk_in ? " in" : "",
58           info->has_bulk_out ? " out" : "");
59    return -1;
60}
61
62int match_null(usb_ifc_info *info)
63{
64    if(info->dev_vendor != 0x18d1) return -1;
65    if(info->ifc_class != 0xff) return -1;
66    if(info->ifc_subclass != 0xfe) return -1;
67    if(info->ifc_protocol != 0x01) return -1;
68    return 0;
69}
70
71int match_zero(usb_ifc_info *info)
72{
73    if(info->dev_vendor != 0x18d1) return -1;
74    if(info->ifc_class != 0xff) return -1;
75    if(info->ifc_subclass != 0xfe) return -1;
76    if(info->ifc_protocol != 0x02) return -1;
77    return 0;
78}
79
80int match_loop(usb_ifc_info *info)
81{
82    if(info->dev_vendor != 0x18d1) return -1;
83    if(info->ifc_class != 0xff) return -1;
84    if(info->ifc_subclass != 0xfe) return -1;
85    if(info->ifc_protocol != 0x03) return -1;
86    return 0;
87}
88
89int test_null(usb_handle *usb)
90{
91    int i;
92    unsigned char buf[4096];
93    memset(buf, 0xee, 4096);
94    long long t0, t1;
95
96    t0 = NOW();
97    for(i = 0; i < arg_count; i++) {
98        if(usb_write(usb, buf, arg_size) != arg_size) {
99            fprintf(stderr,"write failed (%s)\n", strerror(errno));
100            return -1;
101        }
102    }
103    t1 = NOW();
104    fprintf(stderr,"%d bytes in %lld uS\n", arg_count * arg_size, (t1 - t0));
105    return 0;
106}
107
108int test_zero(usb_handle *usb)
109{
110    int i;
111    unsigned char buf[4096];
112    long long t0, t1;
113
114    t0 = NOW();
115    for(i = 0; i < arg_count; i++) {
116        if(usb_read(usb, buf, arg_size) != arg_size) {
117            fprintf(stderr,"read failed (%s)\n", strerror(errno));
118            return -1;
119        }
120    }
121    t1 = NOW();
122    fprintf(stderr,"%d bytes in %lld uS\n", arg_count * arg_size, (t1 - t0));
123    return 0;
124}
125
126struct
127{
128    const char *cmd;
129    ifc_match_func match;
130    int (*test)(usb_handle *usb);
131    const char *help;
132} tests[] = {
133    { "list", printifc,   0,         "list interfaces" },
134    { "send", match_null, test_null, "send to null interface" },
135    { "recv", match_zero, test_zero, "recv from zero interface" },
136    { "loop", match_loop, 0,         "exercise loopback interface" },
137    {},
138};
139
140int usage(void)
141{
142    int i;
143
144    fprintf(stderr,"usage: usbtest <testname>\n\navailable tests:\n");
145    for(i = 0; tests[i].cmd; i++) {
146        fprintf(stderr," %-8s %s\n", tests[i].cmd, tests[i].help);
147    }
148    return -1;
149}
150
151int process_args(int argc, char **argv)
152{
153    while(argc-- > 0) {
154        char *arg = *argv++;
155        if(!strncmp(arg,"count=",6)) {
156            arg_count = atoi(arg + 6);
157        } else if(!strncmp(arg,"size=",5)) {
158            arg_size = atoi(arg + 5);
159        } else {
160            fprintf(stderr,"unknown argument: %s\n", arg);
161            return -1;
162        }
163    }
164
165    if(arg_count == 0) {
166        fprintf(stderr,"count may not be zero\n");
167        return -1;
168    }
169
170    if(arg_size > 4096) {
171        fprintf(stderr,"size may not be greater than 4096\n");
172        return -1;
173    }
174
175    return 0;
176}
177
178int main(int argc, char **argv)
179{
180    usb_handle *usb;
181    int i;
182
183    if(argc < 2)
184        return usage();
185
186    if(argc > 2) {
187        if(process_args(argc - 2, argv + 2))
188            return -1;
189    }
190
191    for(i = 0; tests[i].cmd; i++) {
192        if(!strcmp(argv[1], tests[i].cmd)) {
193            usb = usb_open(tests[i].match);
194            if(tests[i].test) {
195                if(usb == 0) {
196                    fprintf(stderr,"usbtest: %s: could not find interface\n",
197                            tests[i].cmd);
198                    return -1;
199                }
200                if(tests[i].test(usb)) {
201                    fprintf(stderr,"usbtest: %s: FAIL\n", tests[i].cmd);
202                    return -1;
203                } else {
204                    fprintf(stderr,"usbtest: %s: OKAY\n", tests[i].cmd);
205                }
206            }
207            return 0;
208        }
209    }
210
211    return usage();
212}
213