VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/RemoteUSBBackend.cpp

Last change on this file was 100521, checked in by vboxsync, 10 months ago

Main: separate function for parsing the entries in remote USB device list. bugref:10478

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.7 KB
RevLine 
[55401]1/* $Id: RemoteUSBBackend.cpp 100521 2023-07-11 16:47:42Z vboxsync $ */
[31891]2/** @file
3 * VirtualBox Remote USB backend
4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[31891]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[31891]26 */
27
[50530]28#define LOG_GROUP LOG_GROUP_USB_REMOTE
[67914]29#include "LoggingNew.h"
30
[31891]31#include "ConsoleImpl.h"
32#include "ConsoleVRDPServer.h"
33#include "RemoteUSBBackend.h"
34#include "RemoteUSBDeviceImpl.h"
35
[33004]36#include <VBox/RemoteDesktop/VRDE.h>
[31891]37#include <VBox/vrdpusb.h>
38#include <VBox/err.h>
39#include <VBox/log.h>
40
41#include <VBox/vusb.h>
42
43#include <iprt/time.h>
44
45/** @page pg_vrdb_usb Async Remote USB
46 *
47 *
48 * USB backend functions are called in EMT so care must be taken to prevent
49 * delays in the functions execution.
50 *
51 * Among 11 backend functions 10 just return a success indicator.
52 *
53 * Such a function usually will check pending error code and if everything is ok,
54 * submit asynchronous RDP request and return success immediately.
55 *
56 * On actual completion of each request, the status will be saved as
57 * pending, so in case of an error all further functions will fail with
58 * device disconnected condition.
59 * @todo May be a device disconnect notification for console is required?
60 *
61 * The only remaining function that needs special processing is
62 * the reap_urb. It has a timeout parameter.
63 * Normally, the timeout is 0, as result of polling from VUSB frame timer.
64 * It is ok for async processing, the backend will periodically reap urbs from client.
65 * And already reaped URBs from client will be returned for the call.
66 * Exceptions:
67 * 1) during device initialization, when obtaining device descriptions
68 * the timeout is -1, and the request is expected to be processed synchronously.
69 * It looks like only 3 URBs with some information are retrieved that way.
70 * Probably, one can return this information in DEVICE_LIST together with the
71 * device description and when such request are submitted, just return
72 * the prefetched data.
73 * 2) during suspend timeout is non zero (10 or less milliseconds),
74 * and URB's are reaped for about 1 second. But here network delays
75 * will not affect the timeout, so it is ok.
76 *
77 *
[65125]78 * @section sub_vrdb_usb_dad Device attaching/detaching
[31891]79 *
80 * Devices are attached when client is connected or when a new device is connected to client.
81 * Devices are detached when client is disconnected (all devices) or a device is disconnected
82 * the client side.
83 *
84 * The backend polls the client for list of attached USB devices from RemoteUSBThread.
85 *
86 */
87
88/* Queued URB submitted to VRDP client. */
89typedef struct _REMOTEUSBQURB
90{
91 struct _REMOTEUSBQURB *next;
92 struct _REMOTEUSBQURB *prev;
93
94 PREMOTEUSBDEVICE pDevice; /* Device, the URB is queued for. */
95
96 uint32_t u32Handle; /* The handle of the URB. Generated by the Remote USB backend. */
97
98 void *pvData; /* Pointer to URB data allocated by VUSB. */
99 void *pvURB; /* Pointer to URB known to VUSB. */
100
101 uint32_t u32Len; /* Data length returned by the VRDP client. */
102 uint32_t u32Err; /* URB error code returned by the VRDP client. */
103
104 bool fCompleted; /* The URB has been returned back by VRDP client. */
105 bool fInput; /* This URB receives data from the client. */
106
[33004]107 uint32_t u32TransferredLen; /* For VRDE_USB_DIRECTION_OUT URBs = bytes written.
108 * For VRDE_USB_DIRECTION_IN URBs = bytes received.
[31891]109 */
110} REMOTEUSBQURB;
111
112/* Remote USB device instance data. */
113typedef struct _REMOTEUSBDEVICE
114{
115 struct _REMOTEUSBDEVICE *prev;
116 struct _REMOTEUSBDEVICE *next;
117
118 RemoteUSBBackend *pOwner;
119
[33004]120 VRDEUSBDEVID id; /* The remote identifier, assigned by client. */
[31891]121
122 uint32_t u32ClientId; /* The identifier of the remote client. */
123
124 REMOTEUSBQURB *pHeadQURBs; /* List of URBs queued for the device. */
125 REMOTEUSBQURB *pTailQURBs;
126
127 volatile uint32_t hURB; /* Source for URB's handles. */
128 bool fFailed; /* True if an operation has failed for the device. */
129 RTCRITSECT critsect; /* Protects the queued urb list. */
[49814]130 volatile bool fWokenUp; /* Flag whther the reaper was woken up. */
[31891]131} REMOTEUSBDEVICE;
132
133
134
135static void requestDevice(REMOTEUSBDEVICE *pDevice)
136{
[94965]137 int vrc = RTCritSectEnter(&pDevice->critsect);
138 AssertRC(vrc);
[31891]139}
140
141static void releaseDevice(REMOTEUSBDEVICE *pDevice)
142{
143 RTCritSectLeave(&pDevice->critsect);
144}
145
146static REMOTEUSBQURB *qurbAlloc(PREMOTEUSBDEVICE pDevice)
147{
[63563]148 /** @todo reuse URBs. */
[31891]149 REMOTEUSBQURB *pQURB = (REMOTEUSBQURB *)RTMemAllocZ (sizeof (REMOTEUSBQURB));
150
151 if (pQURB)
152 {
153 pQURB->pDevice = pDevice;
154 }
155
156 return pQURB;
157}
158
159static void qurbFree (REMOTEUSBQURB *pQURB)
160{
161 RTMemFree (pQURB);
162 return;
163}
164
165
166/* Called by VRDP server when the client responds to a request on USB channel. */
[51092]167DECLCALLBACK(int) USBClientResponseCallback(void *pv, uint32_t u32ClientId, uint8_t code, const void *pvRet, uint32_t cbRet)
[31891]168{
[63256]169 RT_NOREF(u32ClientId);
[94965]170 int vrc = VINF_SUCCESS;
[31891]171
172 LogFlow(("USBClientResponseCallback: id = %d, pv = %p, code = %d, pvRet = %p, cbRet = %d\n",
173 u32ClientId, pv, code, pvRet, cbRet));
174
175 RemoteUSBBackend *pThis = (RemoteUSBBackend *)pv;
176
177 switch (code)
178 {
[33004]179 case VRDE_USB_REQ_DEVICE_LIST:
[31891]180 {
[94965]181 vrc = pThis->saveDeviceList(pvRet, cbRet);
[31891]182 } break;
183
[33004]184 case VRDE_USB_REQ_NEGOTIATE:
[31891]185 {
[51092]186 if (pvRet && cbRet >= sizeof(VRDEUSBREQNEGOTIATERET))
[31891]187 {
[33004]188 VRDEUSBREQNEGOTIATERET *pret = (VRDEUSBREQNEGOTIATERET *)pvRet;
[31891]189
[94965]190 vrc = pThis->negotiateResponse(pret, cbRet);
[31891]191 }
192 else
193 {
194 Log(("USBClientResponseCallback: WARNING: not enough data in response: pv = %p, cb = %d, expected %d.\n",
[51092]195 pvRet, cbRet, sizeof(VRDEUSBREQNEGOTIATERET)));
[31891]196
[94965]197 vrc = VERR_INVALID_PARAMETER;
[31891]198 }
199 } break;
200
[33004]201 case VRDE_USB_REQ_REAP_URB:
[31891]202 {
[94965]203 vrc = pThis->reapURB(pvRet, cbRet);
[31891]204
[98278]205 LogFlow(("USBClientResponseCallback: reap URB, vrc = %Rrc.\n", vrc));
[31891]206 } break;
207
[33004]208 case VRDE_USB_REQ_QUEUE_URB:
209 case VRDE_USB_REQ_CLOSE:
210 case VRDE_USB_REQ_CANCEL_URB:
[31891]211 {
212 /* Do nothing, actually this should not happen. */
213 Log(("USBClientResponseCallback: WARNING: response to a request %d is not expected!!!\n", code));
214 } break;
215
[33004]216 case VRDE_USB_REQ_OPEN:
217 case VRDE_USB_REQ_RESET:
218 case VRDE_USB_REQ_SET_CONFIG:
219 case VRDE_USB_REQ_CLAIM_INTERFACE:
220 case VRDE_USB_REQ_RELEASE_INTERFACE:
221 case VRDE_USB_REQ_INTERFACE_SETTING:
222 case VRDE_USB_REQ_CLEAR_HALTED_EP:
[31891]223 {
224 /*
225 * Device specific responses with status codes.
226 */
[51092]227 if (pvRet && cbRet >= sizeof(VRDEUSBREQRETHDR))
[31891]228 {
[33004]229 VRDEUSBREQRETHDR *pret = (VRDEUSBREQRETHDR *)pvRet;
[31891]230
[33004]231 if (pret->status != VRDE_USB_STATUS_SUCCESS)
[31891]232 {
[51092]233 REMOTEUSBDEVICE *pDevice = pThis->deviceFromId(pret->id);
[31891]234
235 if (!pDevice)
236 {
237 Log(("USBClientResponseCallback: WARNING: invalid device id %08X.\n", pret->id));
[94965]238 vrc = VERR_INVALID_PARAMETER;
[31891]239 }
240 else
241 {
242 Log(("USBClientResponseCallback: WARNING: the operation failed, status %d\n", pret->status));
243 pDevice->fFailed = true;
244 }
245 }
246 }
247 else
248 {
249 Log(("USBClientResponseCallback: WARNING: not enough data in response: pv = %p, cb = %d, expected %d.\n",
[51092]250 pvRet, cbRet, sizeof(VRDEUSBREQRETHDR)));
[31891]251 }
252 } break;
253
254 default:
255 {
256 Log(("USBClientResponseCallback: WARNING: invalid code %d\n", code));
257 } break;
258 }
259
[94965]260 return vrc;
[31891]261}
262
263/*
264 * Backend entry points.
265 */
[51092]266static DECLCALLBACK(int) iface_Open(PREMOTEUSBBACKEND pInstance, const char *pszAddress,
267 size_t cbAddress, PREMOTEUSBDEVICE *ppDevice)
[31891]268{
[63256]269 RT_NOREF(cbAddress);
[94965]270 int vrc = VINF_SUCCESS;
[31891]271
272 RemoteUSBBackend *pThis = (RemoteUSBBackend *)pInstance;
273
[51092]274 REMOTEUSBDEVICE *pDevice = (REMOTEUSBDEVICE *)RTMemAllocZ(sizeof(REMOTEUSBDEVICE));
[31891]275
276 if (!pDevice)
277 {
[94965]278 vrc = VERR_NO_MEMORY;
[31891]279 }
280 else
281 {
282 /* Parse given address string to find the device identifier.
283 * The format is "REMOTEUSB0xAAAABBBB&0xCCCCDDDD", where AAAABBBB is hex device identifier
284 * and CCCCDDDD is hex client id.
285 */
[51092]286 if (strncmp(pszAddress, REMOTE_USB_BACKEND_PREFIX_S, REMOTE_USB_BACKEND_PREFIX_LEN) != 0)
[31891]287 {
288 AssertFailed();
[94965]289 vrc = VERR_INVALID_PARAMETER;
[31891]290 }
291 else
292 {
293 /* Initialize the device structure. */
294 pDevice->pOwner = pThis;
[49814]295 pDevice->fWokenUp = false;
[31891]296
[94965]297 vrc = RTCritSectInit(&pDevice->critsect);
298 AssertRC(vrc);
[31891]299
[94965]300 if (RT_SUCCESS(vrc))
[31891]301 {
[51092]302 pDevice->id = RTStrToUInt32(&pszAddress[REMOTE_USB_BACKEND_PREFIX_LEN]);
[31891]303
[51092]304 size_t l = strlen(pszAddress);
[31891]305
[51092]306 if (l >= REMOTE_USB_BACKEND_PREFIX_LEN + strlen("0x12345678&0x87654321"))
[31891]307 {
[51092]308 const char *p = &pszAddress[REMOTE_USB_BACKEND_PREFIX_LEN + strlen("0x12345678")];
[31891]309 if (*p == '&')
310 {
[51092]311 pDevice->u32ClientId = RTStrToUInt32(p + 1);
[31891]312 }
313 else
314 {
[51092]315 AssertFailed();
[94965]316 vrc = VERR_INVALID_PARAMETER;
[31891]317 }
318 }
319 else
320 {
[51092]321 AssertFailed();
[94965]322 vrc = VERR_INVALID_PARAMETER;
[31891]323 }
324
[94965]325 if (RT_SUCCESS(vrc))
[31891]326 {
[33004]327 VRDE_USB_REQ_OPEN_PARM parm;
[31891]328
[33004]329 parm.code = VRDE_USB_REQ_OPEN;
[31891]330 parm.id = pDevice->id;
331
[51092]332 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]333 }
334 }
335 }
336 }
337
[94965]338 if (RT_SUCCESS(vrc))
[31891]339 {
340 *ppDevice = pDevice;
341
[51092]342 pThis->addDevice(pDevice);
[31891]343 }
344 else
345 {
[51092]346 RTMemFree(pDevice);
[31891]347 }
348
[94965]349 return vrc;
[31891]350}
351
[51092]352static DECLCALLBACK(void) iface_Close(PREMOTEUSBDEVICE pDevice)
[31891]353{
354 RemoteUSBBackend *pThis = pDevice->pOwner;
355
[33004]356 VRDE_USB_REQ_CLOSE_PARM parm;
[31891]357
[33004]358 parm.code = VRDE_USB_REQ_CLOSE;
[31891]359 parm.id = pDevice->id;
360
[51092]361 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]362
[51092]363 pThis->removeDevice(pDevice);
[31891]364
[51092]365 if (RTCritSectIsInitialized(&pDevice->critsect))
[31891]366 {
[51092]367 RTCritSectDelete(&pDevice->critsect);
[31891]368 }
369
[51092]370 RTMemFree(pDevice);
[31891]371
372 return;
373}
374
[51092]375static DECLCALLBACK(int) iface_Reset(PREMOTEUSBDEVICE pDevice)
[31891]376{
377 RemoteUSBBackend *pThis = pDevice->pOwner;
378
379 if (pDevice->fFailed)
380 {
381 return VERR_VUSB_DEVICE_NOT_ATTACHED;
382 }
383
[33004]384 VRDE_USB_REQ_RESET_PARM parm;
[31891]385
[33004]386 parm.code = VRDE_USB_REQ_RESET;
[31891]387 parm.id = pDevice->id;
388
[51092]389 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]390
391 return VINF_SUCCESS;
392}
393
[51092]394static DECLCALLBACK(int) iface_SetConfig(PREMOTEUSBDEVICE pDevice, uint8_t u8Cfg)
[31891]395{
396 RemoteUSBBackend *pThis = pDevice->pOwner;
397
398 if (pDevice->fFailed)
399 {
400 return VERR_VUSB_DEVICE_NOT_ATTACHED;
401 }
402
[33004]403 VRDE_USB_REQ_SET_CONFIG_PARM parm;
[31891]404
[33004]405 parm.code = VRDE_USB_REQ_SET_CONFIG;
[31891]406 parm.id = pDevice->id;
407 parm.configuration = u8Cfg;
408
[51092]409 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]410
411 return VINF_SUCCESS;
412}
413
[51092]414static DECLCALLBACK(int) iface_ClaimInterface(PREMOTEUSBDEVICE pDevice, uint8_t u8Ifnum)
[31891]415{
416 RemoteUSBBackend *pThis = pDevice->pOwner;
417
418 if (pDevice->fFailed)
419 {
420 return VERR_VUSB_DEVICE_NOT_ATTACHED;
421 }
422
[33004]423 VRDE_USB_REQ_CLAIM_INTERFACE_PARM parm;
[31891]424
[33004]425 parm.code = VRDE_USB_REQ_CLAIM_INTERFACE;
[31891]426 parm.id = pDevice->id;
427 parm.iface = u8Ifnum;
428
[51092]429 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]430
431 return VINF_SUCCESS;
432}
433
[51092]434static DECLCALLBACK(int) iface_ReleaseInterface(PREMOTEUSBDEVICE pDevice, uint8_t u8Ifnum)
[31891]435{
436 RemoteUSBBackend *pThis = pDevice->pOwner;
437
438 if (pDevice->fFailed)
439 {
440 return VERR_VUSB_DEVICE_NOT_ATTACHED;
441 }
442
[33004]443 VRDE_USB_REQ_RELEASE_INTERFACE_PARM parm;
[31891]444
[33004]445 parm.code = VRDE_USB_REQ_RELEASE_INTERFACE;
[31891]446 parm.id = pDevice->id;
447 parm.iface = u8Ifnum;
448
[51092]449 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]450
451 return VINF_SUCCESS;
452}
453
[51092]454static DECLCALLBACK(int) iface_InterfaceSetting(PREMOTEUSBDEVICE pDevice, uint8_t u8Ifnum, uint8_t u8Setting)
[31891]455{
456 RemoteUSBBackend *pThis = pDevice->pOwner;
457
458 if (pDevice->fFailed)
459 {
460 return VERR_VUSB_DEVICE_NOT_ATTACHED;
461 }
462
[33004]463 VRDE_USB_REQ_INTERFACE_SETTING_PARM parm;
[31891]464
[33004]465 parm.code = VRDE_USB_REQ_INTERFACE_SETTING;
[31891]466 parm.id = pDevice->id;
467 parm.iface = u8Ifnum;
468 parm.setting = u8Setting;
469
[51092]470 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]471
472 return VINF_SUCCESS;
473}
474
[51092]475static DECLCALLBACK(int) iface_ClearHaltedEP(PREMOTEUSBDEVICE pDevice, uint8_t u8Ep)
[31891]476{
477 RemoteUSBBackend *pThis = pDevice->pOwner;
478
479 if (pDevice->fFailed)
480 {
481 return VERR_VUSB_DEVICE_NOT_ATTACHED;
482 }
483
[33004]484 VRDE_USB_REQ_CLEAR_HALTED_EP_PARM parm;
[31891]485
[33004]486 parm.code = VRDE_USB_REQ_CLEAR_HALTED_EP;
[31891]487 parm.id = pDevice->id;
488 parm.ep = u8Ep;
489
[51092]490 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]491
492 return VINF_SUCCESS;
493}
494
[51092]495static DECLCALLBACK(void) iface_CancelURB(PREMOTEUSBDEVICE pDevice, PREMOTEUSBQURB pRemoteURB)
[31891]496{
497 RemoteUSBBackend *pThis = pDevice->pOwner;
498
[33004]499 VRDE_USB_REQ_CANCEL_URB_PARM parm;
[31891]500
[33004]501 parm.code = VRDE_USB_REQ_CANCEL_URB;
[31891]502 parm.id = pDevice->id;
503 parm.handle = pRemoteURB->u32Handle;
504
[51092]505 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]506
[51092]507 requestDevice(pDevice);
[31891]508
509 /* Remove this urb from the queue. It is safe because if
510 * client will return the URB, it will be just ignored
511 * in reapURB.
512 */
513 if (pRemoteURB->prev)
514 {
515 pRemoteURB->prev->next = pRemoteURB->next;
516 }
517 else
518 {
519 pDevice->pHeadQURBs = pRemoteURB->next;
520 }
521
522 if (pRemoteURB->next)
523 {
524 pRemoteURB->next->prev = pRemoteURB->prev;
525 }
526 else
527 {
528 pDevice->pTailQURBs = pRemoteURB->prev;
529 }
530
[51092]531 qurbFree(pRemoteURB);
[31891]532
[51092]533 releaseDevice(pDevice);
[31891]534
535 return;
536}
537
[51092]538static DECLCALLBACK(int) iface_QueueURB(PREMOTEUSBDEVICE pDevice, uint8_t u8Type, uint8_t u8Ep, uint8_t u8Direction,
539 uint32_t u32Len, void *pvData, void *pvURB, PREMOTEUSBQURB *ppRemoteURB)
[31891]540{
[94965]541 int vrc = VINF_SUCCESS;
[31891]542
543#ifdef DEBUG_sunlover
[51092]544 LogFlow(("RemoteUSBBackend::iface_QueueURB: u8Type = %d, u8Ep = %d, u8Direction = %d, data\n%.*Rhxd\n",
545 u8Type, u8Ep, u8Direction, u32Len, pvData));
[31891]546#endif /* DEBUG_sunlover */
547
548 if (pDevice->fFailed)
549 {
550 return VERR_VUSB_DEVICE_NOT_ATTACHED;
551 }
552
553 RemoteUSBBackend *pThis = pDevice->pOwner;
554
[33004]555 VRDE_USB_REQ_QUEUE_URB_PARM parm;
[31891]556 uint32_t u32Handle = 0;
557 uint32_t u32DataLen = 0;
558
[51092]559 REMOTEUSBQURB *qurb = qurbAlloc(pDevice);
[31891]560
561 if (qurb == NULL)
562 {
[94965]563 vrc = VERR_NO_MEMORY;
[31891]564 goto l_leave;
565 }
566
567 /*
568 * Compute length of data which need to be transferred to the client.
569 */
570 switch(u8Direction)
571 {
572 case VUSB_DIRECTION_IN:
573 {
574 if (u8Type == VUSBXFERTYPE_MSG)
575 {
576 u32DataLen = 8; /* 8 byte header. */
[63563]577 // u32DataLen = u32Len; /// @todo do messages need all information?
[31891]578 }
579 } break;
580
581 case VUSB_DIRECTION_OUT:
582 {
583 u32DataLen = u32Len;
584 } break;
585
586 default:
587 {
588 AssertFailed();
[94965]589 vrc = VERR_INVALID_PARAMETER;
[31891]590 goto l_leave;
591 }
592 }
593
[33004]594 parm.code = VRDE_USB_REQ_QUEUE_URB;
[31891]595 parm.id = pDevice->id;
596
597 u32Handle = pDevice->hURB++;
598 if (u32Handle == 0)
599 {
600 u32Handle = pDevice->hURB++;
601 }
602
603 LogFlow(("RemoteUSBBackend::iface_QueueURB: handle = %d\n", u32Handle));
604
605 parm.handle = u32Handle;
606
607 switch(u8Type)
608 {
[33004]609 case VUSBXFERTYPE_CTRL: parm.type = VRDE_USB_TRANSFER_TYPE_CTRL; break;
610 case VUSBXFERTYPE_ISOC: parm.type = VRDE_USB_TRANSFER_TYPE_ISOC; break;
611 case VUSBXFERTYPE_BULK: parm.type = VRDE_USB_TRANSFER_TYPE_BULK; break;
612 case VUSBXFERTYPE_INTR: parm.type = VRDE_USB_TRANSFER_TYPE_INTR; break;
613 case VUSBXFERTYPE_MSG: parm.type = VRDE_USB_TRANSFER_TYPE_MSG; break;
[94965]614 default: AssertFailed(); vrc = VERR_INVALID_PARAMETER; goto l_leave;
[31891]615 }
616
617 parm.ep = u8Ep;
618
619 switch(u8Direction)
620 {
[33004]621 case VUSB_DIRECTION_SETUP: AssertFailed(); parm.direction = VRDE_USB_DIRECTION_SETUP; break;
622 case VUSB_DIRECTION_IN: parm.direction = VRDE_USB_DIRECTION_IN; break;
623 case VUSB_DIRECTION_OUT: parm.direction = VRDE_USB_DIRECTION_OUT; break;
[94965]624 default: AssertFailed(); vrc = VERR_INVALID_PARAMETER; goto l_leave;
[31891]625 }
626
627 parm.urblen = u32Len;
628 parm.datalen = u32DataLen;
629
630 if (u32DataLen)
631 {
632 parm.data = pvData;
633 }
634
635 requestDevice (pDevice);
636
637 /* Add at tail of queued urb list. */
638 qurb->next = NULL;
639 qurb->prev = pDevice->pTailQURBs;
[33004]640 qurb->u32Err = VRDE_USB_XFER_OK;
[31891]641 qurb->u32Len = u32Len;
642 qurb->pvData = pvData;
643 qurb->pvURB = pvURB;
644 qurb->u32Handle = u32Handle;
645 qurb->fCompleted = false;
646 qurb->fInput = (u8Direction == VUSB_DIRECTION_IN);
647 qurb->u32TransferredLen = 0;
648
649 if (pDevice->pTailQURBs)
650 {
651 Assert(pDevice->pTailQURBs->next == NULL);
652 pDevice->pTailQURBs->next = qurb;
653 }
654 else
655 {
656 /* This is the first URB to be added. */
657 Assert(pDevice->pHeadQURBs == NULL);
658 pDevice->pHeadQURBs = qurb;
659 }
660
661 pDevice->pTailQURBs = qurb;
662
[51092]663 releaseDevice(pDevice);
[31891]664
665 *ppRemoteURB = qurb;
666
[51092]667 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]668
669l_leave:
[94965]670 if (RT_FAILURE(vrc))
[31891]671 {
[51092]672 qurbFree(qurb);
[31891]673 }
674
[94965]675 return vrc;
[31891]676}
677
678/* The function checks the URB queue for completed URBs. Also if the client
679 * has requested URB polling, the function will send URB poll requests.
680 */
[51092]681static DECLCALLBACK(int) iface_ReapURB(PREMOTEUSBDEVICE pDevice, uint32_t u32Millies, void **ppvURB,
682 uint32_t *pu32Len, uint32_t *pu32Err)
[31891]683{
[94965]684 int vrc = VINF_SUCCESS;
[31891]685
686 LogFlow(("RemoteUSBBackend::iface_ReapURB %d ms\n", u32Millies));
687
688 if (pDevice->fFailed)
689 {
690 return VERR_VUSB_DEVICE_NOT_ATTACHED;
691 }
692
693 RemoteUSBBackend *pThis = pDevice->pOwner;
694
695 /* Wait for transaction completion. */
[51092]696 uint64_t u64StartTime = RTTimeMilliTS();
[31891]697
[51092]698 if (pThis->pollingEnabledURB())
[31891]699 {
[33004]700 VRDE_USB_REQ_REAP_URB_PARM parm;
[31891]701
[33004]702 parm.code = VRDE_USB_REQ_REAP_URB;
[31891]703
[51092]704 pThis->VRDPServer()->SendUSBRequest(pDevice->u32ClientId, &parm, sizeof(parm));
[31891]705 }
706
707 REMOTEUSBQURB *qurb = NULL;
708
709 for (;;)
710 {
711 uint32_t u32ClientId;
712
[49814]713 if (ASMAtomicXchgBool(&pDevice->fWokenUp, false))
714 break;
715
[31891]716 /* Scan queued URBs, look for completed. */
[51092]717 requestDevice(pDevice);
[31891]718
719 u32ClientId = pDevice->u32ClientId;
720
721 qurb = pDevice->pHeadQURBs;
722
723 while (qurb)
724 {
725 if (qurb->fCompleted)
726 {
727 /* Remove this completed urb from the queue. */
728 if (qurb->prev)
729 {
730 qurb->prev->next = qurb->next;
731 }
732 else
733 {
734 pDevice->pHeadQURBs = qurb->next;
735 }
736
737 if (qurb->next)
738 {
739 qurb->next->prev = qurb->prev;
740 }
741 else
742 {
743 pDevice->pTailQURBs = qurb->prev;
744 }
745
746 qurb->next = NULL;
747 qurb->prev = NULL;
748
749 break;
750 }
751
752 qurb = qurb->next;
753 }
754
[51092]755 releaseDevice(pDevice);
[31891]756
757 if ( qurb
758 || !pDevice->pHeadQURBs
759 || u32Millies == 0
760 || pDevice->fFailed
[51092]761 || (RTTimeMilliTS() - u64StartTime >= (uint64_t)u32Millies))
[31891]762 {
763 /* Got an URB or do not have to wait for an URB. */
764 break;
765 }
766
767 LogFlow(("RemoteUSBBackend::iface_ReapURB iteration.\n"));
768
[51092]769 RTThreadSleep(10);
[31891]770
[51092]771 if (pThis->pollingEnabledURB())
[31891]772 {
[33004]773 VRDE_USB_REQ_REAP_URB_PARM parm;
[31891]774
[33004]775 parm.code = VRDE_USB_REQ_REAP_URB;
[31891]776
[51092]777 pThis->VRDPServer()->SendUSBRequest(u32ClientId, &parm, sizeof(parm));
[31891]778 }
779 }
780
781 LogFlow(("RemoteUSBBackend::iface_ReapURB completed in %lld ms, qurb = %p\n", RTTimeMilliTS () - u64StartTime, qurb));
782
783 if (!qurb)
784 {
785 *ppvURB = NULL;
786 *pu32Len = 0;
787 *pu32Err = VUSBSTATUS_OK;
788 }
789 else
790 {
791 *ppvURB = qurb->pvURB;
792 *pu32Len = qurb->u32Len;
793 *pu32Err = qurb->u32Err;
794
795#ifdef LOG_ENABLED
796 Log(("URB len = %d, data = %p\n", qurb->u32Len, qurb->pvURB));
797 if (qurb->u32Len)
798 {
799 Log(("Received URB content:\n%.*Rhxd\n", qurb->u32Len, qurb->pvData));
800 }
801#endif
802
[51092]803 qurbFree(qurb);
[31891]804 }
805
[94965]806 return vrc;
[31891]807}
808
[51092]809static DECLCALLBACK(int) iface_Wakeup(PREMOTEUSBDEVICE pDevice)
[49814]810{
811 ASMAtomicXchgBool(&pDevice->fWokenUp, true);
812 return VINF_SUCCESS;
813}
814
[51092]815void RemoteUSBBackend::AddRef(void)
[31891]816{
817 cRefs++;
818}
819
[51092]820void RemoteUSBBackend::Release(void)
[31891]821{
822 cRefs--;
823
824 if (cRefs <= 0)
825 {
826 delete this;
827 }
828}
829
[51092]830void RemoteUSBBackend::PollRemoteDevices(void)
[31891]831{
832 if ( mfWillBeDeleted
833 && menmPollRemoteDevicesStatus != PollRemoteDevicesStatus_Dereferenced)
834 {
835 /* Unmount all remote USB devices. */
[51612]836 mConsole->i_processRemoteUSBDevices(mu32ClientId, NULL, 0, false);
[31891]837
838 menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_Dereferenced;
839
[51092]840 Release();
[31891]841
842 return;
843 }
844
[51092]845 switch(menmPollRemoteDevicesStatus)
[31891]846 {
847 case PollRemoteDevicesStatus_Negotiate:
848 {
[33004]849 VRDEUSBREQNEGOTIATEPARM parm;
[31891]850
[33004]851 parm.code = VRDE_USB_REQ_NEGOTIATE;
852 parm.version = VRDE_USB_VERSION;
[38911]853 /* VRDE_USB_VERSION_3: support VRDE_USB_REQ_DEVICE_LIST_EXT_RET. */
854 parm.flags = VRDE_USB_SERVER_CAPS_PORT_VERSION;
[31891]855
[51092]856 mServer->SendUSBRequest(mu32ClientId, &parm, sizeof(parm));
[31891]857
858 /* Reference the object. When the client disconnects and
859 * the backend is about to be deleted, the method must be called
860 * to disconnect the USB devices (as stated above).
861 */
[51092]862 AddRef();
[31891]863
[33540]864 /* Goto the disabled state. When a response will be received
[31891]865 * the state will be changed to the SendRequest.
866 */
867 menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_WaitNegotiateResponse;
868 } break;
869
870 case PollRemoteDevicesStatus_WaitNegotiateResponse:
871 {
872 LogFlow(("USB::PollRemoteDevices: WaitNegotiateResponse\n"));
873 /* Do nothing. */
874 } break;
875
876 case PollRemoteDevicesStatus_SendRequest:
877 {
878 LogFlow(("USB::PollRemoteDevices: SendRequest\n"));
879
880 /* Send a request for device list. */
[33004]881 VRDE_USB_REQ_DEVICE_LIST_PARM parm;
[31891]882
[33004]883 parm.code = VRDE_USB_REQ_DEVICE_LIST;
[31891]884
[51092]885 mServer->SendUSBRequest(mu32ClientId, &parm, sizeof(parm));
[31891]886
887 menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_WaitResponse;
888 } break;
889
890 case PollRemoteDevicesStatus_WaitResponse:
891 {
892 LogFlow(("USB::PollRemoteDevices: WaitResponse\n"));
893
894 if (mfHasDeviceList)
895 {
[51612]896 mConsole->i_processRemoteUSBDevices(mu32ClientId, (VRDEUSBDEVICEDESC *)mpvDeviceList, mcbDeviceList, mfDescExt);
[31891]897 LogFlow(("USB::PollRemoteDevices: WaitResponse after process\n"));
898
899 menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_SendRequest;
900
901 mfHasDeviceList = false;
902 }
903 } break;
904
905 case PollRemoteDevicesStatus_Dereferenced:
906 {
907 LogFlow(("USB::PollRemoteDevices: Dereferenced\n"));
908 /* Do nothing. */
909 } break;
910
911 default:
912 {
[51092]913 AssertFailed();
[31891]914 } break;
915 }
916}
917
[51092]918void RemoteUSBBackend::NotifyDelete(void)
[31891]919{
920 mfWillBeDeleted = true;
921}
922
923/*
924 * The backend maintains a list of UUIDs of devices
925 * which are managed by the backend.
926 */
[51092]927bool RemoteUSBBackend::addUUID(const Guid *pUuid)
[31891]928{
929 unsigned i;
930 for (i = 0; i < RT_ELEMENTS(aGuids); i++)
931 {
[44039]932 if (aGuids[i].isZero())
[31891]933 {
934 aGuids[i] = *pUuid;
935 return true;
936 }
937 }
938
939 return false;
940}
941
[51092]942bool RemoteUSBBackend::findUUID(const Guid *pUuid)
[31891]943{
944 unsigned i;
945 for (i = 0; i < RT_ELEMENTS(aGuids); i++)
946 {
947 if (aGuids[i] == *pUuid)
948 {
949 return true;
950 }
951 }
952
953 return false;
954}
955
[51092]956void RemoteUSBBackend::removeUUID(const Guid *pUuid)
[31891]957{
958 unsigned i;
959 for (i = 0; i < RT_ELEMENTS(aGuids); i++)
960 {
961 if (aGuids[i] == *pUuid)
962 {
[51092]963 aGuids[i].clear();
[31891]964 break;
965 }
966 }
967}
968
969RemoteUSBBackend::RemoteUSBBackend(Console *console, ConsoleVRDPServer *server, uint32_t u32ClientId)
970 :
[51092]971 mConsole(console),
972 mServer(server),
973 cRefs(0),
974 mu32ClientId(u32ClientId),
975 mfHasDeviceList(false),
976 mpvDeviceList(NULL),
977 mcbDeviceList(0),
978 menmPollRemoteDevicesStatus(PollRemoteDevicesStatus_Negotiate),
979 mfPollURB(true),
980 mpDevices(NULL),
981 mfWillBeDeleted(false),
982 mClientVersion(0), /* VRDE_USB_VERSION_2: the client version. */
983 mfDescExt(false) /* VRDE_USB_VERSION_3: VRDE_USB_REQ_DEVICE_LIST_EXT_RET. */
[31891]984{
985 Assert(console);
986 Assert(server);
987
[94965]988 int vrc = RTCritSectInit(&mCritsect);
[31891]989
[94965]990 if (RT_FAILURE(vrc))
[31891]991 {
[51092]992 AssertFailed();
[47117]993 RT_ZERO(mCritsect);
[31891]994 }
995
996 mCallback.pInstance = (PREMOTEUSBBACKEND)this;
997 mCallback.pfnOpen = iface_Open;
998 mCallback.pfnClose = iface_Close;
999 mCallback.pfnReset = iface_Reset;
1000 mCallback.pfnSetConfig = iface_SetConfig;
1001 mCallback.pfnClaimInterface = iface_ClaimInterface;
1002 mCallback.pfnReleaseInterface = iface_ReleaseInterface;
1003 mCallback.pfnInterfaceSetting = iface_InterfaceSetting;
1004 mCallback.pfnQueueURB = iface_QueueURB;
1005 mCallback.pfnReapURB = iface_ReapURB;
1006 mCallback.pfnClearHaltedEP = iface_ClearHaltedEP;
1007 mCallback.pfnCancelURB = iface_CancelURB;
[49814]1008 mCallback.pfnWakeup = iface_Wakeup;
[31891]1009}
1010
1011RemoteUSBBackend::~RemoteUSBBackend()
1012{
1013 Assert(cRefs == 0);
1014
[51092]1015 if (RTCritSectIsInitialized(&mCritsect))
[31891]1016 {
[51092]1017 RTCritSectDelete(&mCritsect);
[31891]1018 }
1019
[51092]1020 RTMemFree(mpvDeviceList);
[31891]1021
[51092]1022 mServer->usbBackendRemoveFromList(this);
[31891]1023}
1024
[51092]1025int RemoteUSBBackend::negotiateResponse(const VRDEUSBREQNEGOTIATERET *pret, uint32_t cbRet)
[31891]1026{
[94965]1027 int vrc = VINF_SUCCESS;
[31891]1028
1029 Log(("RemoteUSBBackend::negotiateResponse: flags = %02X.\n", pret->flags));
1030
1031 LogRel(("Remote USB: Received negotiate response. Flags 0x%02X.\n",
1032 pret->flags));
1033
[33004]1034 if (pret->flags & VRDE_USB_CAPS_FLAG_POLL)
[31891]1035 {
1036 Log(("RemoteUSBBackend::negotiateResponse: client requested URB polling.\n"));
1037 mfPollURB = true;
1038 }
1039 else
1040 {
1041 mfPollURB = false;
1042 }
1043
[33004]1044 /* VRDE_USB_VERSION_2: check the client version. */
1045 if (pret->flags & VRDE_USB_CAPS2_FLAG_VERSION)
[31891]1046 {
1047 /* This could be a client version > 1. */
[51092]1048 if (cbRet >= sizeof(VRDEUSBREQNEGOTIATERET_2))
[31891]1049 {
[33004]1050 VRDEUSBREQNEGOTIATERET_2 *pret2 = (VRDEUSBREQNEGOTIATERET_2 *)pret;
[31891]1051
[33004]1052 if (pret2->u32Version <= VRDE_USB_VERSION)
[31891]1053 {
1054 /* This is OK. The client wants a version supported by the server. */
1055 mClientVersion = pret2->u32Version;
1056 }
1057 else
1058 {
1059 LogRel(("VRDP: ERROR: unsupported remote USB protocol client version %d.\n", pret2->u32Version));
[94965]1060 vrc = VERR_NOT_SUPPORTED;
[31891]1061 }
1062 }
1063 else
1064 {
1065 LogRel(("VRDP: ERROR: invalid remote USB negotiate request packet size %d.\n", cbRet));
[94965]1066 vrc = VERR_NOT_SUPPORTED;
[31891]1067 }
1068 }
1069 else
1070 {
1071 /* This is a client version 1. */
[33004]1072 mClientVersion = VRDE_USB_VERSION_1;
[31891]1073 }
1074
[94965]1075 if (RT_SUCCESS(vrc))
[31891]1076 {
1077 LogRel(("VRDP: remote USB protocol version %d.\n", mClientVersion));
1078
[38911]1079 /* VRDE_USB_VERSION_3: check the client capabilities: VRDE_USB_CLIENT_CAPS_*. */
1080 if (mClientVersion == VRDE_USB_VERSION_3)
1081 {
[51092]1082 if (cbRet >= sizeof(VRDEUSBREQNEGOTIATERET_3))
[38911]1083 {
1084 VRDEUSBREQNEGOTIATERET_3 *pret3 = (VRDEUSBREQNEGOTIATERET_3 *)pret;
1085
1086 mfDescExt = (pret3->u32Flags & VRDE_USB_CLIENT_CAPS_PORT_VERSION) != 0;
1087 }
1088 else
1089 {
1090 LogRel(("VRDP: ERROR: invalid remote USB negotiate request packet size %d.\n", cbRet));
[94965]1091 vrc = VERR_NOT_SUPPORTED;
[38911]1092 }
1093 }
1094
[31891]1095 menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_SendRequest;
1096 }
1097
[94965]1098 return vrc;
[31891]1099}
1100
[51092]1101int RemoteUSBBackend::saveDeviceList(const void *pvList, uint32_t cbList)
[31891]1102{
1103 Log(("RemoteUSBBackend::saveDeviceList: pvList = %p, cbList = %d\n", pvList, cbList));
1104
1105 if (!mfHasDeviceList)
1106 {
[51092]1107 RTMemFree(mpvDeviceList);
[31891]1108 mpvDeviceList = NULL;
[100521]1109 mcbDeviceList = 0;
[31891]1110
1111 if (cbList > 0)
1112 {
[51092]1113 mpvDeviceList = RTMemAlloc(cbList);
[100521]1114 AssertPtrReturn(mpvDeviceList, VERR_NO_MEMORY);
1115
[51092]1116 memcpy(mpvDeviceList, pvList, cbList);
[100521]1117 mcbDeviceList = cbList;
[31891]1118 }
1119
1120 mfHasDeviceList = true;
1121 }
1122
1123 return VINF_SUCCESS;
1124}
1125
[51092]1126void RemoteUSBBackend::request(void)
[31891]1127{
[94965]1128 int vrc = RTCritSectEnter(&mCritsect);
1129 AssertRC(vrc);
[31891]1130}
1131
[51092]1132void RemoteUSBBackend::release(void)
[31891]1133{
1134 RTCritSectLeave(&mCritsect);
1135}
1136
[51092]1137PREMOTEUSBDEVICE RemoteUSBBackend::deviceFromId(VRDEUSBDEVID id)
[31891]1138{
[51092]1139 request();
[31891]1140
1141 REMOTEUSBDEVICE *pDevice = mpDevices;
1142
1143 while (pDevice && pDevice->id != id)
1144 {
1145 pDevice = pDevice->next;
1146 }
1147
[51092]1148 release();
[31891]1149
1150 return pDevice;
1151}
1152
[51092]1153void RemoteUSBBackend::addDevice(PREMOTEUSBDEVICE pDevice)
[31891]1154{
[51092]1155 request();
[31891]1156
1157 pDevice->next = mpDevices;
1158
1159 if (mpDevices)
1160 {
1161 mpDevices->prev = pDevice;
1162 }
1163
1164 mpDevices = pDevice;
1165
[51092]1166 release();
[31891]1167}
1168
[51092]1169void RemoteUSBBackend::removeDevice(PREMOTEUSBDEVICE pDevice)
[31891]1170{
[51092]1171 request();
[31891]1172
1173 if (pDevice->prev)
1174 {
1175 pDevice->prev->next = pDevice->next;
1176 }
1177 else
1178 {
1179 mpDevices = pDevice->next;
1180 }
1181
1182 if (pDevice->next)
1183 {
1184 pDevice->next->prev = pDevice->prev;
1185 }
1186
[51092]1187 release();
[31891]1188}
1189
[51092]1190int RemoteUSBBackend::reapURB(const void *pvBody, uint32_t cbBody)
[31891]1191{
[94965]1192 int vrc = VINF_SUCCESS;
[31891]1193
1194 LogFlow(("RemoteUSBBackend::reapURB: pvBody = %p, cbBody = %d\n", pvBody, cbBody));
1195
[33004]1196 VRDEUSBREQREAPURBBODY *pBody = (VRDEUSBREQREAPURBBODY *)pvBody;
[31891]1197
[96988]1198 /* 'pvBody' memory buffer can contain multiple URBs. */
[51092]1199 while (cbBody >= sizeof(VRDEUSBREQREAPURBBODY))
[31891]1200 {
1201 Log(("RemoteUSBBackend::reapURB: id = %d, flags = %02X, error = %d, handle %d, len = %d.\n",
1202 pBody->id, pBody->flags, pBody->error, pBody->handle, pBody->len));
1203
1204 uint8_t fu8ReapValidFlags;
1205
[33004]1206 if (mClientVersion == VRDE_USB_VERSION_1 || mClientVersion == VRDE_USB_VERSION_2)
[31891]1207 {
[33004]1208 fu8ReapValidFlags = VRDE_USB_REAP_VALID_FLAGS;
[31891]1209 }
1210 else
1211 {
[33004]1212 fu8ReapValidFlags = VRDE_USB_REAP_VALID_FLAGS_3;
[31891]1213 }
1214
1215 /* Verify client's data. */
1216 if ( (pBody->flags & ~fu8ReapValidFlags) != 0
1217 || pBody->handle == 0)
1218 {
1219 LogFlow(("RemoteUSBBackend::reapURB: WARNING: invalid reply data. Skipping the reply.\n"));
[94965]1220 vrc = VERR_INVALID_PARAMETER;
[31891]1221 break;
1222 }
1223
[51092]1224 PREMOTEUSBDEVICE pDevice = deviceFromId(pBody->id);
[31891]1225
1226 if (!pDevice)
1227 {
1228 LogFlow(("RemoteUSBBackend::reapURB: WARNING: invalid device id. Skipping the reply.\n"));
[94965]1229 vrc = VERR_INVALID_PARAMETER;
[31891]1230 break;
1231 }
1232
[96988]1233 uint32_t cbBodyData = 0; /* Data contained in the URB body structure for input URBs. i.e. beyond VRDEUSBREQREAPURBBODY. */
[31891]1234
[51092]1235 requestDevice(pDevice);
[31891]1236
1237 /* Search the queued URB for given handle. */
1238 REMOTEUSBQURB *qurb = pDevice->pHeadQURBs;
1239
1240 while (qurb && qurb->u32Handle != pBody->handle)
1241 {
1242 LogFlow(("RemoteUSBBackend::reapURB: searching: %p handle = %d.\n", qurb, qurb->u32Handle));
1243 qurb = qurb->next;
1244 }
1245
1246 if (!qurb)
1247 {
1248 LogFlow(("RemoteUSBBackend::reapURB: Queued URB not found, probably already canceled. Skipping the URB.\n"));
1249 }
1250 else
1251 {
[96988]1252 LogFlow(("RemoteUSBBackend::reapURB: qurb = %p, u32Err = %d\n", qurb, qurb->u32Err));
[31891]1253
[96988]1254 /* Update the URB error field, if it does not yet indicate an error. */
1255 if (qurb->u32Err == VUSBSTATUS_OK)
[31891]1256 {
[96988]1257 if (mClientVersion == VRDE_USB_VERSION_1)
[31891]1258 {
[96988]1259 switch(pBody->error)
1260 {
1261 case VRDE_USB_XFER_OK: qurb->u32Err = VUSBSTATUS_OK; break;
1262 case VRDE_USB_XFER_STALL: qurb->u32Err = VUSBSTATUS_STALL; break;
1263 case VRDE_USB_XFER_DNR: qurb->u32Err = VUSBSTATUS_DNR; break;
1264 case VRDE_USB_XFER_CRC: qurb->u32Err = VUSBSTATUS_CRC; break;
1265 default: Log(("RemoteUSBBackend::reapURB: Invalid error %d\n", pBody->error));
1266 qurb->u32Err = VUSBSTATUS_DNR; break;
1267 }
[31891]1268 }
[96988]1269 else if ( mClientVersion == VRDE_USB_VERSION_2
1270 || mClientVersion == VRDE_USB_VERSION_3)
[31891]1271 {
[96988]1272 switch(pBody->error)
1273 {
1274 case VRDE_USB_XFER_OK: qurb->u32Err = VUSBSTATUS_OK; break;
1275 case VRDE_USB_XFER_STALL: qurb->u32Err = VUSBSTATUS_STALL; break;
1276 case VRDE_USB_XFER_DNR: qurb->u32Err = VUSBSTATUS_DNR; break;
1277 case VRDE_USB_XFER_CRC: qurb->u32Err = VUSBSTATUS_CRC; break;
1278 case VRDE_USB_XFER_DO: qurb->u32Err = VUSBSTATUS_DATA_OVERRUN; break;
1279 case VRDE_USB_XFER_DU: qurb->u32Err = VUSBSTATUS_DATA_UNDERRUN; break;
[31891]1280
[96988]1281 /* Unmapped errors. */
1282 case VRDE_USB_XFER_BS:
1283 case VRDE_USB_XFER_DTM:
1284 case VRDE_USB_XFER_PCF:
1285 case VRDE_USB_XFER_UPID:
1286 case VRDE_USB_XFER_BO:
1287 case VRDE_USB_XFER_BU:
1288 case VRDE_USB_XFER_ERR:
1289 default: Log(("RemoteUSBBackend::reapURB: Invalid error %d\n", pBody->error));
1290 qurb->u32Err = VUSBSTATUS_DNR; break;
1291 }
[31891]1292 }
[96988]1293 else
1294 {
1295 qurb->u32Err = VUSBSTATUS_DNR;
1296 }
[31891]1297 }
1298
[96988]1299 /* Get the URB data. The URB is completed unless the client tells that this is a fragment of an IN URB. */
[31891]1300 bool fURBCompleted = true;
1301
1302 if (qurb->fInput)
1303 {
[96988]1304 if (pBody->len <= cbBody - sizeof(VRDEUSBREQREAPURBBODY))
1305 cbBodyData = pBody->len; /* VRDE_USB_DIRECTION_IN URBs include some data. */
1306 else
[31891]1307 {
[96988]1308 cbBodyData = cbBody - sizeof(VRDEUSBREQREAPURBBODY);
[31891]1309 qurb->u32Err = VUSBSTATUS_DNR;
1310 }
[96988]1311
1312 if (qurb->u32Err == VUSBSTATUS_OK)
[31891]1313 {
[96988]1314 LogFlow(("RemoteUSBBackend::reapURB: copying data %d bytes\n", pBody->len));
1315 if (pBody->len > qurb->u32Len - qurb->u32TransferredLen)
1316 {
1317 /* Received more data than expected for this URB. If there more fragments follow,
1318 * they will be discarded because the URB handle will not be valid anymore.
1319 */
1320 qurb->u32Err = VUSBSTATUS_DNR;
1321 qurb->u32TransferredLen = qurb->u32Len;
1322 }
1323 else
1324 {
1325 memcpy ((uint8_t *)qurb->pvData + qurb->u32TransferredLen, &pBody[1], pBody->len);
1326 qurb->u32TransferredLen += pBody->len;
1327 }
[31891]1328
[96988]1329 if ( qurb->u32Err == VUSBSTATUS_OK
1330 && (pBody->flags & VRDE_USB_REAP_FLAG_FRAGMENT) != 0)
1331 {
1332 /* If the client sends fragmented packets, accumulate the URB data. */
1333 fURBCompleted = false;
1334 }
[31891]1335 }
1336 }
[96988]1337 else
1338 qurb->u32TransferredLen += pBody->len; /* Update the value for OUT URBs. */
[31891]1339
1340 if (fURBCompleted)
1341 {
[38986]1342 /* Move the URB near the head of URB list, so that iface_ReapURB can
1343 * find it faster. Note that the order of completion must be preserved!
1344 */
[31891]1345 if (qurb->prev)
1346 {
[38986]1347 /* The URB is not in the head. Unlink it from its current position. */
[31891]1348 qurb->prev->next = qurb->next;
1349
1350 if (qurb->next)
1351 {
1352 qurb->next->prev = qurb->prev;
1353 }
1354 else
1355 {
1356 pDevice->pTailQURBs = qurb->prev;
1357 }
1358
[38986]1359 /* And insert it to its new place. */
1360 if (pDevice->pHeadQURBs->fCompleted)
1361 {
[48955]1362 /* At least one other completed URB; insert after the
[38986]1363 * last completed URB.
1364 */
1365 REMOTEUSBQURB *prev_qurb = pDevice->pHeadQURBs;
1366 while (prev_qurb->next && prev_qurb->next->fCompleted)
1367 prev_qurb = prev_qurb->next;
[31891]1368
[38986]1369 qurb->next = prev_qurb->next;
1370 qurb->prev = prev_qurb;
1371
1372 if (prev_qurb->next)
1373 prev_qurb->next->prev = qurb;
1374 else
1375 pDevice->pTailQURBs = qurb;
1376 prev_qurb->next = qurb;
1377 }
1378 else
1379 {
1380 /* No other completed URBs; insert at head. */
1381 qurb->next = pDevice->pHeadQURBs;
1382 qurb->prev = NULL;
[48955]1383
[38986]1384 pDevice->pHeadQURBs->prev = qurb;
1385 pDevice->pHeadQURBs = qurb;
1386 }
[31891]1387 }
1388
1389 qurb->u32Len = qurb->u32TransferredLen; /* Update the final length. */
1390 qurb->fCompleted = true;
1391 }
1392 }
1393
1394 releaseDevice (pDevice);
1395
[33004]1396 if (pBody->flags & VRDE_USB_REAP_FLAG_LAST)
[31891]1397 {
1398 break;
1399 }
1400
1401 /* There is probably a further URB body. */
[96988]1402 if (cbBodyData > cbBody - sizeof(VRDEUSBREQREAPURBBODY))
[31891]1403 {
[94965]1404 vrc = VERR_INVALID_PARAMETER;
[31891]1405 break;
1406 }
1407
[96988]1408 cbBody -= sizeof(VRDEUSBREQREAPURBBODY) + cbBodyData;
1409 pBody = (VRDEUSBREQREAPURBBODY *)((uint8_t *)pBody + sizeof(VRDEUSBREQREAPURBBODY) + cbBodyData);
[31891]1410 }
1411
[94965]1412 LogFlow(("RemoteUSBBackend::reapURB: returns %Rrc\n", vrc));
[31891]1413
[94965]1414 return vrc;
[31891]1415}
1416/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use