VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/VUSBSnifferUsbMon.cpp@ 60066

Last change on this file since 60066 was 59700, checked in by vboxsync, 9 years ago

VUSB: Some structural cleanup (#2 Remove the HCI specific bits from the VUSBURB structure and let each controller manage it by itself just telling the root hub how much space it needs for each URB)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.8 KB
Line 
1/* $Id: VUSBSnifferUsbMon.cpp 59700 2016-02-16 12:18:30Z vboxsync $ */
2/** @file
3 * Virtual USB Sniffer facility - Linux usbmon ASCII format.
4 */
5
6/*
7 * Copyright (C) 2016 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DRV_VUSB
23#include <VBox/log.h>
24#include <iprt/mem.h>
25#include <iprt/buildconfig.h>
26#include <iprt/string.h>
27#include <iprt/system.h>
28#include <iprt/time.h>
29
30#include "VUSBSnifferInternal.h"
31
32
33/*********************************************************************************************************************************
34* Defined Constants And Macros *
35*********************************************************************************************************************************/
36
37/*********************************************************************************************************************************
38* Structures and Typedefs *
39*********************************************************************************************************************************/
40
41/**
42 * The internal VUSB sniffer state.
43 */
44typedef struct VUSBSNIFFERFMTINT
45{
46 /** Stream handle. */
47 PVUSBSNIFFERSTRM pStrm;
48} VUSBSNIFFERFMTINT;
49
50
51/*********************************************************************************************************************************
52* Static Variables *
53*********************************************************************************************************************************/
54
55/**
56 * Supported file extensions.
57 */
58static const char *s_apszFileExts[] =
59{
60 "mon",
61 "usbmon",
62 NULL
63};
64
65
66/*********************************************************************************************************************************
67* Internal Functions *
68*********************************************************************************************************************************/
69
70
71/** @copydoc VUSBSNIFFERFMT::pfnInit */
72static DECLCALLBACK(int) vusbSnifferFmtUsbMonInit(PVUSBSNIFFERFMTINT pThis, PVUSBSNIFFERSTRM pStrm)
73{
74 pThis->pStrm = pStrm;
75 return VINF_SUCCESS;
76}
77
78
79/** @copydoc VUSBSNIFFERFMT::pfnDestroy */
80static DECLCALLBACK(void) vusbSnifferFmtUsbMonDestroy(PVUSBSNIFFERFMTINT pThis)
81{
82
83}
84
85
86/** @copydoc VUSBSNIFFERFMT::pfnRecordEvent */
87static DECLCALLBACK(int) vusbSnifferFmtUsbMonRecordEvent(PVUSBSNIFFERFMTINT pThis, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
88{
89 char aszLineBuf[512];
90 char chEvtType = 'X';
91 char chDir = 'X';
92 char chEptType = 'X';
93
94 switch (enmEvent)
95 {
96 case VUSBSNIFFEREVENT_SUBMIT:
97 chEvtType = 'S';
98 break;
99 case VUSBSNIFFEREVENT_COMPLETE:
100 chEvtType = 'C';
101 break;
102 case VUSBSNIFFEREVENT_ERROR_SUBMIT:
103 case VUSBSNIFFEREVENT_ERROR_COMPLETE:
104 chEvtType = 'E';
105 break;
106 default:
107 AssertMsgFailed(("Invalid event type %d\n", enmEvent));
108 }
109
110 switch (pUrb->enmType)
111 {
112 case VUSBXFERTYPE_ISOC:
113 chEptType = 'Z';
114 break;
115 case VUSBXFERTYPE_BULK:
116 chEptType = 'B';
117 break;
118 case VUSBXFERTYPE_INTR:
119 chEptType = 'I';
120 break;
121 case VUSBXFERTYPE_CTRL:
122 case VUSBXFERTYPE_MSG:
123 chEptType = 'C';
124 break;
125 default:
126 AssertMsgFailed(("invalid transfer type %d\n", pUrb->enmType));
127 }
128
129 if (pUrb->enmDir == VUSBDIRECTION_IN)
130 chDir = 'i';
131 else if (pUrb->enmDir == VUSBDIRECTION_OUT)
132 chDir = 'o';
133 else if (pUrb->enmDir == VUSBDIRECTION_SETUP)
134 chDir = 'o';
135
136 RT_ZERO(aszLineBuf);
137
138 /* Assemble the static part. */
139 size_t cch = RTStrPrintf(&aszLineBuf[0], sizeof(aszLineBuf), "%p %llu %c %c%c:%u:%u:%u ",
140 pUrb, RTTimeNanoTS() / RT_NS_1US, chEvtType, chEptType, chDir,
141 0, pUrb->DstAddress, pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0x00));
142 int rc = pThis->pStrm->pfnWrite(pThis->pStrm, &aszLineBuf[0], cch);
143 if (RT_SUCCESS(rc))
144 {
145 /* Log the setup packet for control requests, the status otherwise. */
146 if ( (pUrb->enmType == VUSBXFERTYPE_CTRL || pUrb->enmType == VUSBXFERTYPE_MSG)
147 && enmEvent == VUSBSNIFFEREVENT_SUBMIT)
148 {
149 PVUSBSETUP pSetup = (PVUSBSETUP)pUrb->abData;
150
151 cch = RTStrPrintf(&aszLineBuf[0], sizeof(aszLineBuf), "s %02x %02x %04x %04x %04x ",
152 pSetup->bmRequestType, pSetup->bRequest, pSetup->wValue,
153 pSetup->wIndex, pSetup->wLength);
154 rc = pThis->pStrm->pfnWrite(pThis->pStrm, &aszLineBuf[0], cch);
155 }
156 else
157 {
158 bool fLogAdditionalStatus = pUrb->enmType == VUSBXFERTYPE_ISOC
159 || pUrb->enmType == VUSBXFERTYPE_INTR;
160
161 cch = RTStrPrintf(&aszLineBuf[0], sizeof(aszLineBuf), "%d%s", pUrb->enmStatus,
162 fLogAdditionalStatus ? "" : " ");
163
164 /* There are additional fields to log for isochronous and interrupt URBs. */
165 if (pUrb->enmType == VUSBXFERTYPE_ISOC)
166 {
167 if (enmEvent == VUSBSNIFFEREVENT_COMPLETE)
168 {
169 uint32_t u32ErrorCount = 0;
170
171 for (unsigned i = 0; i < pUrb->cIsocPkts; i++)
172 if ( pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_OK
173 && pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_NOT_ACCESSED)
174 u32ErrorCount++;
175
176 cch += RTStrPrintf(&aszLineBuf[cch], sizeof(aszLineBuf) - cch, ":%u:%u:%u ",
177 1 /* Interval */, 0 /* Frame number */, u32ErrorCount);
178 }
179 else
180 cch += RTStrPrintf(&aszLineBuf[cch], sizeof(aszLineBuf) - cch, ":%u:%u ",
181 1 /* Interval */, 0 /* Frame number */);
182 }
183 else if (pUrb->enmType == VUSBXFERTYPE_INTR)
184 cch += RTStrPrintf(&aszLineBuf[cch], sizeof(aszLineBuf) - cch, ":%u ",
185 1 /* Interval */);
186
187 rc = pThis->pStrm->pfnWrite(pThis->pStrm, &aszLineBuf[0], cch);
188 }
189
190 /* Log the packet descriptors for isochronous URBs. */
191 if ( RT_SUCCESS(rc)
192 && pUrb->enmType == VUSBXFERTYPE_ISOC)
193 {
194 cch = RTStrPrintf(&aszLineBuf[0], sizeof(aszLineBuf), "%u ", pUrb->cIsocPkts);
195 rc = pThis->pStrm->pfnWrite(pThis->pStrm, &aszLineBuf[0], cch);
196 for (unsigned i = 0; i < pUrb->cIsocPkts && RT_SUCCESS(rc); i++)
197 {
198 cch = RTStrPrintf(&aszLineBuf[0], sizeof(aszLineBuf), "%d:%u:%u ",
199 pUrb->aIsocPkts[i].enmStatus, pUrb->aIsocPkts[i].off,
200 pUrb->aIsocPkts[i].cb);
201 rc = pThis->pStrm->pfnWrite(pThis->pStrm, &aszLineBuf[0], cch);
202 }
203 }
204
205 if (RT_SUCCESS(rc))
206 {
207 /* Print data length */
208 cch = RTStrPrintf(&aszLineBuf[0], sizeof(aszLineBuf), "%d n\n", pUrb->cbData);
209 rc = pThis->pStrm->pfnWrite(pThis->pStrm, &aszLineBuf[0], cch);
210 }
211
212 /** @todo: Dump the data */
213 }
214
215 return rc;
216}
217
218/**
219 * VUSB sniffer format writer.
220 */
221const VUSBSNIFFERFMT g_VUsbSnifferFmtUsbMon =
222{
223 /** szName */
224 "USBMON",
225 /** pszDesc */
226 "UsbMon format writer compatible with vusb-analyzer: http://vusb-analyzer.sourceforge.net",
227 /** papszFileExts */
228 &s_apszFileExts[0],
229 /** cbFmt */
230 sizeof(VUSBSNIFFERFMTINT),
231 /** pfnInit */
232 vusbSnifferFmtUsbMonInit,
233 /** pfnDestroy */
234 vusbSnifferFmtUsbMonDestroy,
235 /** pfnRecordEvent */
236 vusbSnifferFmtUsbMonRecordEvent
237};
238
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