VirtualBox

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

Last change on this file since 94264 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • 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 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * USB device proxy - the VRDP backend, calls the RemoteUSBBackend methods.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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 RT_NOREF(fResetOnLinux);
89 LogFlow(("usbProxyVrdpReset: pProxyDev = %p\n", pProxyDev));
90
91 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
92
93 int rc = pDevVrdp->pCallback->pfnReset (pDevVrdp->pDevice);
94
95 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
96 {
97 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
98 pProxyDev->fDetached = true;
99 }
100
101 pProxyDev->iActiveCfg = -1;
102 pProxyDev->cIgnoreSetConfigs = 2;
103
104 return rc;
105}
106
107static DECLCALLBACK(int) usbProxyVrdpSetConfig(PUSBPROXYDEV pProxyDev, int cfg)
108{
109 LogFlow(("usbProxyVrdpSetConfig: pProxyDev=%s cfg=%#x\n", pProxyDev->pUsbIns->pszName, cfg));
110
111 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
112
113 int rc = pDevVrdp->pCallback->pfnSetConfig (pDevVrdp->pDevice, (uint8_t)cfg);
114
115 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
116 {
117 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
118 pProxyDev->fDetached = true;
119 }
120
121 return rc;
122}
123
124static DECLCALLBACK(int) usbProxyVrdpClaimInterface(PUSBPROXYDEV pProxyDev, int ifnum)
125{
126 LogFlow(("usbProxyVrdpClaimInterface: pProxyDev=%s ifnum=%#x\n", pProxyDev->pUsbIns->pszName, ifnum));
127
128 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
129
130 int rc = pDevVrdp->pCallback->pfnClaimInterface (pDevVrdp->pDevice, (uint8_t)ifnum);
131
132 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
133 {
134 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
135 pProxyDev->fDetached = true;
136 }
137
138 return rc;
139}
140
141static DECLCALLBACK(int) usbProxyVrdpReleaseInterface(PUSBPROXYDEV pProxyDev, int ifnum)
142{
143 LogFlow(("usbProxyVrdpReleaseInterface: pProxyDev=%s ifnum=%#x\n", pProxyDev->pUsbIns->pszName, ifnum));
144
145 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
146
147 int rc = pDevVrdp->pCallback->pfnReleaseInterface (pDevVrdp->pDevice, (uint8_t)ifnum);
148
149 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
150 {
151 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
152 pProxyDev->fDetached = true;
153 }
154
155 return rc;
156}
157
158static DECLCALLBACK(int) usbProxyVrdpSetInterface(PUSBPROXYDEV pProxyDev, int ifnum, int setting)
159{
160 LogFlow(("usbProxyVrdpSetInterface: pProxyDev=%p ifnum=%#x setting=%#x\n", pProxyDev, ifnum, setting));
161
162 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
163
164 int rc = pDevVrdp->pCallback->pfnInterfaceSetting (pDevVrdp->pDevice, (uint8_t)ifnum, (uint8_t)setting);
165
166 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
167 {
168 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
169 pProxyDev->fDetached = true;
170 }
171
172 return rc;
173}
174
175static DECLCALLBACK(int) usbProxyVrdpClearHaltedEp(PUSBPROXYDEV pProxyDev, unsigned int ep)
176{
177 LogFlow(("usbProxyVrdpClearHaltedEp: pProxyDev=%s ep=%u\n", pProxyDev->pUsbIns->pszName, ep));
178
179 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
180
181 int rc = pDevVrdp->pCallback->pfnClearHaltedEP (pDevVrdp->pDevice, (uint8_t)ep);
182
183 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
184 {
185 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
186 pProxyDev->fDetached = true;
187 }
188
189 return rc;
190}
191
192static DECLCALLBACK(int) usbProxyVrdpUrbQueue(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
193{
194 LogFlow(("usbProxyVrdpUrbQueue: pUrb=%p\n", pUrb));
195
196 /** @todo implement isochronous transfers for USB over VRDP. */
197 if (pUrb->enmType == VUSBXFERTYPE_ISOC)
198 {
199 Log(("usbproxy: isochronous transfers aren't implemented yet.\n"));
200 return VERR_NOT_IMPLEMENTED;
201 }
202
203 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
204 int rc = pDevVrdp->pCallback->pfnQueueURB (pDevVrdp->pDevice, pUrb->enmType, pUrb->EndPt, pUrb->enmDir, pUrb->cbData,
205 pUrb->abData, pUrb, (PREMOTEUSBQURB *)&pUrb->Dev.pvPrivate);
206
207 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
208 {
209 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
210 pProxyDev->fDetached = true;
211 }
212
213 return rc;
214}
215
216static DECLCALLBACK(PVUSBURB) usbProxyVrdpUrbReap(PUSBPROXYDEV pProxyDev, RTMSINTERVAL cMillies)
217{
218 LogFlow(("usbProxyVrdpUrbReap: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
219
220 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
221
222 PVUSBURB pUrb = NULL;
223 uint32_t cbData = 0;
224 uint32_t u32Err = VUSBSTATUS_OK;
225
226 int rc = pDevVrdp->pCallback->pfnReapURB (pDevVrdp->pDevice, cMillies, (void **)&pUrb, &cbData, &u32Err);
227
228 LogFlow(("usbProxyVrdpUrbReap: rc = %Rrc, pUrb = %p\n", rc, pUrb));
229
230 if (RT_SUCCESS(rc) && pUrb)
231 {
232 pUrb->enmStatus = (VUSBSTATUS)u32Err;
233 pUrb->cbData = cbData;
234 pUrb->Dev.pvPrivate = NULL;
235 }
236
237 if (rc == VERR_VUSB_DEVICE_NOT_ATTACHED)
238 {
239 Log(("usb-vrdp: remote device %p unplugged!!\n", pDevVrdp->pDevice));
240 pProxyDev->fDetached = true;
241 }
242
243 return pUrb;
244}
245
246static DECLCALLBACK(int) usbProxyVrdpUrbCancel(PUSBPROXYDEV pProxyDev, PVUSBURB pUrb)
247{
248 LogFlow(("usbProxyVrdpUrbCancel: pUrb=%p\n", pUrb));
249
250 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
251 pDevVrdp->pCallback->pfnCancelURB (pDevVrdp->pDevice, (PREMOTEUSBQURB)pUrb->Dev.pvPrivate);
252 return VINF_SUCCESS; /** @todo Enhance remote interface to pass a status code. */
253}
254
255static DECLCALLBACK(int) usbProxyVrdpWakeup(PUSBPROXYDEV pProxyDev)
256{
257 LogFlow(("usbProxyVrdpWakeup: pProxyDev=%s\n", pProxyDev->pUsbIns->pszName));
258
259 PUSBPROXYDEVVRDP pDevVrdp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVVRDP);
260 return pDevVrdp->pCallback->pfnWakeup (pDevVrdp->pDevice);
261}
262
263/**
264 * The VRDP USB Proxy Backend operations.
265 */
266extern const USBPROXYBACK g_USBProxyDeviceVRDP =
267{
268 /* pszName */
269 "vrdp",
270 /* cbBackend */
271 sizeof(USBPROXYDEVVRDP),
272 usbProxyVrdpOpen,
273 NULL,
274 usbProxyVrdpClose,
275 usbProxyVrdpReset,
276 usbProxyVrdpSetConfig,
277 usbProxyVrdpClaimInterface,
278 usbProxyVrdpReleaseInterface,
279 usbProxyVrdpSetInterface,
280 usbProxyVrdpClearHaltedEp,
281 usbProxyVrdpUrbQueue,
282 usbProxyVrdpUrbCancel,
283 usbProxyVrdpUrbReap,
284 usbProxyVrdpWakeup,
285 0
286};
287
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