VirtualBox

source: vbox/trunk/src/VBox/Devices/USB/vrdp/USBProxyDevice-vrdp.cpp@ 54647

Last change on this file since 54647 was 50234, checked in by vboxsync, 11 years ago

USB/Proxy: More code cleanup and finish a few todos, also some new ones so it doesn't get boring

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: USBProxyDevice-vrdp.cpp 50234 2014-01-24 22:48:13Z vboxsync $ */
2/** @file
3 * USB device proxy - the VRDP backend, calls the RemoteUSBBackend methods.
4 */
5
6/*
7 * Copyright (C) 2006-2014 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#define LOG_GROUP LOG_GROUP_DRV_USBPROXY
19
20#include <VBox/log.h>
21#include <VBox/err.h>
22#include <VBox/vrdpusb.h>
23#include <VBox/vmm/pdm.h>
24
25#include <iprt/assert.h>
26#include <iprt/alloc.h>
27#include <iprt/string.h>
28
29#include "../USBProxyDevice.h"
30
31/**
32 * Backend data for the VRDP USB Proxy device backend.
33 */
34typedef struct USBPROXYDEVVRDP
35{
36 REMOTEUSBCALLBACK *pCallback;
37 PREMOTEUSBDEVICE pDevice;
38} USBPROXYDEVVRDP, *PUSBPROXYDEVVRDP;
39
40
41/*
42 * The USB proxy device functions.
43 */
44
45static DECLCALLBACK(int) usbProxyVrdpOpen(PUSBPROXYDEV pProxyDev, const char *pszAddress, void *pvBackend)
46{
47 LogFlow(("usbProxyVrdpOpen: pProxyDev=%p pszAddress=%s, pvBackend=%p\n", pProxyDev, pszAddress, pvBackend));
48
49 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
50 int rc = VINF_SUCCESS;
51
52 if (strncmp (pszAddress, REMOTE_USB_BACKEND_PREFIX_S, REMOTE_USB_BACKEND_PREFIX_LEN) == 0)
53 {
54 REMOTEUSBCALLBACK *pCallback = (REMOTEUSBCALLBACK *)pvBackend;
55 PREMOTEUSBDEVICE pDevice = NULL;
56
57 rc = pCallback->pfnOpen (pCallback->pInstance, pszAddress, strlen (pszAddress) + 1, &pDevice);
58
59 if (RT_SUCCESS (rc))
60 {
61 pDevVrdp->pCallback = pCallback;
62 pDevVrdp->pDevice = pDevice;
63 pProxyDev->iActiveCfg = 1; /** @todo that may not be always true. */
64 pProxyDev->cIgnoreSetConfigs = 1;
65 return VINF_SUCCESS;
66 }
67 }
68 else
69 {
70 AssertFailed();
71 rc = VERR_INVALID_PARAMETER;
72 }
73
74 return rc;
75}
76
77static DECLCALLBACK(void) usbProxyVrdpClose(PUSBPROXYDEV pProxyDev)
78{
79 LogFlow(("usbProxyVrdpClose: pProxyDev = %p\n", pProxyDev));
80
81 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
82
83 pDevVrdp->pCallback->pfnClose (pDevVrdp->pDevice);
84}
85
86static DECLCALLBACK(int) usbProxyVrdpReset(PUSBPROXYDEV pProxyDev, bool fResetOnLinux)
87{
88 LogFlow(("usbProxyVrdpReset: pProxyDev = %p\n", pProxyDev));
89
90 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
91
92 int rc = pDevVrdp->pCallback->pfnReset (pDevVrdp->pDevice);
93
94 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
95 {
96 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
97 pProxyDev->fDetached = true;
98 }
99
100 pProxyDev->iActiveCfg = -1;
101 pProxyDev->cIgnoreSetConfigs = 2;
102
103 return rc;
104}
105
106static DECLCALLBACK(int) usbProxyVrdpSetConfig(PUSBPROXYDEV pProxyDev, int cfg)
107{
108 LogFlow(("usbProxyVrdpSetConfig: pProxyDev=%s cfg=%#x\n", pProxyDev->pUsbIns->pszName, cfg));
109
110 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
111
112 int rc = pDevVrdp->pCallback->pfnSetConfig (pDevVrdp->pDevice, (uint8_t)cfg);
113
114 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
115 {
116 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
117 pProxyDev->fDetached = true;
118 }
119
120 return rc;
121}
122
123static DECLCALLBACK(int) usbProxyVrdpClaimInterface(PUSBPROXYDEV pProxyDev, int ifnum)
124{
125 LogFlow(("usbProxyVrdpClaimInterface: pProxyDev=%s ifnum=%#x\n", pProxyDev->pUsbIns->pszName, ifnum));
126
127 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
128
129 int rc = pDevVrdp->pCallback->pfnClaimInterface (pDevVrdp->pDevice, (uint8_t)ifnum);
130
131 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
132 {
133 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
134 pProxyDev->fDetached = true;
135 }
136
137 return rc;
138}
139
140static DECLCALLBACK(int) usbProxyVrdpReleaseInterface(PUSBPROXYDEV pProxyDev, int ifnum)
141{
142 LogFlow(("usbProxyVrdpReleaseInterface: pProxyDev=%s ifnum=%#x\n", pProxyDev->pUsbIns->pszName, ifnum));
143
144 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
145
146 int rc = pDevVrdp->pCallback->pfnReleaseInterface (pDevVrdp->pDevice, (uint8_t)ifnum);
147
148 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
149 {
150 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
151 pProxyDev->fDetached = true;
152 }
153
154 return rc;
155}
156
157static DECLCALLBACK(int) usbProxyVrdpSetInterface(PUSBPROXYDEV pProxyDev, int ifnum, int setting)
158{
159 LogFlow(("usbProxyVrdpSetInterface: pProxyDev=%p ifnum=%#x setting=%#x\n", pProxyDev, ifnum, setting));
160
161 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
162
163 int rc = pDevVrdp->pCallback->pfnInterfaceSetting (pDevVrdp->pDevice, (uint8_t)ifnum, (uint8_t)setting);
164
165 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
166 {
167 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
168 pProxyDev->fDetached = true;
169 }
170
171 return rc;
172}
173
174static DECLCALLBACK(int) usbProxyVrdpClearHaltedEp(PUSBPROXYDEV pProxyDev, unsigned int ep)
175{
176 LogFlow(("usbProxyVrdpClearHaltedEp: pProxyDev=%s ep=%u\n", pProxyDev->pUsbIns->pszName, ep));
177
178 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
179
180 int rc = pDevVrdp->pCallback->pfnClearHaltedEP (pDevVrdp->pDevice, (uint8_t)ep);
181
182 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
183 {
184 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
185 pProxyDev->fDetached = true;
186 }
187
188 return rc;
189}
190
191static DECLCALLBACK(int) usbProxyVrdpUrbQueue(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
192{
193 LogFlow(("usbProxyVrdpUrbQueue: pUrb=%p\n", pUrb));
194
195 /** @todo implement isochronous transfers for USB over VRDP. */
196 if (pUrb->enmType == VUSBXFERTYPE_ISOC)
197 {
198 Log(("usbproxy: isochronous transfers aren't implemented yet.\n"));
199 return VERR_NOT_IMPLEMENTED;
200 }
201
202 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
203 int rc = pDevVrdp->pCallback->pfnQueueURB (pDevVrdp->pDevice, pUrb->enmType, pUrb->EndPt, pUrb->enmDir, pUrb->cbData,
204 pUrb->abData, pUrb, (PREMOTEUSBQURB *)&pUrb->Dev.pvPrivate);
205
206 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
207 {
208 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
209 pProxyDev->fDetached = true;
210 }
211
212 return rc;
213}
214
215static DECLCALLBACK(PVUSBURB) usbProxyVrdpUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
216{
217 LogFlow(("usbProxyVrdpUrbReap: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
218
219 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
220
221 PVUSBURB pUrb = NULL;
222 uint32_t cbData = 0;
223 uint32_t u32Err = VUSBSTATUS_OK;
224
225 int rc = pDevVrdp->pCallback->pfnReapURB (pDevVrdp->pDevice, cMillies, (void **)&pUrb, &cbData, &u32Err);
226
227 LogFlow(("usbProxyVrdpUrbReap: rc = %Rrc, pUrb = %p\n", rc, pUrb));
228
229 if (RT_SUCCESS(rc) && pUrb)
230 {
231 pUrb->enmStatus = (VUSBSTATUS)u32Err;
232 pUrb->cbData = cbData;
233 pUrb->Dev.pvPrivate = NULL;
234 }
235
236 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
237 {
238 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
239 pProxyDev->fDetached = true;
240 }
241
242 return pUrb;
243}
244
245static DECLCALLBACK(int) usbProxyVrdpUrbCancel(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
246{
247 LogFlow(("usbProxyVrdpUrbCancel: pUrb=%p\n", pUrb));
248
249 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
250 pDevVrdp->pCallback->pfnCancelURB (pDevVrdp->pDevice, (PREMOTEUSBQURB)pUrb->Dev.pvPrivate);
251 return VINF_SUCCESS; /** @todo: Enhance remote interface to pass a status code. */
252}
253
254static DECLCALLBACK(int) usbProxyVrdpWakeup(PUSBPROXYDEV pProxyDev)
255{
256 LogFlow(("usbProxyVrdpWakeup: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
257
258 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
259 return pDevVrdp->pCallback->pfnWakeup (pDevVrdp->pDevice);
260}
261
262/**
263 * The VRDP USB Proxy Backend operations.
264 */
265extern const USBPROXYBACK g_USBProxyDeviceVRDP =
266{
267 /* pszName */
268 "vrdp",
269 /* cbBackend */
270 sizeof(USBPROXYDEVVRDP),
271 usbProxyVrdpOpen,
272 NULL,
273 usbProxyVrdpClose,
274 usbProxyVrdpReset,
275 usbProxyVrdpSetConfig,
276 usbProxyVrdpClaimInterface,
277 usbProxyVrdpReleaseInterface,
278 usbProxyVrdpSetInterface,
279 usbProxyVrdpClearHaltedEp,
280 usbProxyVrdpUrbQueue,
281 usbProxyVrdpUrbCancel,
282 usbProxyVrdpUrbReap,
283 usbProxyVrdpWakeup,
284 0
285};
286
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