VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/testcase/tstPalmOne.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: 9.8 KB
Line 
1/* $Id: tstPalmOne.c 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * USB PalmOne testcase
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// set_config(1); - the culprit
249 set_interface(0, 0);
250
251#if 0
252 /* Send an Get Max LUN request */
253 abBuf[0] = 0;
254 if (doctrl(VUSB_DIR_TO_HOST | VUSB_REQ_CLASS | VUSB_TO_INTERFACE,
255 0xfe /* max lun */, 0, 1, 1, abBuf, "get max lun") >= 0)
256 printf("max luns: %d\n", abBuf[0]);
257#endif
258
259 for (i = 0; i < 3; i++)
260 {
261 printf("i=%d\n", i);
262
263 /* Send an INQUIRY command to ep 2 */
264 memset(abBuf, 0, sizeof(abBuf));
265 memcpy(abBuf, "USBC", 4);
266 *(uint32_t *)(&abBuf[4]) = 0x12330984 ;
267 //abBuf[8] = 0x08;
268 abBuf[8] = 0x24;
269 abBuf[0xc] = 0x80;
270 abBuf[0xe] = 0x06; /* cmd length */
271 abBuf[0x0f] = 0x12; /* cmd - INQUIRY */
272 abBuf[0x13] = 0x24;
273
274 hex(abBuf, 31, "intquery req");
275 if (send_bulk(OutEndPt, abBuf, 31) < 0)
276 return;
277 //usleep(15000);
278
279 /* read result */
280 memset(abBuf, 0, sizeof(abBuf));
281 //printf("recv..\n");
282 int cb = recv_bulk(InEndPt, abBuf, 36);
283 hex(abBuf, cb, "inquiry result");
284
285 /* sense? */
286 memset(abBuf, 0, sizeof(abBuf));
287 cb = recv_bulk(InEndPt, abBuf, 36);
288 hex(abBuf, cb, "inquiry sense?");
289 usleep(150000);
290 }
291}
292
293void palm(void)
294{
295// set_config(1); //skip this
296// reset_ep(6);
297
298 /* This seems to be some kind of 'identify device' request. */
299 uint8_t abVendor[0x14] = {0};
300 int cb = doctrl(VUSB_DIR_TO_HOST | VUSB_REQ_VENDOR | VUSB_TO_ENDPOINT,
301 0x04, 0, 0, 0x14, abVendor, "vendor req");
302 hex(abVendor, cb, "palm vendor req");
303
304 /* read from ep 6. */
305 uint8_t abBuf[512];
306 memset(abBuf, 0, sizeof(abBuf));
307 cb = recv_bulk(6, abBuf, 6);
308 hex(abBuf, cb, "bulk 1");
309
310 /* read from ep 6. */
311 memset(abBuf, 0, sizeof(abBuf));
312 cb = recv_bulk(6, abBuf, 22);
313 hex(abBuf, cb, "bulk 2");
314
315#if 0
316 /* write to ep 6 */
317 memset(abBuf, 0, sizeof(abBuf));
318 abBuf[0] = 1;
319 abBuf[1] = 2;
320 abBuf[5] = 0x32;
321 if (send_bulk(7, abBuf, 6) < 0)
322 return;
323
324 memset(abBuf, 0, sizeof(abBuf));
325 abBuf[0] = 0x12;
326 abBuf[1] = 1;
327 if (send_bulk(7, abBuf, 8) < 0)
328 return;
329
330 memset(abBuf, 0, sizeof(abBuf));
331 abBuf[1] = 0x20;
332 abBuf[6] = 0x24;
333 if (send_bulk(7, abBuf, 6) < 0)
334 return;
335
336 memset(abBuf, 0, sizeof(abBuf));
337 abBuf[0] = 0xff;
338 abBuf[1] = 0xff;
339 abBuf[2] = 0xff;
340 abBuf[3] = 0xff;
341 abBuf[4] = 0x3c;
342 abBuf[6] = 0x3c;
343 abBuf[0x0f] = 1;
344 abBuf[0x11] = 0x10;
345 abBuf[0x15] = 0x10;
346 abBuf[0x18] = 0x3c;
347 abBuf[0x1a] = 0x3c;
348 if (send_bulk(7, abBuf, 0x24) < 0)
349 return;
350
351 /* read from ep 6 */
352 memset(abBuf, 0, sizeof(abBuf));
353 cb = recv_bulk(6, abBuf, 64);
354 hex(abBuf, cb, "bulk 3");
355
356 /* read from ep 6. */
357 memset(abBuf, 0, sizeof(abBuf));
358 cb = recv_bulk(6, abBuf, 50);
359 hex(abBuf, cb, "bulk 4");
360#endif
361}
362
363int reset(void)
364{
365 int i = 0;
366 printf("resetting...\n");
367 return doioctl(USBDEVFS_RESET, &i, "reset");
368}
369
370int main(int argc, char **argv)
371{
372 g_fd = open(argv[1], O_RDWR);
373 if (errno == ENOENT && g_fd < 0)
374 {
375 int i;
376 for (i = 0; i < 120; i++)
377 {
378 g_fd = open(argv[1], O_RDWR);
379 if (g_fd >= 0)
380 break;
381 printf("."); fflush(stdout);
382 usleep(500000);
383 }
384 printf("\n");
385 }
386 if (g_fd < 0)
387 return bitch("open");
388
389// reset();
390// set_config(0);
391// set_config(1);
392
393 usb_set_connected(0, 1);
394 claim_if(0);
395
396#if 0
397 msd();
398#else
399 palm();
400#endif
401 return 0;
402}
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