2 * Copyright (C) 2005-2007 Takahiro Hirofuchi
6 #include "usbip_common.h"
10 #define PROGNAME "libusbip"
16 extern struct udev
*udev_context
;
24 static const struct speed_string speed_strings
[] = {
25 { USB_SPEED_UNKNOWN
, "unknown", "Unknown Speed"},
26 { USB_SPEED_LOW
, "1.5", "Low Speed(1.5Mbps)" },
27 { USB_SPEED_FULL
, "12", "Full Speed(12Mbps)" },
28 { USB_SPEED_HIGH
, "480", "High Speed(480Mbps)" },
29 { USB_SPEED_WIRELESS
, "53.3-480", "Wireless"},
30 { USB_SPEED_SUPER
, "5000", "Super Speed(5000Mbps)" },
34 struct portst_string
{
39 static struct portst_string portst_strings
[] = {
40 { SDEV_ST_AVAILABLE
, "Device Available" },
41 { SDEV_ST_USED
, "Device in Use" },
42 { SDEV_ST_ERROR
, "Device Error"},
43 { VDEV_ST_NULL
, "Port Available"},
44 { VDEV_ST_NOTASSIGNED
, "Port Initializing"},
45 { VDEV_ST_USED
, "Port in Use"},
46 { VDEV_ST_ERROR
, "Port Error"},
50 const char *usbip_status_string(int32_t status
)
52 for (int i
= 0; portst_strings
[i
].desc
!= NULL
; i
++)
53 if (portst_strings
[i
].num
== status
)
54 return portst_strings
[i
].desc
;
56 return "Unknown Status";
59 const char *usbip_speed_string(int num
)
61 for (int i
= 0; speed_strings
[i
].speed
!= NULL
; i
++)
62 if (speed_strings
[i
].num
== num
)
63 return speed_strings
[i
].desc
;
65 return "Unknown Speed";
69 #define DBG_UDEV_INTEGER(name)\
70 dbg("%-20s = %x", to_string(name), (int) udev->name)
72 #define DBG_UINF_INTEGER(name)\
73 dbg("%-20s = %x", to_string(name), (int) uinf->name)
75 void dump_usb_interface(struct usbip_usb_interface
*uinf
)
79 usbip_names_get_class(buff
, sizeof(buff
),
80 uinf
->bInterfaceClass
,
81 uinf
->bInterfaceSubClass
,
82 uinf
->bInterfaceProtocol
);
83 dbg("%-20s = %s", "Interface(C/SC/P)", buff
);
86 void dump_usb_device(struct usbip_usb_device
*udev
)
90 dbg("%-20s = %s", "path", udev
->path
);
91 dbg("%-20s = %s", "busid", udev
->busid
);
93 usbip_names_get_class(buff
, sizeof(buff
),
95 udev
->bDeviceSubClass
,
96 udev
->bDeviceProtocol
);
97 dbg("%-20s = %s", "Device(C/SC/P)", buff
);
99 DBG_UDEV_INTEGER(bcdDevice
);
101 usbip_names_get_product(buff
, sizeof(buff
),
104 dbg("%-20s = %s", "Vendor/Product", buff
);
106 DBG_UDEV_INTEGER(bNumConfigurations
);
107 DBG_UDEV_INTEGER(bNumInterfaces
);
109 dbg("%-20s = %s", "speed",
110 usbip_speed_string(udev
->speed
));
112 DBG_UDEV_INTEGER(busnum
);
113 DBG_UDEV_INTEGER(devnum
);
117 int read_attr_value(struct udev_device
*dev
, const char *name
,
124 attr
= udev_device_get_sysattr_value(dev
, name
);
126 err("udev_device_get_sysattr_value failed");
130 /* The client chooses the device configuration
131 * when attaching it so right after being bound
132 * to usbip-host on the server the device will
133 * have no configuration.
134 * Therefore, attributes such as bConfigurationValue
135 * and bNumInterfaces will not exist and sscanf will
136 * fail. Check for these cases and don't treat them
140 ret
= sscanf(attr
, format
, &num
);
142 if (strcmp(name
, "bConfigurationValue") &&
143 strcmp(name
, "bNumInterfaces")) {
144 err("sscanf failed for attribute %s", name
);
155 int read_attr_speed(struct udev_device
*dev
)
159 speed
= udev_device_get_sysattr_value(dev
, "speed");
161 err("udev_device_get_sysattr_value failed");
165 for (int i
= 0; speed_strings
[i
].speed
!= NULL
; i
++) {
166 if (!strcmp(speed
, speed_strings
[i
].speed
))
167 return speed_strings
[i
].num
;
172 return USB_SPEED_UNKNOWN
;
175 #define READ_ATTR(object, type, dev, name, format) \
177 (object)->name = (type) read_attr_value(dev, to_string(name), \
182 int read_usb_device(struct udev_device
*sdev
, struct usbip_usb_device
*udev
)
184 uint32_t busnum
, devnum
;
185 const char *path
, *name
;
187 READ_ATTR(udev
, uint8_t, sdev
, bDeviceClass
, "%02x\n");
188 READ_ATTR(udev
, uint8_t, sdev
, bDeviceSubClass
, "%02x\n");
189 READ_ATTR(udev
, uint8_t, sdev
, bDeviceProtocol
, "%02x\n");
191 READ_ATTR(udev
, uint16_t, sdev
, idVendor
, "%04x\n");
192 READ_ATTR(udev
, uint16_t, sdev
, idProduct
, "%04x\n");
193 READ_ATTR(udev
, uint16_t, sdev
, bcdDevice
, "%04x\n");
195 READ_ATTR(udev
, uint8_t, sdev
, bConfigurationValue
, "%02x\n");
196 READ_ATTR(udev
, uint8_t, sdev
, bNumConfigurations
, "%02x\n");
197 READ_ATTR(udev
, uint8_t, sdev
, bNumInterfaces
, "%02x\n");
199 READ_ATTR(udev
, uint8_t, sdev
, devnum
, "%d\n");
200 udev
->speed
= read_attr_speed(sdev
);
202 path
= udev_device_get_syspath(sdev
);
203 name
= udev_device_get_sysname(sdev
);
205 strncpy(udev
->path
, path
, SYSFS_PATH_MAX
);
206 strncpy(udev
->busid
, name
, SYSFS_BUS_ID_SIZE
);
208 sscanf(name
, "%u-%u", &busnum
, &devnum
);
209 udev
->busnum
= busnum
;
214 int read_usb_interface(struct usbip_usb_device
*udev
, int i
,
215 struct usbip_usb_interface
*uinf
)
217 char busid
[SYSFS_BUS_ID_SIZE
];
218 struct udev_device
*sif
;
220 sprintf(busid
, "%s:%d.%d", udev
->busid
, udev
->bConfigurationValue
, i
);
222 sif
= udev_device_new_from_subsystem_sysname(udev_context
, "usb", busid
);
224 err("udev_device_new_from_subsystem_sysname %s failed", busid
);
228 READ_ATTR(uinf
, uint8_t, sif
, bInterfaceClass
, "%02x\n");
229 READ_ATTR(uinf
, uint8_t, sif
, bInterfaceSubClass
, "%02x\n");
230 READ_ATTR(uinf
, uint8_t, sif
, bInterfaceProtocol
, "%02x\n");
235 int usbip_names_init(char *f
)
237 return names_init(f
);
240 void usbip_names_free(void)
245 void usbip_names_get_product(char *buff
, size_t size
, uint16_t vendor
,
248 const char *prod
, *vend
;
250 prod
= names_product(vendor
, product
);
252 prod
= "unknown product";
255 vend
= names_vendor(vendor
);
257 vend
= "unknown vendor";
259 snprintf(buff
, size
, "%s : %s (%04x:%04x)", vend
, prod
, vendor
, product
);
262 void usbip_names_get_class(char *buff
, size_t size
, uint8_t class,
263 uint8_t subclass
, uint8_t protocol
)
265 const char *c
, *s
, *p
;
267 if (class == 0 && subclass
== 0 && protocol
== 0) {
268 snprintf(buff
, size
, "(Defined at Interface level) (%02x/%02x/%02x)", class, subclass
, protocol
);
272 p
= names_protocol(class, subclass
, protocol
);
274 p
= "unknown protocol";
276 s
= names_subclass(class, subclass
);
278 s
= "unknown subclass";
280 c
= names_class(class);
284 snprintf(buff
, size
, "%s / %s / %s (%02x/%02x/%02x)", c
, s
, p
, class, subclass
, protocol
);