libusb specific implementation details¶
This document details implementation details specific to libusb, used on all platforms with USB interactions.
libusb context management¶
All system resources with libusb are represented using a libusb_context
instance, opened using libusb_init
. Cahute stores this as a context
pointer; see Context pointers for more information.
Note
libusb can provide logs through a callback, using libusb_set_log_cb
.
However, instead of taking a cookie, this callback takes the libusb
context, so matching it to a Cahute context would require a global
mapping.
See #80 for more information.
USB device detection using libusb¶
Cahute can use libusb to detect USB devices, using
cahute_libusb_detect_usb()
.
This function gets the device list using libusb_get_device_list
, then
browses it. If an entry matches one of the entries in
USB detection for CASIO calculators, then it is yielded.
Note
libusb requires opening the device with libusb_open
in order to get
a string descriptor using control flows. Thus, we cannot use
iManufacturer
to distinguish between models.
USB links¶
libusb is used by Cahute to interact with calculators connected as devices to the current machine, assumed to be a host (such as a PC or smartphone with OTG).
USB link opening using libusb¶
Cahute can use libusb to open a device with a given bus number and address,
using cahute_open_libusb_link()
.
This function gets the device list using libusb_get_device_list
, and finds
one matching the provided bus and address numbers using
libusb_get_bus_number
and libusb_get_device_address
on every entry.
If a matching device is found, the configuration is obtained using
libusb_get_device_descriptor
and libusb_get_active_config_descriptor
,
in order to:
Get the vendor (VID) and product (PID) identifiers, to ensure they match one of the known combinations for CASIO calculators.
Get the interface class (
bInterfaceClass
) to determine the protocol and transport.In both cases, ensure that the bulk IN and OUT endpoints exist, and get their endpoint identifiers.
Note
While historical implementations of CASIO’s protocols using libusb hardcode 0x82 as Bulk IN and 0x01 as Bulk OUT, this has proven to change on other platforms such as OS X; see #3 (comment 1823215641) for more context.
The interface class to transport mapping is the following:
(in) Intf. class |
(in) Intf. subclass |
(in) Intf. protocol |
(out) Link type |
---|---|---|---|
8 |
6 |
80 |
UMS |
255 |
0 |
255 |
Serial over bulk |
See USB detection for CASIO calculators for more information.
Once all metadata has been gathered, the function opens the device using
libusb_open
, and attempt to claim its interface using
libusb_claim_interface
and libusb_detach_kernel_driver
.
Note
Access errors, i.e. any of these two functions returning
LIBUSB_ERROR_ACCESS
, are ignored, since libusb is still
able to communicate with the device on some platforms afterwards.
See #3 for more context.
If the device opening yields LIBUSB_ERROR_NOT_SUPPORTED
,
it means that the device is running a driver that is not supported by
libusb. Then, if the platform supports it, we get the port number
using libusb_get_port_number
, and try to open the device through the
system-specific interface.
Note
On Microsoft Windows, the port number is considered to be a device address; see Device opening using a device address for more information.
Serial over bulk USB links using libusb¶
In order to handle serial over bulk USB links using libusb, we have a
libusb_device_handle
. The available operations are the following:
Closing uses
libusb_close
on the device handle, andlibusb_exit
on the libusb context;Receiving and sending uses
libusb_bulk_transfer
.
See Serial transport over USB bulk for more information.
UMS links using libusb¶
In order to handle UMS links using libusb, we have a
libusb_device_handle
. The available operations are the following:
Closing uses
libusb_close
on the device handle, andlibusb_exit
on the libusb context;Requesting using SCSI uses
libusb_bulk_transfer
with manual reading and writing of the Command Block Wrapper (CBW) and Command Status Wrapper (CSW).
See USB Mass Storage (UMS) transport for more information.