VirtualBox

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

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

USB/Proxy: Start a source code cleanup, remove unused struct members and make the generic proxy code do the backend specific memory allocation (fixes a small memory leak in the VRDP backend when closing a proxy device)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/* $Id: USBProxyDevice-vrdp.cpp 50228 2014-01-24 21:16:37Z 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.215389.xyz. 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 RT_SUCCESS(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 RT_SUCCESS(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 RT_SUCCESS(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 RT_SUCCESS(rc);
172}
173
174static DECLCALLBACK(bool) 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 RT_SUCCESS(rc);
189}
190
191static DECLCALLBACK(int) usbProxyVrdpUrbQueue(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 false;
200 }
201
202 PUSBPROXYDEV pProxyDev = PDMINS_2_DATA(pUrb->pUsbIns, PUSBPROXYDEV);
203 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
204
205 int rc = pDevVrdp->pCallback->pfnQueueURB (pDevVrdp->pDevice, pUrb->enmType, pUrb->EndPt, pUrb->enmDir, pUrb->cbData,
206 pUrb->abData, pUrb, (PREMOTEUSBQURB *)&pUrb->Dev.pvPrivate);
207
208 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
209 {
210 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
211 pProxyDev->fDetached = true;
212 }
213
214 return RT_SUCCESS(rc);
215}
216
217static DECLCALLBACK(PVUSBURB) usbProxyVrdpUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
218{
219 LogFlow(("usbProxyVrdpUrbReap: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
220
221 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
222
223 PVUSBURB pUrb = NULL;
224 uint32_t cbData = 0;
225 uint32_t u32Err = VUSBSTATUS_OK;
226
227 int rc = pDevVrdp->pCallback->pfnReapURB (pDevVrdp->pDevice, cMillies, (void **)&pUrb, &cbData, &u32Err);
228
229 LogFlow(("usbProxyVrdpUrbReap: rc = %Rrc, pUrb = %p\n", rc, pUrb));
230
231 if (RT_SUCCESS(rc) && pUrb)
232 {
233 pUrb->enmStatus = (VUSBSTATUS)u32Err;
234 pUrb->cbData = cbData;
235 pUrb->Dev.pvPrivate = NULL;
236 }
237
238 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
239 {
240 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
241 pProxyDev->fDetached = true;
242 }
243
244 return pUrb;
245}
246
247static DECLCALLBACK(void) usbProxyVrdpUrbCancel(PVUSBURB pUrb)
248{
249 LogFlow(("usbProxyVrdpUrbCancel: pUrb=%p\n", pUrb));
250
251 PUSBPROXYDEV pProxyDev = PDMINS_2_DATA(pUrb->pUsbIns, PUSBPROXYDEV);
252 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
253
254 pDevVrdp->pCallback->pfnCancelURB (pDevVrdp->pDevice, (PREMOTEUSBQURB)pUrb->Dev.pvPrivate);
255}
256
257static DECLCALLBACK(int) usbProxyVrdpWakeup(PUSBPROXYDEV pProxyDev)
258{
259 LogFlow(("usbProxyVrdpWakeup: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
260
261 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
262
263 return pDevVrdp->pCallback->pfnWakeup (pDevVrdp->pDevice);
264}
265
266/**
267 * The VRDP USB Proxy Backend operations.
268 */
269extern const USBPROXYBACK g_USBProxyDeviceVRDP =
270{
271 /* pszName */
272 "vrdp",
273 /* cbBackend */
274 sizeof(USBPROXYDEVVRDP),
275 usbProxyVrdpOpen,
276 NULL,
277 usbProxyVrdpClose,
278 usbProxyVrdpReset,
279 usbProxyVrdpSetConfig,
280 usbProxyVrdpClaimInterface,
281 usbProxyVrdpReleaseInterface,
282 usbProxyVrdpSetInterface,
283 usbProxyVrdpClearHaltedEp,
284 usbProxyVrdpUrbQueue,
285 usbProxyVrdpUrbCancel,
286 usbProxyVrdpUrbReap,
287 usbProxyVrdpWakeup,
288 0
289};
290
Note: See TracBrowser for help on using the repository browser.

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