rdpusb.c revision e64031e20c39650a7bc902a3e1aba613b9415dee
/** @file
*
* Remote Desktop Protocol client:
* USB Channel Process Functions
*
*/
/*
* Copyright (C) 2006-2007 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "../rdesktop.h"
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#include "vrdpusb.h"
#define RDPUSB_REQ_OPEN (0)
#define RDPUSB_REQ_CLOSE (1)
#define RDPUSB_REQ_RESET (2)
#define RDPUSB_REQ_SET_CONFIG (3)
#define RDPUSB_REQ_CLAIM_INTERFACE (4)
#define RDPUSB_REQ_RELEASE_INTERFACE (5)
#define RDPUSB_REQ_INTERFACE_SETTING (6)
#define RDPUSB_REQ_QUEUE_URB (7)
#define RDPUSB_REQ_REAP_URB (8)
#define RDPUSB_REQ_CLEAR_HALTED_EP (9)
#define RDPUSB_REQ_CANCEL_URB (10)
#define RDPUSB_REQ_DEVICE_LIST (11)
#define RDPUSB_REQ_NEGOTIATE (12)
static VCHANNEL *rdpusb_channel;
#define PROC_BUS_USB "/proc/bus/usb"
/* A device list entry */
#pragma pack (1)
typedef struct _DevListEntry
{
} DevListEntry;
#pragma pack ()
{
if (p)
{
uint16 h, l;
while (*p == ' ') p++; // skiping spaces
if (*p == '.')
{
return (h << 8) + l;
}
}
return 0;
}
{
if (p)
{
while (*p == ' ') p++; // skiping spaces
}
return 0;
}
{
if (p)
{
while (*p == ' ') p++; // skiping spaces
return (tmp16);
}
return 0;
}
{
if (p)
{
}
return 0;
}
static void *build_device_list (int *plen)
{
Log(("RDPUSB build_device_list"));
char szLine[1024];
char *p;
DevListEntry *e = NULL;
if (f != NULL)
{
{
if (p) *p = 0;
p = &szLine[0];
// Log(("%s\n", szLine));
switch (*p)
{
case 'T':
{
/* A new device, allocate memory. */
{
size += sizeof (DevListEntry);
}
if (len > 0)
{
char path[128];
Log(("%s: id = %X, class = %d access = %d\n", path, e->id, e->bDeviceClass, access (path, R_OK | W_OK)));
{
}
else
{
/* The entry was not filled. Reuse.*/
}
}
memset (e, 0, sizeof (DevListEntry));
len += sizeof (DevListEntry);
// T: Bus=03 Lev=02 Prnt=36 Port=01 Cnt=02 Dev#= 38 Spd=12 MxCh= 0
/* Get bus and dev#. */
if (!tmp8)
{
e->id = 0;
}
else
{
e->idPort &= 0x00FF;
e->id &= 0x00FF;
}
if (e)
{
if (!tmp8)
{
e->id = 0;
}
else
{
e->id &= 0xFF00;
}
if (e->id != 0)
{
e->idPort &= 0xFF00;
}
}
} break;
case 'D':
{
// D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
if (e && e->id)
{
}
} break;
case 'P':
{
// P: Vendor=0483 ProdID=2016 Rev= 0.01
if (e && e->id)
{
}
} break;
case 'S':
{
if (e && e->id)
{
// S: Manufacturer=STMicroelectronics
uint16 offset_addr = 0;
if (s)
{
}
else
{
if (s)
{
}
else
{
if (s)
{
}
}
}
if (s)
{
int l = strlen (s) + 1;
if (l > 1)
{
{
size += l;
}
len += l;
}
else
{
}
}
}
} break;
}
}
if (len > 0)
{
Log(("Finalising list\n"));
#ifdef RDPUSB_DEBUG
#endif
char path[128];
{
}
else
{
/* The entry was not filled. Reuse.*/
}
{
size += 2;
}
e->oNext = 0;
lastlen += 2;
}
fclose (f);
}
return buffer;
}
static STREAM
{
STREAM s;
return s;
}
static void
{
#ifdef RDPUSB_DEBUG
Log(("RDPUSB send:\n"));
#endif
}
static void
{
out_uint32_le(s, devid);
s_mark_end(s);
rdpusb_send(s);
}
static void
{
}
static inline int
{
{
return VRDP_USB_STATUS_DEVICE_REMOVED;
}
return VRDP_USB_STATUS_SUCCESS;
}
static struct usb_proxy *
{
{
}
return proxy;
}
static void
rdpusb_reap_urbs (void)
{
STREAM s;
while (proxy)
{
if (pUrb)
{
int datalen = 0;
{
}
if (datalen)
{
}
s_mark_end(s);
rdpusb_send(s);
{
/* Remove the URB from list. */
{
}
else
{
}
{
}
}
#ifdef RDPUSB_DEBUG
#endif
#ifdef RDPUSB_DEBUG
#endif
}
}
return;
}
static void
{
int rc;
#ifdef RDPUSB_DEBUG
Log(("RDPUSB recv:\n"));
#endif
in_uint32_le (s, len);
{
return;
}
switch (code)
{
case RDPUSB_REQ_OPEN:
{
char devpath[128];
in_uint32_le(s, devid);
if (rc != VINF_SUCCESS)
{
}
else
{
if (g_proxies)
{
}
}
} break;
case RDPUSB_REQ_CLOSE:
{
in_uint32_le(s, devid);
if (proxy)
{
{
}
else
{
}
{
}
}
/* No reply. */
} break;
case RDPUSB_REQ_RESET:
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (rc != VINF_SUCCESS)
{
}
} break;
case RDPUSB_REQ_SET_CONFIG:
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
case RDPUSB_REQ_QUEUE_URB:
{
in_uint32_le(s, devid);
if (!proxy)
{
/* No reply. */
break;
}
/* Allocate a single block for URB description and data buffer */
);
if (datalen)
{
}
/* No reply required. */
if (rc)
{
{
}
}
else
{
}
} break;
case RDPUSB_REQ_REAP_URB:
{
rdpusb_reap_urbs ();
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
case RDPUSB_REQ_CANCEL_URB:
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
in_uint32_le(s, handle);
{
}
if (pUrb)
{
/* No reply required. */
/* Remove URB from list. */
{
}
else
{
}
{
}
// xfree (pUrb);
}
} break;
case RDPUSB_REQ_DEVICE_LIST:
{
int len = 0;
if (len)
{
}
else
{
out_uint16_le(s, 0);
}
s_mark_end(s);
rdpusb_send(s);
if (buf)
{
}
} break;
case RDPUSB_REQ_NEGOTIATE:
{
s_mark_end(s);
rdpusb_send(s);
} break;
default:
break;
}
}
void
{
// Log(("RDPUSB: rdpusb_add_fds: begin *n = %d\n", *n));
while (proxy)
{
if (fd != -1)
{
// Log(("RDPUSB: rdpusb_add_fds: adding %d\n", proxy->priv.File));
}
}
// Log(("RDPUSB: rdpusb_add_fds: end *n = %d\n", *n));
return;
}
void
{
(void)rfds;
(void)wfds;
// Log(("RDPUSB: rdpusb_check_fds: begin\n"));
rdpusb_reap_urbs ();
// Log(("RDPUSB: rdpusb_check_fds: end\n"));
return;
}
rdpusb_init(void)
{
return (rdpusb_channel != NULL);
}
void
rdpusb_close (void)
{
while (proxy)
{
}
return;
}