USBIP C library 0.7.0
Virtual USB devices & host drivers over USB/IP
Loading...
Searching...
No Matches
Device core API

Build a virtual USB device from typed descriptors. More...

Files

file  usbip-device.h
 Device core API - descriptors, standard requests, endpoints, dispatch.
 

Macros

#define USBIP_WINUSB_DEFAULT_GUID
 The DeviceInterfaceGUID advertised when enable_winusb() is passed NULL.
 

Typedefs

typedef struct usbip_device usbip_device
 The virtual device

 
typedef struct usbip_ep usbip_ep
 An endpoint (byte pipe)

 
typedef int(* usbip_device_control_fn) (void *ctx, const usb_setup *setup, uint8_t *buf, uint16_t len)
 Class/vendor control handler (core form).
 
typedef int(* usbip_device_set_alt_fn) (void *ctx, int ifnum, int alt)
 SET_INTERFACE handler: the host selected alternate setting alt on ifnum.
 
typedef void(* usbip_ep_out_fn) (void *ctx, usbip_ep *ep, const void *data, int len)
 A bulk/interrupt OUT packet arrived from the host.
 
typedef int(* usbip_ep_iso_fn) (void *ctx, usbip_ep *ep, int npkts, uint32_t *lens, uint8_t *buf)
 The isochronous data callback: one call handles one transfer's packets.
 

Functions

usbip_deviceusbip_device_create (uint16_t vid, uint16_t pid)
 Create a virtual device with the given vendor/product IDs.
 
void usbip_device_set_strings (usbip_device *dev, const char *mfr, const char *product, const char *serial)
 Set the manufacturer / product / serial string descriptors (indices 1-3).
 
void usbip_device_set_class (usbip_device *dev, uint8_t cls, uint8_t sub, uint8_t proto)
 Set the device-descriptor class triple.
 
void usbip_device_set_bcd_device (usbip_device *dev, uint16_t bcd)
 Set the device release number (bcdDevice).
 
void usbip_device_set_speed (usbip_device *dev, usb_speed speed)
 Report a link speed (default USB_SPEED_FULL).
 
usb_speed usbip_device_get_speed (usbip_device *dev)
 The device's reported link speed (for speed-aware class code; a class reaches its device with usbip_function_device() from classes/usb_class.h).
 
int usbip_device_add_string (usbip_device *dev, const char *str)
 Register an extra string descriptor (e.g.
 
void usbip_device_set_composite (usbip_device *dev)
 Declare the device composite: several independent class functions on one device.
 
int usbip_device_enable_winusb (usbip_device *dev, const char *guid)
 Advertise WinUSB via BOTH Microsoft OS 1.0 and Microsoft OS 2.0 descriptors.
 
int usbip_device_enable_msos (usbip_device *dev, const char *compatible, const char *guid)
 Generalized Microsoft OS descriptor advertisement with any Compatible ID.
 
void usbip_device_enable_webusb (usbip_device *dev, uint8_t vendor_code, const char *url)
 Advertise WebUSB so a capable browser can surface and open the device.
 
void usbip_device_set_iso_pacing (usbip_device *dev, int enabled)
 Pace isochronous completions to real wall-clock time.
 
int usbip_device_add_descriptor (usbip_device *dev, const void *descriptor)
 Append a typed descriptor (interface / endpoint / HID / class-specific) to the device's configuration, in wire order.
 
usbip_epusbip_device_add_endpoint (usbip_device *dev, const void *ep_descriptor)
 Append an endpoint descriptor and return the pipe it created.
 
uint8_t usbip_device_reserve_endpoint (usbip_device *dev, uint8_t want_addr)
 Claim an endpoint address now, for an endpoint declared later.
 
int usbip_device_get_num_interfaces (usbip_device *dev)
 How many interface numbers the device has registered so far - i.e.
 
void usbip_device_set_interface_string (usbip_device *dev, uint8_t ifnum, uint8_t alt, uint8_t istr)
 Patch iInterface in the (ifnum, alt) interface descriptor already appended.
 
void usbip_device_on_control (usbip_device *dev, int ifnum, usbip_device_control_fn cb, void *ctx)
 Register the class/vendor control handler for one interface.
 
void usbip_device_on_set_alt (usbip_device *dev, int ifnum, usbip_device_set_alt_fn cb, void *ctx)
 Register the SET_INTERFACE handler for one interface.
 
void usbip_ep_on_out (usbip_ep *ep, usbip_ep_out_fn cb, void *ctx)
 Register the OUT-data callback for an endpoint.
 
void usbip_ep_on_iso (usbip_ep *ep, usbip_ep_iso_fn cb, void *ctx)
 Register the isochronous data callback for an endpoint (either direction).
 
int usbip_device_group_begin (usbip_device *dev)
 Open a new descriptor group: a run of descriptors that form one function of the device (what an IAD groups, and what one Microsoft OS advertisement covers).
 
void usbip_device_group_abort (usbip_device *dev)
 Roll back everything appended since the last usbip_device_group_begin(): descriptors, endpoints, interface registrations, reservations, control/set-alt registrations, and the group's Microsoft OS advertisements.
 
int usbip_device_enable_msos_group (usbip_device *dev, int group, const char *compatible, const char *guid)
 Advertise Microsoft OS descriptors scoped to one descriptor group.
 
uint8_t usbip_endpoint_address (usbip_ep *ep)
 An endpoint's bEndpointAddress, as it appears in the descriptor the host reads.
 
int usbip_device_read (usbip_ep *ep, void *buf, int len, unsigned timeout_ms)
 Read host-to-device (OUT) data from an endpoint, blocking up to timeout_ms.
 
int usbip_device_write (usbip_ep *ep, const void *buf, int len, unsigned timeout_ms)
 Write device-to-host (IN) data to an endpoint, blocking up to timeout_ms.
 
void usbip_ep_stall (usbip_ep *ep)
 Halt (STALL) a non-control endpoint.
 
int usbip_device_plug (usbip_device *dev, usb_transport *transport)
 Plug the device onto a transport and start serving it.
 
void usbip_device_unplug (usbip_device *dev)
 Stop serving a device previously passed to usbip_device_plug().
 
void usbip_device_set_busid (usbip_device *dev, const char *busid)
 Name this device on the wire, instead of the 1-<n> assigned at plug time.
 
const char * usbip_device_get_busid (usbip_device *dev)
 The busid this device is exported under - what usbip attach -b takes.
 
int usbip_device_is_composite (usbip_device *dev)
 Whether the app declared this device composite (see usbip_device_set_composite()).
 

Detailed Description

Build a virtual USB device from typed descriptors.

Create a usbip_device, append descriptors (usbip_device_add_descriptor() / usbip_device_add_endpoint()), register control and data callbacks, then usbip_device_plug() it onto a transport - the program becomes the USB/IP server (roles). Data moves through usbip_ep pipes with usbip_device_read() / usbip_device_write(). The core knows only descriptors and requests and links on its own as libusbip-device; composition lives in the class layer.

Macro Definition Documentation

◆ USBIP_WINUSB_DEFAULT_GUID

#define USBIP_WINUSB_DEFAULT_GUID

The DeviceInterfaceGUID advertised when enable_winusb() is passed NULL.

Typedef Documentation

◆ usbip_device

typedef struct usbip_device usbip_device

The virtual device

◆ usbip_ep

typedef struct usbip_ep usbip_ep

An endpoint (byte pipe)

◆ usbip_device_control_fn

typedef int(* usbip_device_control_fn) (void *ctx, const usb_setup *setup, uint8_t *buf, uint16_t len)

Class/vendor control handler (core form).

For an IN request, fill buf with up to len bytes and return the count; for an OUT request, buf holds len bytes and you return >= 0; return a negative value to STALL. Standard requests are handled by the core before this is called.

Parameters
ctxthe context registered with usbip_device_on_control().
setupthe 8-byte SETUP packet.
bufdata buffer (IN: to fill; OUT: incoming data).
lenIN: capacity of buf; OUT: number of bytes in buf.
Returns
bytes produced (IN) / consumed-OK (OUT, >= 0), or < 0 to STALL.

◆ usbip_device_set_alt_fn

typedef int(* usbip_device_set_alt_fn) (void *ctx, int ifnum, int alt)

SET_INTERFACE handler: the host selected alternate setting alt on ifnum.

Parameters
ctxthe context registered with usbip_device_on_set_alt().
ifnumthe interface whose alternate setting changed.
altthe newly selected alternate setting.
Returns
ignored.

◆ usbip_ep_out_fn

typedef void(* usbip_ep_out_fn) (void *ctx, usbip_ep *ep, const void *data, int len)

A bulk/interrupt OUT packet arrived from the host.

Parameters
ctxthe context registered with usbip_ep_on_out().
epthe OUT endpoint it arrived on.
datathe received bytes.
lennumber of bytes in data.

◆ usbip_ep_iso_fn

typedef int(* usbip_ep_iso_fn) (void *ctx, usbip_ep *ep, int npkts, uint32_t *lens, uint8_t *buf)

The isochronous data callback: one call handles one transfer's packets.

buf and lens always describe the same layout: npkts packets laid back-to-back in buf, packet i being lens[i] bytes (no padding between packets). The endpoint's direction decides who fills them in:

  • OUT endpoint - the host sent data. The packets arrive filled in; read them. The buffer is discarded on return.
  • IN endpoint - the host wants data. On entry lens[i] holds the size the host asked for, and buf has room for all of it. Write each packet's data and set lens[i] to the bytes you wrote (anything from 0, an empty packet, up to the requested size).

An endpoint's direction never changes, so a given callback only ever sees one of the two cases.

Parameters
ctxthe context registered with usbip_ep_on_iso().
epthe isochronous endpoint.
npktsnumber of packets.
lensthe per-packet sizes (see above).
bufthe packet bytes, back-to-back (see above).
Returns
USB_SUCCESS (0) on success.

Function Documentation

◆ usbip_device_create()

usbip_device * usbip_device_create ( uint16_t  vid,
uint16_t  pid 
)

Create a virtual device with the given vendor/product IDs.

Parameters
vididVendor.
pididProduct.
Returns
the new device, or NULL on allocation failure. Destroy it implicitly via usbip_device_unplug() / process exit.

◆ usbip_device_set_strings()

void usbip_device_set_strings ( usbip_device dev,
const char *  mfr,
const char *  product,
const char *  serial 
)

Set the manufacturer / product / serial string descriptors (indices 1-3).

Parameters
devthe device.
mfriManufacturer string (may be NULL).
productiProduct string (may be NULL).
serialiSerialNumber string (may be NULL).

◆ usbip_device_set_class()

void usbip_device_set_class ( usbip_device dev,
uint8_t  cls,
uint8_t  sub,
uint8_t  proto 
)

Set the device-descriptor class triple.

Default USB_CLASS_PER_INTERFACE (0/0/0) means "class defined per interface". Multi-interface devices (e.g. UVC) use USB_CLASS_MISC / USB_SUBCLASS_COMMON / USB_PROTOCOL_IAD (0xEF/0x02/0x01) so the host honours the Interface Association Descriptor.

Parameters
devthe device.
clsbDeviceClass.
subbDeviceSubClass.
protobDeviceProtocol.

◆ usbip_device_set_bcd_device()

void usbip_device_set_bcd_device ( usbip_device dev,
uint16_t  bcd 
)

Set the device release number (bcdDevice).

Default 0x0100.

Some hosts bind a driver only on an exact match (e.g. Windows + a CSR Bluetooth radio's 0x8891/0x0c5c).

Parameters
devthe device.
bcdbcdDevice (BCD, e.g. 0x0100 = "1.00").

◆ usbip_device_set_speed()

void usbip_device_set_speed ( usbip_device dev,
usb_speed  speed 
)

Report a link speed (default USB_SPEED_FULL).

USB/IP is URB-level, so "high speed" is just the reported speed + 512-byte bulk endpoints - no companion descriptors. Call BEFORE adding interfaces so speed-aware classes (e.g. CDC-ACM) size their bulk endpoints accordingly.

Parameters
devthe device.
speedthe reported usb_speed.

◆ usbip_device_get_speed()

usb_speed usbip_device_get_speed ( usbip_device dev)

The device's reported link speed (for speed-aware class code; a class reaches its device with usbip_function_device() from classes/usb_class.h).

Parameters
devthe device.
Returns
the reported usb_speed.

◆ usbip_device_add_string()

int usbip_device_add_string ( usbip_device dev,
const char *  str 
)

Register an extra string descriptor (e.g.

an interface name).

Indices 1-3 are reserved for the manufacturer/product/serial set by usbip_device_set_strings().

Parameters
devthe device.
strthe string to add.
Returns
the new descriptor's index, for use as an iInterface/iProduct/… value.

◆ usbip_device_set_composite()

void usbip_device_set_composite ( usbip_device dev)

Declare the device composite: several independent class functions on one device.

Call before adding any class. Sets the device-descriptor triple to 0xEF/0x02/0x01 (Miscellaneous / Common Class / Interface Association) and asks every multi-interface class to emit an Interface Association Descriptor grouping its own interfaces.

Linux does not need this - cdc_acm and friends group their interfaces from the class-specific descriptors (CDC's Union descriptor). Windows does: usbccgp splits a composite device into one child devnode per function, and without an IAD it splits per interface, handing CDC's data interface to a separate devnode from its communications interface, so the COM port never forms.

A single-function device must NOT set this - it would advertise an association that describes the whole device.

The triple is pinned from here on: a class that sets its own device triple (e.g. Bluetooth's 0xE0/0x01/0x01) is ignored with a diagnostic, because overwriting 0xEF/0x02/0x01 would silently unmake the composite.

Parameters
devthe device.

◆ usbip_device_enable_winusb()

int usbip_device_enable_winusb ( usbip_device dev,
const char *  guid 
)

Advertise WinUSB via BOTH Microsoft OS 1.0 and Microsoft OS 2.0 descriptors.

Windows then auto-installs the WinUSB driver, so libusb apps like dfu-util work without Zadig. Bumps bcdUSB to 0x0210 so the host fetches the BOS.

Parameters
devthe device.
guidDeviceInterfaceGUID to advertise, or NULL for USBIP_WINUSB_DEFAULT_GUID.
Return values
USB_SUCCESSrecorded.
USB_ERROR_NO_MEMthe advertisement table is full or memory ran out.

◆ usbip_device_enable_msos()

int usbip_device_enable_msos ( usbip_device dev,
const char *  compatible,
const char *  guid 
)

Generalized Microsoft OS descriptor advertisement with any Compatible ID.

Use "WINUSB" (libusb/dfu-util) or "MTP" (Media Transfer Protocol).

This form describes the whole device, which is what a single-function device wants. On a composite, scope the advertisement to one function instead - see usbip_function_enable_msos().

Parameters
devthe device.
compatiblethe Compatible ID string (e.g. "WINUSB", "MTP").
guidDeviceInterfaceGUID to add, or NULL to omit it (MTP needs none).
Return values
USB_SUCCESSrecorded.
USB_ERROR_NO_MEMthe advertisement table is full or memory ran out.

◆ usbip_device_enable_webusb()

void usbip_device_enable_webusb ( usbip_device dev,
uint8_t  vendor_code,
const char *  url 
)

Advertise WebUSB so a capable browser can surface and open the device.

Adds a WebUSB platform-capability descriptor to the BOS and answers the bVendorCode/GET_URL (wIndex 0x02) vendor request with url. Bumps bcdUSB to 0x0210 (BOS present). Pair with usbip_device_enable_winusb() so the device also binds WinUSB on Windows.

Parameters
devthe device.
vendor_codethe bVendorCode for the WebUSB request; pick a value distinct from WinUSB's 0x20/0x21 if both are enabled.
urlthe landing-page URL.

◆ usbip_device_set_iso_pacing()

void usbip_device_set_iso_pacing ( usbip_device dev,
int  enabled 
)

Pace isochronous completions to real wall-clock time.

USB/IP has no SOF clock, so by default iso transfers complete instantly and the host's audio/video engine free-runs (a UAC speaker plays many times too fast). When enabled, each iso transfer is held until the time its packet schedule would really take. Pacing blocks the per-connection serve thread, so it best suits a single iso stream (e.g. an audio speaker). Off by default.

Parameters
devthe device.
enablednon-zero to enable pacing, 0 to disable.

◆ usbip_device_add_descriptor()

int usbip_device_add_descriptor ( usbip_device dev,
const void *  descriptor 
)

Append a typed descriptor (interface / endpoint / HID / class-specific) to the device's configuration, in wire order.

The core parses two standard types as it appends: an interface descriptor registers its bInterfaceNumber and becomes the append cursor; an endpoint descriptor gets its number allocated (the requested address is a preference - see usbip_device_add_endpoint()) and bumps bNumEndpoints in the owning interface descriptor, which should therefore be left 0.

The descriptor's bytes are appended as they are, so its 16-bit fields have to be little-endian already. Declaring it USB_PACKED is what arranges that - assign the fields in host order and the layout takes care of itself, on any host. A descriptor built as a raw byte array wants USB_U16LE instead.

Parameters
devthe device.
descriptorpointer to a USB_PACKED descriptor whose first byte is its length.
Return values
USB_SUCCESSappended.
USB_ERROR_NO_MEMthe configuration blob is full, or (for an endpoint descriptor) no endpoint number was free in its direction.

◆ usbip_device_add_endpoint()

usbip_ep * usbip_device_add_endpoint ( usbip_device dev,
const void *  ep_descriptor 
)

Append an endpoint descriptor and return the pipe it created.

Prefer this over usbip_device_add_descriptor() for endpoints: bEndpointAddress is only a preference. It is honoured when the number is free, but if another interface already holds it the endpoint is relocated to the lowest free number in the same direction. Pass a zero endpoint number (0x00 OUT / 0x80 IN) to say "any". Because the address may change, keep the returned pipe rather than looking it up again by the address you asked for.

Parameters
devthe device.
ep_descriptora packed usb_endpoint_descriptor.
Returns
the endpoint, or NULL if it could not be added.

◆ usbip_device_reserve_endpoint()

uint8_t usbip_device_reserve_endpoint ( usbip_device dev,
uint8_t  want_addr 
)

Claim an endpoint address now, for an endpoint declared later.

Needed when a class-specific descriptor has to name an endpoint that has not been declared yet (UVC's VideoStreaming input header). The claim belongs to the current interface (the last interface descriptor appended), so its alternate settings can all use it; the allocator hands the same number back when the real endpoint descriptor arrives.

Parameters
devthe device.
want_addrthe preferred address (direction bit included), e.g. 0x81.
Returns
the reserved address, or 0 if no number was free in that direction - or if no interface has been appended yet to own the claim.

◆ usbip_device_get_num_interfaces()

int usbip_device_get_num_interfaces ( usbip_device dev)

How many interface numbers the device has registered so far - i.e.

the next free bInterfaceNumber, and the bNumInterfaces the host will see.

Parameters
devthe device.
Returns
highest bInterfaceNumber + 1, or 0 when no interface exists yet.

◆ usbip_device_set_interface_string()

void usbip_device_set_interface_string ( usbip_device dev,
uint8_t  ifnum,
uint8_t  alt,
uint8_t  istr 
)

Patch iInterface in the (ifnum, alt) interface descriptor already appended.

Does nothing if no such interface descriptor exists.

Parameters
devthe device.
ifnumthe bInterfaceNumber.
altthe bAlternateSetting.
istrstring descriptor index (from usbip_device_add_string()).

◆ usbip_device_on_control()

void usbip_device_on_control ( usbip_device dev,
int  ifnum,
usbip_device_control_fn  cb,
void *  ctx 
)

Register the class/vendor control handler for one interface.

Interface-recipient requests are routed to their bInterfaceNumber's handler. ifnum -1 registers the device-level fallback: it receives every non-interface-recipient request, and interface-recipient requests whose bInterfaceNumber has no handler of its own.

Parameters
devthe device.
ifnumthe bInterfaceNumber (0-15), or -1 for the device-level fallback.
cbthe handler, or NULL to remove it.
ctxpassed back to cb.

◆ usbip_device_on_set_alt()

void usbip_device_on_set_alt ( usbip_device dev,
int  ifnum,
usbip_device_set_alt_fn  cb,
void *  ctx 
)

Register the SET_INTERFACE handler for one interface.

Parameters
devthe device.
ifnumthe bInterfaceNumber (0-15).
cbthe handler, or NULL to remove it.
ctxpassed back to cb.

◆ usbip_ep_on_out()

void usbip_ep_on_out ( usbip_ep ep,
usbip_ep_out_fn  cb,
void *  ctx 
)

Register the OUT-data callback for an endpoint.

Without one, OUT data is queued for usbip_device_read().

Parameters
epthe OUT endpoint.
cbthe callback, or NULL to go back to queueing.
ctxpassed back to cb.

◆ usbip_ep_on_iso()

void usbip_ep_on_iso ( usbip_ep ep,
usbip_ep_iso_fn  cb,
void *  ctx 
)

Register the isochronous data callback for an endpoint (either direction).

Without one, iso IN transfers complete with zero-length packets and iso OUT data is dropped (the transfers still complete normally).

Parameters
epthe isochronous endpoint.
cbthe callback, or NULL to remove it.
ctxpassed back to cb.

◆ usbip_device_group_begin()

int usbip_device_group_begin ( usbip_device dev)

Open a new descriptor group: a run of descriptors that form one function of the device (what an IAD groups, and what one Microsoft OS advertisement covers).

Everything appended until the next usbip_device_group_begin() belongs to it. Groups exist for descriptor bookkeeping only - the Microsoft OS emitters fan out one section per group, and the plug-time IAD diagnostic warns per group. A simple device need not create any: it is then treated as one implicit group.

Parameters
devthe device.
Returns
the group id (>= 0), or a negative USB_ERROR code when the group table (8) is full.

◆ usbip_device_group_abort()

void usbip_device_group_abort ( usbip_device dev)

Roll back everything appended since the last usbip_device_group_begin(): descriptors, endpoints, interface registrations, reservations, control/set-alt registrations, and the group's Microsoft OS advertisements.

For unwinding a failed build before the device is plugged; never call it on a served device.

Parameters
devthe device.

◆ usbip_device_enable_msos_group()

int usbip_device_enable_msos_group ( usbip_device dev,
int  group,
const char *  compatible,
const char *  guid 
)

Advertise Microsoft OS descriptors scoped to one descriptor group.

On a composite, Windows loads usbccgp and gives each function its own devnode; a device-wide Compatible ID cannot express "only this function is WinUSB". This form names the group, so Microsoft OS 1.0 emits a section with the right bFirstInterfaceNumber and Microsoft OS 2.0 wraps the feature in a Function Subset. Interface numbers are resolved when the host asks, so it may be called before the group's interfaces exist. Bumps bcdUSB to 0x0210 (BOS present).

Parameters
devthe device.
groupthe group id from usbip_device_group_begin(), or -1 for the whole device (what usbip_device_enable_msos() passes).
compatiblethe Compatible ID string (e.g. "WINUSB", "MTP").
guidDeviceInterfaceGUID to add, or NULL to omit it.
Return values
USB_SUCCESSrecorded.
USB_ERROR_NO_MEMthe advertisement table is full or memory ran out.

◆ usbip_endpoint_address()

uint8_t usbip_endpoint_address ( usbip_ep ep)

An endpoint's bEndpointAddress, as it appears in the descriptor the host reads.

Worth asking for after the fact: the allocator may have moved the endpoint off the address that was requested (see usbip_function_add_endpoint()).

Parameters
epthe endpoint.
Returns
the address (direction bit included), or 0 if ep is NULL.

◆ usbip_device_read()

int usbip_device_read ( usbip_ep ep,
void *  buf,
int  len,
unsigned  timeout_ms 
)

Read host-to-device (OUT) data from an endpoint, blocking up to timeout_ms.

Parameters
epthe OUT endpoint (from usbip_function_endpoint()).
bufbuffer to receive data.
lenbuffer capacity in bytes.
timeout_mstimeout in milliseconds (0 = wait indefinitely).
Returns
bytes read (>= 0), or a negative USB_ERROR code (USB_ERROR_NO_DEVICE if ep is NULL, USB_ERROR_TIMEOUT on timeout).

◆ usbip_device_write()

int usbip_device_write ( usbip_ep ep,
const void *  buf,
int  len,
unsigned  timeout_ms 
)

Write device-to-host (IN) data to an endpoint, blocking up to timeout_ms.

Parameters
epthe IN endpoint (from usbip_function_endpoint()).
bufdata to send.
lennumber of bytes to send.
timeout_mstimeout in milliseconds (0 = wait indefinitely).
Returns
bytes written (>= 0), or a negative USB_ERROR code.

◆ usbip_ep_stall()

void usbip_ep_stall ( usbip_ep ep)

Halt (STALL) a non-control endpoint.

Every URB on it is completed with a STALL until the host issues CLEAR_FEATURE(ENDPOINT_HALT), which the core answers itself. Any IN URB the host already has outstanding is STALLed immediately, so this is how a class says "the data you asked for is not coming" without leaving the host to sit out its own timeout.

Data already queued with usbip_device_write() survives the halt and is delivered once the host clears it. Mass storage relies on that: it halts the bulk-IN endpoint to abandon a failed data phase, then queues the CSW.

Parameters
epthe endpoint (ignored if NULL).

◆ usbip_device_plug()

int usbip_device_plug ( usbip_device dev,
usb_transport transport 
)

Plug the device onto a transport and start serving it.

This side is the USB/IP server: the call starts listening (on TCP 3240 by default) and returns immediately. Nothing enumerates the device until a USB/IP client - the OS importer (usbip attach), or a program on the host API - connects and imports it. Data written before that is queued on its endpoint.

Several devices, one process. Plugging another device onto the same address exports it alongside the first rather than failing to bind: the listener is shared, and each device is named on the wire by its own busid - 1-1, 1-2, ... in plug order, unless usbip_device_set_busid() named it. The importer picks one (usbip attach -b 1-2, or by busid through the host API), and every imported device gets its own connection. This is separate from a composite device (usbip_device_set_composite()), which is one device with several functions.

Parameters
devthe device.
transporttransport from usbip_transport() / usbip_loopback(), or NULL for the local default.
Return values
USB_SUCCESSserving started (e.g. the port is now accepting imports).
Returns
a negative USB_ERROR code otherwise (e.g. the port is busy).

◆ usbip_device_unplug()

void usbip_device_unplug ( usbip_device dev)

Stop serving a device previously passed to usbip_device_plug().

When other devices still share the listener it keeps running for them; the last device unplugged closes it.

Parameters
devthe device.

◆ usbip_device_set_busid()

void usbip_device_set_busid ( usbip_device dev,
const char *  busid 
)

Name this device on the wire, instead of the 1-<n> assigned at plug time.

Only useful when a process exports several devices and the importer needs stable names regardless of plug order. Call before usbip_device_plug().

Parameters
devthe device.
busidthe busid, e.g. "1-4". Truncated to 31 characters.

◆ usbip_device_get_busid()

const char * usbip_device_get_busid ( usbip_device dev)

The busid this device is exported under - what usbip attach -b takes.

Assigned by usbip_device_plug() unless usbip_device_set_busid() set it; reads "1-1" before either.

Parameters
devthe device.
Returns
the busid, owned by the device.

◆ usbip_device_is_composite()

int usbip_device_is_composite ( usbip_device dev)

Whether the app declared this device composite (see usbip_device_set_composite()).

A multi-interface class consults this from its build() to decide whether to emit an IAD grouping its interfaces.

Parameters
devthe device.
Returns
non-zero when composite.