VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/testcase/tstTrekStorGo.c@ 77807

Last change on this file since 77807 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1/* $Id: tstTrekStorGo.c 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * Some simple inquiry test for the TrekStor USB-Stick GO, linux usbfs
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <sys/vfs.h>
21#include <sys/ioctl.h>
22#include <sys/poll.h>
23#include <stdint.h>
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <limits.h>
28#include <unistd.h>
29#include <fcntl.h>
30#include <errno.h>
31#include <linux/usbdevice_fs.h>
32
33
34/** @name USB Control message recipient codes (from spec)
35 * @{ */
36#define VUSB_TO_DEVICE 0x0
37#define VUSB_TO_INTERFACE 0x1
38#define VUSB_TO_ENDPOINT 0x2
39#define VUSB_TO_OTHER 0x3
40#define VUSB_RECIP_MASK 0x1f
41/** @} */
42
43/** @name USB control pipe setup packet structure (from spec)
44 * @{ */
45#define VUSB_REQ_SHIFT (5)
46#define VUSB_REQ_STANDARD (0x0 << VUSB_REQ_SHIFT)
47#define VUSB_REQ_CLASS (0x1 << VUSB_REQ_SHIFT)
48#define VUSB_REQ_VENDOR (0x2 << VUSB_REQ_SHIFT)
49#define VUSB_REQ_RESERVED (0x3 << VUSB_REQ_SHIFT)
50#define VUSB_REQ_MASK (0x3 << VUSB_REQ_SHIFT)
51/** @} */
52
53#define VUSB_DIR_TO_HOST 0x80
54typedef struct vusb_setup
55{
56 uint8_t bmRequestType;
57 uint8_t bRequest;
58 uint16_t wValue;
59 uint16_t wIndex;
60 uint16_t wLength;
61} VUSBSETUP, *PVUSBSETUP;
62typedef const VUSBSETUP *PCVUSBSETUP;
63
64
65int g_fd;
66
67int bitch(const char *pszMsg)
68{
69 printf("failure: %s: %d %s\n", pszMsg, errno, strerror(errno));
70 return 1;
71}
72
73void hex(const void *pv, ssize_t cb, const char *pszWhat)
74{
75 printf("%s: cb=%d\n", pszWhat, cb);
76 unsigned char *pb = (unsigned char *)pv;
77 int cch = 0;
78 int off = 0;
79 int cchPrecision = 16;
80 while (off < cb)
81 {
82 int i;
83 printf("%s%0*x %04x:", off ? "\n" : "", sizeof(pb) * 2, (uintptr_t)pb, off);
84
85 for (i = 0; i < cchPrecision && off + i < cb; i++)
86 printf(off + i < cb ? !(i & 7) && i ? "-%02x" : " %02x" : " ", pb[i]);
87 while (i++ < cchPrecision)
88 printf(" ");
89 printf(" ");
90 for (i = 0; i < cchPrecision && off + i < cb; i++)
91 {
92 uint8_t u8 = pb[i];
93 fputc(u8 < 127 && u8 >= 32 ? u8 : '.', stdout);
94 }
95
96 /* next */
97 pb += cchPrecision;
98 off += cchPrecision;
99 }
100 printf("\n");
101}
102
103int doioctl(int iCmd, void *pvData, const char *pszWho)
104{
105 int rc;
106 do
107 {
108 errno = 0;
109 rc = ioctl(g_fd, iCmd, pvData);
110
111 } while (rc && errno == EAGAIN);
112 if (rc)
113 printf("doioctl: %s: iCmd=%#x errno=%d %s\n", pszWho, iCmd, errno, strerror(errno));
114 else
115 printf("doioctl: %s: iCmd=%#x ok\n", pszWho, iCmd);
116 return rc;
117}
118
119int dobulk(int EndPt, void *pvBuf, size_t cbBuf, const char *pszWho)
120{
121#if 0
122 struct usbdevfs_urb KUrb = {0};
123 KUrb.type = USBDEVFS_URB_TYPE_BULK;
124 KUrb.endpoint = EndPt;
125 KUrb.buffer = pvBuf;
126 KUrb.buffer_length = cbBuf;
127 KUrb.actual_length = 0; //cbBuf
128 KUrb.flags = 0; /* ISO_ASAP/SHORT_NOT_OK */
129 if (!doioctl(USBDEVFS_SUBMITURB, &KUrb, pszWho))
130 {
131 struct usbdevfs_urb *pKUrb = NULL;
132 if (!doioctl(USBDEVFS_REAPURB, &pKUrb, pszWho)
133 && pKUrb == &KUrb)
134 return KUrb.actual_length;
135 }
136 return -1;
137#else
138 struct usbdevfs_bulktransfer BulkMsg = {0};
139
140 BulkMsg.ep = EndPt;
141 BulkMsg.timeout = 1000;
142 BulkMsg.len = cbBuf;
143 BulkMsg.data = pvBuf;
144 int rc = doioctl(USBDEVFS_BULK, &BulkMsg, pszWho);
145// printf("rc=%d BulkMsg.len=%d cbBuf=%d\n", rc, BulkMsg.len, cbBuf);
146 if (rc >= 0)
147 return rc;
148 return -1;
149#endif
150}
151
152int send_bulk(int EndPt, void *pvBuf, size_t cbBuf)
153{
154 return dobulk(EndPt, pvBuf, cbBuf, "send_bulk");
155}
156
157int recv_bulk(int EndPt, void *pvBuf, size_t cbBuf)
158{
159 int cb = dobulk(EndPt | 0x80, pvBuf, cbBuf, "recv_bulk");
160 if (cb > 0)
161 printf("cb=%d\n", cb);
162 return cb;
163}
164
165int doctrl(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength,
166 void *pvBuf, const char *pszWho)
167{
168#if 0
169 struct usbdevfs_urb KUrb = {0};
170 KUrb.type = USBDEVFS_URB_TYPE_BULK;
171 KUrb.endpoint = EndPt;
172 KUrb.buffer = pvBuf;
173 KUrb.buffer_length = cbBuf;
174 KUrb.actual_length = 0; //cbBuf
175 KUrb.flags = 0; /* ISO_ASAP/SHORT_NOT_OK */
176 if (!doioctl(USBDEVFS_SUBMITURB, &KUrb, pszWho))
177 {
178 struct usbdevfs_urb *pKUrb = NULL;
179 if (!doioctl(USBDEVFS_REAPURB, &pKUrb, pszWho)
180 && pKUrb == &KUrb)
181 return KUrb.actual_length;
182 }
183 return -1;
184#else
185 struct usbdevfs_ctrltransfer CtrlMsg = {0};
186
187 CtrlMsg.bRequestType = bmRequestType;
188 CtrlMsg.bRequest = bRequest;
189 CtrlMsg.wValue = wValue;
190 CtrlMsg.wLength = wLength;
191 CtrlMsg.timeout = 1000;
192 CtrlMsg.data = pvBuf;
193
194 int rc = doioctl(USBDEVFS_CONTROL, &CtrlMsg, pszWho);
195 printf("rc=%d CtrlMsg.wLength=%d\n", rc, CtrlMsg.wLength);
196 if (rc >= 0)
197 return rc;
198 return -1;
199#endif
200}
201
202static int claim_if(int iIf)
203{
204 return doioctl(USBDEVFS_CLAIMINTERFACE, &iIf, "claim_if");
205}
206
207static int usb_set_connected(int ifnum, int conn)
208{
209 struct usbdevfs_ioctl io;
210 io.ifno = ifnum;
211 io.ioctl_code = (conn) ? USBDEVFS_CONNECT : USBDEVFS_DISCONNECT;
212 io.data = NULL;
213 return doioctl(USBDEVFS_IOCTL, &io, "set_connected");
214}
215
216static int set_config(int iCfg)
217{
218 return doioctl(USBDEVFS_SETCONFIGURATION, &iCfg, "set_config");
219}
220
221static int set_interface(int iIf, int iAlt)
222{
223 struct usbdevfs_setinterface SetIf = {0};
224 SetIf.interface = iIf;
225 SetIf.altsetting = iAlt;
226 return doioctl(USBDEVFS_SETINTERFACE, &SetIf, "set_interface");
227}
228
229/* can be exploited to check if there is an active config. */
230static int reset_ep(int EndPt)
231{
232 return doioctl(USBDEVFS_RESETEP, &EndPt, "reset_ep");
233}
234
235
236static void msd()
237{
238#if 1
239 unsigned InEndPt = 1;
240 unsigned OutEndPt = 1;
241#else
242 unsigned InEndPt = 1;
243 unsigned OutEndPt = 2;
244#endif
245 unsigned char abBuf[512];
246 int i;
247
248#if 0
249 /* Send an Get Max LUN request */
250 abBuf[0] = 0;
251 if (doctrl(VUSB_DIR_TO_HOST | VUSB_REQ_CLASS | VUSB_TO_INTERFACE,
252 0xfe /* max lun */, 0, 1, 1, abBuf, "get max lun") >= 0)
253 printf("max luns: %d\n", abBuf[0]);
254#endif
255
256 for (i = 0; i < 3; i++)
257 {
258 printf("i=%d\n", i);
259
260 /* Send an INQUIRY command to ep 2 */
261 memset(abBuf, 0, sizeof(abBuf));
262 memcpy(abBuf, "USBC", 4);
263 *(uint32_t *)(&abBuf[4]) = 0x12330984 ;
264 //abBuf[8] = 0x08;
265 abBuf[8] = 0x24;
266 abBuf[0xc] = 0x80;
267 abBuf[0xe] = 0x06; /* cmd length */
268 abBuf[0x0f] = 0x12; /* cmd - INQUIRY */
269 abBuf[0x13] = 0x24;
270
271 hex(abBuf, 31, "intquery req");
272 if (send_bulk(OutEndPt, abBuf, 31) < 0)
273 return;
274 //usleep(15000);
275
276 /* read result */
277 memset(abBuf, 0, sizeof(abBuf));
278 //printf("recv..\n");
279 int cb = recv_bulk(InEndPt, abBuf, 36);
280 hex(abBuf, cb, "inquiry result");
281
282 /* sense? */
283 memset(abBuf, 0, sizeof(abBuf));
284 cb = recv_bulk(InEndPt, abBuf, 36);
285 hex(abBuf, cb, "inquiry sense?");
286 usleep(150000);
287 }
288}
289
290int reset(void)
291{
292 int i = 0;
293 printf("resetting...\n");
294 return doioctl(USBDEVFS_RESET, &i, "reset");
295}
296
297int main(int argc, char **argv)
298{
299 g_fd = open(argv[1], O_RDWR);
300 if (g_fd < 0)
301 return bitch("open");
302
303 reset();
304
305 usb_set_connected(0, 1);
306 claim_if(0);
307
308// set_config(1); - the culprit!
309 set_interface(0, 0);
310
311 msd();
312 return 0;
313}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette