-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Communicate with USB devices
--
-- This library enables you to communicate with USB devices from
-- userspace. It is implemented as a high-level wrapper around
-- bindings-libusb
-- (http://hackage.haskell.org/package/bindings-libusb) which is a
-- low-level binding to the C library: libusb-1.*
-- (http://libusb.org/).
--
-- The USB transfer functions in this library have a simple synchronous
-- interface (they block) but are implemented using the libusb
-- asynchronous interface. They integrate with the GHC event manager
-- making them efficient (no busy-loops) and interruptible (throwing an
-- exception to the thread executing a transfer immediately cancels the
-- transfer).
--
-- If the GHC event manager is not available (because you're either not
-- using GHC or because you're on Windows) the library degrades
-- gracefully to the libusb synchronous implementation.
--
-- This documentation assumes knowledge of how to operate USB devices
-- from a software standpoint (descriptors, configurations, interfaces,
-- endpoints, control/bulk/interrupt/isochronous transfers, etc). Full
-- information can be found in the USB 2.0 specification
-- (http://www.usb.org/developers/docs/).
--
-- For an example how to use this library see the usb-example
-- package (https://github.com/basvandijk/usb-example) or the
-- ls-usb package
-- (http://hackage.haskell.org/package/ls-usb).
--
-- Besides this API documentation the following sources might be
-- interesting:
--
--
@package usb
@version 1.3.0.0
-- | This module provides functionality for initializing the usb
-- library.
module System.USB.Initialization
-- | Abstract type representing a USB session.
--
-- The concept of individual sessions allows your program to use multiple
-- threads that can independently use this library without interfering
-- with eachother.
--
-- Sessions are created and initialized by newCtx and are
-- automatically closed when they are garbage collected.
--
-- The only functions that receive a Ctx are
-- hasCapability, setDebug and getDevices.
data Ctx
-- | Create and initialize a new USB context.
--
-- This function may throw USBExceptions.
--
-- Note that the internal libusb event handling can return
-- errors. These errors occur in the thread that is executing the event
-- handling loop. newCtx will print these errors to stderr.
-- If you need to handle the errors yourself (for example log them in an
-- application specific way) please use newCtx'.
newCtx :: IO Ctx
-- | Like newCtx but enables you to specify the way errors should be
-- handled that occur while handling libusb events.
newCtx' :: (USBException -> IO ()) -> IO Ctx
-- | Set message verbosity.
--
-- The default level is PrintNothing. This means no messages are
-- ever printed. If you choose to increase the message verbosity level
-- you must ensure that your application does not close the
-- stdout/stderr file descriptors.
--
-- You are advised to set the debug level to PrintWarnings. Libusb
-- is conservative with its message logging. Most of the time it will
-- only log messages that explain error conditions and other oddities.
-- This will help you debug your software.
--
-- The LIBUSB_DEBUG environment variable overrules the debug level set by
-- this function. The message verbosity is fixed to the value in the
-- environment variable if it is defined.
--
-- If libusb was compiled without any message logging, this
-- function does nothing: you'll never get any messages.
--
-- If libusb was compiled with verbose debug message logging,
-- this function does nothing: you'll always get messages from all
-- levels.
setDebug :: Ctx -> Verbosity -> IO ()
-- | Message verbosity
data Verbosity
-- | No messages are ever printed by the library.
PrintNothing :: Verbosity
-- | Error messages are printed to stderr.
PrintErrors :: Verbosity
-- | Warning and error messages are printed to stderr.
PrintWarnings :: Verbosity
-- | Informational messages are printed to stdout, warning and
-- error messages are printed to stderr.
PrintInfo :: Verbosity
-- | Debug and informational messages are printed to stdout,
-- warnings and errors to stderr.
PrintDebug :: Verbosity
-- | This module provides miscellaneous functionality.
module System.USB.Misc
-- | Capabilities supported by an instance of libusb on the
-- current running platform.
--
-- Test if the loaded libusb library supports a given capability
-- by calling hasCapability.
data Capability
-- | The hasCapability API is available.
HasCapability :: Capability
-- | Hotplug support is available on this platform.
HasHotplug :: Capability
-- | The library can access HID devices without requiring user
-- intervention.
--
-- Note that before being able to actually access an HID device, you may
-- still have to call additional libusb functions such as
-- detachKernelDriver.
HasHidAccess :: Capability
-- | The library supports detaching of the default USB driver, using
-- detachKernelDriver, if one is set by the OS kernel.
SupportsDetachKernelDriver :: Capability
-- | Check at runtime if the loaded libusb library has a given
-- capability.
--
-- This call should be performed after newCtx, to ensure the
-- backend has updated its capability set. For this reason you need to
-- apply it to a Ctx.
hasCapability :: Ctx -> Capability -> Bool
-- | Structure providing the version of the libusb runtime.
data LibusbVersion
LibusbVersion :: Word16 -> Word16 -> Word16 -> Word16 -> String -> LibusbVersion
-- | Library major version.
major :: LibusbVersion -> Word16
-- | Library minor version.
minor :: LibusbVersion -> Word16
-- | Library micro version.
micro :: LibusbVersion -> Word16
-- | Library nano version.
nano :: LibusbVersion -> Word16
-- | Library release candidate suffix string, e.g. "-rc4".
rc :: LibusbVersion -> String
-- | Returns the version (major, minor, micro, nano and rc) of the loaded
-- libusb library.
libusbVersion :: LibusbVersion
-- | Convert a LibusbVersion to a Version for easy
-- comparison.
toVersion :: LibusbVersion -> Version
-- | This module provides functionality for enumerating the USB devices
-- currently attached to the system.
module System.USB.Enumeration
-- | Abstract type representing a USB device detected on the system.
--
-- You can only obtain a USB device from the getDevices function.
--
-- Certain operations can be performed on a device, but in order to do
-- any I/O you will have to first obtain a DeviceHandle using
-- openDevice.
--
-- Just because you have a reference to a device does not mean it is
-- necessarily usable. The device may have been unplugged, you may not
-- have permission to operate such device or another process or driver
-- may be using the device.
--
-- To get additional information about a device you can retrieve its
-- descriptor using getDeviceDesc.
data Device
-- | Returns a vector of USB devices currently attached to the system.
--
-- This is your entry point into finding a USB device.
--
-- Exceptions:
--
--
getDevices :: Ctx -> IO (Vector Device)
-- | The set of hotplug events to trigger the callback in
-- registerHotplugCallback.
data HotplugEvent
-- | A device has been plugged in and is ready to use.
deviceArrived :: HotplugEvent
-- | A device has left and is no longer available.
--
-- It is the user's responsibility to call closeDevice on any
-- handle associated with a disconnected device. It is safe to call
-- getDeviceDesc on a device that has left.
deviceLeft :: HotplugEvent
-- | Determine if the set of events contains a deviceArrived event.
matchDeviceArrived :: HotplugEvent -> Bool
-- | Determine if the set of events contains a deviceLeft event.
matchDeviceLeft :: HotplugEvent -> Bool
-- | Set of configuration flags for registerHotplugCallback.
data HotplugFlag
-- | Fire events for all matching currently attached devices.
enumerate :: HotplugFlag
-- | Hotplug callback function type.
--
-- libusb will call this function later, when a matching event
-- had happened on a matching device.
--
-- This callback may be called by an internal event thread and as such it
-- is recommended the callback do minimal processing before returning. In
-- fact, it has been observed that doing any I/O with the device from
-- inside the callback results in dead-lock! See the example below on the
-- correct use of this callback.
--
-- It is safe to call either registerHotplugCallback or
-- deregisterHotplugCallback from within a callback function.
--
-- Should return a CallbackRegistrationStatus which indicates
-- whether this callback is finished processing events. Returning
-- DeregisterThisCallback will cause this callback to be
-- deregistered.
--
-- If you need to wait on the arrival of a device after which you need to
-- do something with it, it's recommended to write the device to a
-- concurrent channel like a MVar / TChan / TMVar / TChan / etc. then
-- read the channel outside the callback. This way the processing of the
-- device takes place in a different thread. See the following for one
-- correct use-case:
--
--
-- waitForMyDevice :: Ctx
-- -> Maybe VendorId
-- -> Maybe ProductId
-- -> Maybe Word8
-- -> IO Device
-- waitForMyDevice ctx mbVendorId mbProductId mbDevClass = do
-- mv <- newEmptyMVar
-- -- We mask asynchronous exceptions to ensure that the callback
-- -- gets properly deregistered when an asynchronous exception is
-- -- thrown during the interruptible takeMVar operation.
-- mask_ $ do
-- h <- registerHotplugCallback ctx
-- deviceArrived
-- enumerate
-- mbVendorId
-- mbProductId
-- mbDevClass
-- (dev event ->
-- tryPutMVar mv (dev, event) $>
-- DeregisterThisCallback)
-- (dev, _event) <- takeMVar mv
-- `onException`
-- deregisterHotplugCallback h
-- return dev
--
type HotplugCallback = Device -> HotplugEvent -> IO CallbackRegistrationStatus
-- | Returned from a HotplugCallback to indicate whether the
-- callback is finished processing events.
data CallbackRegistrationStatus
-- | The callback remains registered.
KeepCallbackRegistered :: CallbackRegistrationStatus
-- | The callback will be deregistered.
DeregisterThisCallback :: CallbackRegistrationStatus
-- | Callback handle.
--
-- Callbacks handles are generated by registerHotplugCallback and
-- can be used to deregister callbacks. Callback handles are unique per
-- Ctx and it is safe to call deregisterHotplugCallback on
-- an already deregisted callback.
data HotplugCallbackHandle
-- | WARNING: see the note on HotplugCallback for the danger
-- of using this function!
--
-- Register a hotplug callback function with the context. The callback
-- will fire when a matching event occurs on a matching device. The
-- callback is armed until either it is deregistered with
-- deregisterHotplugCallback or the supplied callback returns
-- True to indicate it is finished processing events.
--
-- If the enumerate flag is passed the callback will be called
-- with a deviceArrived for all devices already plugged into the
-- machine. Note that libusb modifies its internal device list
-- from a separate thread, while calling hotplug callbacks from
-- libusb_handle_events(), so it is possible for a device to
-- already be present on, or removed from, its internal device list,
-- while the hotplug callbacks still need to be dispatched. This means
-- that when using the enumerate flag, your callback may be called
-- twice for the arrival of the same device, once from
-- registerHotplugCallback and once from
-- libusb_handle_events(); and/or your callback may be called
-- for the removal of a device for which an arrived call was never made.
registerHotplugCallback :: Ctx -> HotplugEvent -> HotplugFlag -> Maybe VendorId -> Maybe ProductId -> Maybe Word8 -> HotplugCallback -> IO HotplugCallbackHandle
-- | Deregisters a hotplug callback.
--
-- Deregister a callback from a Ctx. This function is safe to call
-- from within a hotplug callback.
deregisterHotplugCallback :: HotplugCallbackHandle -> IO ()
-- | The number of the bus that a device is connected to.
busNumber :: Device -> Word8
-- | Get the number of the port that a is device connected to. Unless the
-- OS does something funky, or you are hot-plugging USB extension cards,
-- the port number returned by this call is usually guaranteed to be
-- uniquely tied to a physical port, meaning that different devices
-- plugged on the same physical port should return the same port number.
--
-- But outside of this, there is no guarantee that the port number
-- returned by this call will remain the same, or even match the order in
-- which ports have been numbered by the HUB/HCD manufacturer.
portNumber :: Device -> Word8
-- | Get the list of all port numbers from root for the specified device.
portNumbers :: Device -> Int -> Maybe (Vector Word8)
-- | The address of the device on the bus it is connected to.
deviceAddress :: Device -> Word8
-- | Get the negotiated connection speed for a device.
--
-- Nothing means that the OS doesn't know or doesn't support
-- returning the negotiated speed.
deviceSpeed :: Device -> Maybe Speed
-- | Speed codes. Indicates the speed at which the device is operating.
data Speed
-- | The device is operating at low speed (1.5MBit/s).
LowSpeed :: Speed
-- | The device is operating at full speed (12MBit/s).
FullSpeed :: Speed
-- | The device is operating at high speed (480MBit/s).
HighSpeed :: Speed
-- | The device is operating at super speed (5000MBit/s).
SuperSpeed :: Speed
-- | The module provides functionality for opening, closing and configuring
-- USB devices.
module System.USB.DeviceHandling
-- | Abstract type representing a handle of a USB device.
--
-- You can acquire a handle from openDevice.
--
-- A device handle is used to perform I/O and other operations. When
-- finished with a device handle you should close it by applying
-- closeDevice to it.
data DeviceHandle
-- | Open a device and obtain a device handle.
--
-- A handle allows you to perform I/O on the device in question.
--
-- This is a non-blocking function; no requests are sent over the bus.
--
-- It is advisable to use withDeviceHandle because it
-- automatically closes the device when the computation terminates.
--
-- Exceptions:
--
--
openDevice :: Device -> IO DeviceHandle
-- | Close a device handle.
--
-- Should be called on all open handles before your application exits.
--
-- This is a non-blocking function; no requests are sent over the bus.
closeDevice :: DeviceHandle -> IO ()
-- | withDeviceHandle dev act opens the Device dev
-- and passes the resulting handle to the computation act. The
-- handle will be closed on exit from withDeviceHandle whether
-- by normal termination or by raising an exception.
withDeviceHandle :: Device -> (DeviceHandle -> IO a) -> IO a
-- | Retrieve the Device from the DeviceHandle.
getDevice :: DeviceHandle -> Device
-- | Identifier for configurations.
--
-- Can be retrieved by getConfig or by configValue.
type ConfigValue = Word8
-- | Determine the value of the currently active configuration.
--
-- You could formulate your own control request to obtain this
-- information, but this function has the advantage that it may be able
-- to retrieve the information from operating system caches (no I/O
-- involved).
--
-- If the OS does not cache this information, then this function will
-- block while a control transfer is submitted to retrieve the
-- information.
--
-- This function returns Nothing if the device is in unconfigured
-- state.
--
-- Exceptions:
--
--
getConfig :: DeviceHandle -> IO (Maybe ConfigValue)
-- | Set the active configuration for a device.
--
-- The operating system may or may not have already set an active
-- configuration on the device. It is up to your application to ensure
-- the correct configuration is selected before you attempt to claim
-- interfaces and perform other operations.
--
-- If you call this function on a device already configured with the
-- selected configuration, then this function will act as a lightweight
-- device reset: it will issue a SET_CONFIGURATION request using the
-- current configuration, causing most USB-related device state to be
-- reset (altsetting reset to zero, endpoint halts cleared, toggles
-- reset).
--
-- You cannot change/reset configuration if your application has claimed
-- interfaces - you should free them with releaseInterface first.
-- You cannot change/reset configuration if other applications or drivers
-- have claimed interfaces.
--
-- A configuration value of Nothing will put the device in an
-- unconfigured state. The USB specification states that a configuration
-- value of 0 does this, however buggy devices exist which actually have
-- a configuration 0.
--
-- You should always use this function rather than formulating your own
-- SET_CONFIGURATION control request. This is because the underlying
-- operating system needs to know when such changes happen.
--
-- This is a blocking function.
--
-- Exceptions:
--
--
setConfig :: DeviceHandle -> Maybe ConfigValue -> IO ()
-- | Identifier for interfaces.
--
-- Can be retrieved by interfaceNumber.
type InterfaceNumber = Word8
-- | Claim an interface on a given device handle.
--
-- You must claim the interface you wish to use before you can perform
-- I/O on any of its endpoints.
--
-- It is legal to attempt to claim an already-claimed interface, in which
-- case this function just returns without doing anything.
--
-- Claiming of interfaces is a purely logical operation; it does not
-- cause any requests to be sent over the bus. Interface claiming is used
-- to instruct the underlying operating system that your application
-- wishes to take ownership of the interface.
--
-- This is a non-blocking function.
--
-- Exceptions:
--
--
claimInterface :: DeviceHandle -> InterfaceNumber -> IO ()
-- | Release an interface previously claimed with claimInterface.
--
-- You should release all claimed interfaces before closing a device
-- handle.
--
-- This is a blocking function. A SET_INTERFACE control request will be
-- sent to the device, resetting interface state to the first alternate
-- setting.
--
-- Exceptions:
--
--
releaseInterface :: DeviceHandle -> InterfaceNumber -> IO ()
-- | withClaimedInterface claims the interface on the given device
-- handle then executes the given computation. On exit from
-- withClaimedInterface, the interface is released whether by
-- normal termination or by raising an exception.
withClaimedInterface :: DeviceHandle -> InterfaceNumber -> IO a -> IO a
-- | Identifier for interface alternate settings.
--
-- Can be retrieved by interfaceAltSetting.
type InterfaceAltSetting = Word8
-- | Activate an alternate setting for an interface.
--
-- The interface must have been previously claimed with
-- claimInterface.
--
-- You should always use this function rather than formulating your own
-- SET_INTERFACE control request. This is because the underlying
-- operating system needs to know when such changes happen.
--
-- This is a blocking function.
--
-- Exceptions:
--
--
setInterfaceAltSetting :: DeviceHandle -> InterfaceNumber -> InterfaceAltSetting -> IO ()
-- | Clear the halt/stall condition for an endpoint.
--
-- Endpoints with halt status are unable to receive or transmit data
-- until the halt condition is stalled.
--
-- You should cancel all pending transfers before attempting to clear the
-- halt condition.
--
-- This is a blocking function.
--
-- Exceptions:
--
--
clearHalt :: DeviceHandle -> EndpointAddress -> IO ()
-- | Perform a USB port reset to reinitialize a device.
--
-- The system will attempt to restore the previous configuration and
-- alternate settings after the reset has completed.
--
-- If the reset fails, the descriptors change, or the previous state
-- cannot be restored, the device will appear to be disconnected and
-- reconnected. This means that the device handle is no longer valid (you
-- should close it) and rediscover the device. A NotFoundException
-- is raised to indicate that this is the case.
--
-- This is a blocking function which usually incurs a noticeable delay.
--
-- Exceptions:
--
--
resetDevice :: DeviceHandle -> IO ()
-- | Enable/disable libusb's automatic kernel driver detachment.
-- When this is enabled libusb will automatically detach the
-- kernel driver on an interface when claiming the interface, and attach
-- it when releasing the interface.
--
-- Automatic kernel driver detachment is disabled on newly opened device
-- handles by default.
--
-- On platforms which do not have the SupportsDetachKernelDriver
-- capability this function will throw a NotSupportedException,
-- and libusb will continue as if this function was never
-- called.
setAutoDetachKernelDriver :: DeviceHandle -> Bool -> IO ()
-- | Determine if a kernel driver is active on an interface.
--
-- If a kernel driver is active, you cannot claim the interface, and
-- libusb will be unable to perform I/O.
--
-- Exceptions:
--
--
kernelDriverActive :: DeviceHandle -> InterfaceNumber -> IO Bool
-- | Detach a kernel driver from an interface.
--
-- If successful, you will then be able to claim the interface and
-- perform I/O.
--
-- Exceptions:
--
--
detachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()
-- | Re-attach an interface's kernel driver, which was previously detached
-- using detachKernelDriver.
--
-- Exceptions:
--
--
attachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()
-- | If a kernel driver is active on the specified interface the driver is
-- detached and the given action is executed. If the action terminates,
-- whether by normal termination or by raising an exception, the kernel
-- driver is attached again. If a kernel driver is not active on the
-- specified interface the action is just executed.
--
-- Exceptions:
--
--
withDetachedKernelDriver :: DeviceHandle -> InterfaceNumber -> IO a -> IO a
-- | USB devices report their attributes using descriptors. A descriptor is
-- a data structure with a defined format. Using descriptors allows
-- concise storage of the attributes of individual configurations because
-- each configuration may reuse descriptors or portions of descriptors
-- from other configurations that have the same characteristics. In this
-- manner, the descriptors resemble individual data records in a
-- relational database.
--
-- Where appropriate, descriptors contain references to string
-- descriptors (StrIx) that provide textual information describing
-- a descriptor in human-readable form. Note that the inclusion of string
-- descriptors is optional.
module System.USB.Descriptors
-- | Get the USB device descriptor for a given device.
--
-- This is a non-blocking function; the device descriptor is cached in
-- memory.
--
-- This function may throw USBExceptions.
getDeviceDesc :: Device -> IO DeviceDesc
-- | A structure representing the standard USB device descriptor.
--
-- This descriptor is documented in section 9.6.1 of the USB 2.0
-- specification.
--
-- This structure can be retrieved by getDeviceDesc.
data DeviceDesc
DeviceDesc :: !ReleaseNumber -> !Word8 -> !Word8 -> !Word8 -> !Word8 -> !VendorId -> !ProductId -> !ReleaseNumber -> !(Maybe StrIx) -> !(Maybe StrIx) -> !(Maybe StrIx) -> !Word8 -> DeviceDesc
-- | USB specification release number.
deviceUSBSpecReleaseNumber :: DeviceDesc -> !ReleaseNumber
-- | USB-IF class code for the device.
deviceClass :: DeviceDesc -> !Word8
-- | USB-IF subclass code for the device, qualified by the
-- deviceClass value.
deviceSubClass :: DeviceDesc -> !Word8
-- | USB-IF protocol code for the device, qualified by the
-- deviceClass and deviceSubClass values.
deviceProtocol :: DeviceDesc -> !Word8
-- | Maximum packet size for endpoint 0.
deviceMaxPacketSize0 :: DeviceDesc -> !Word8
-- | USB-IF vendor ID.
deviceVendorId :: DeviceDesc -> !VendorId
-- | USB-IF product ID.
deviceProductId :: DeviceDesc -> !ProductId
-- | Device release number.
deviceReleaseNumber :: DeviceDesc -> !ReleaseNumber
-- | Optional index of string descriptor describing manufacturer.
deviceManufacturerStrIx :: DeviceDesc -> !(Maybe StrIx)
-- | Optional index of string descriptor describing product.
deviceProductStrIx :: DeviceDesc -> !(Maybe StrIx)
-- | Optional index of string descriptor containing device serial number.
deviceSerialNumberStrIx :: DeviceDesc -> !(Maybe StrIx)
-- | Number of possible configurations.
deviceNumConfigs :: DeviceDesc -> !Word8
-- | Release / version number of the USB specification / device.
type ReleaseNumber = (Int, Int, Int, Int)
-- | A 16-bit number used to identify a USB device. Each vendor ID is
-- assigned by the USB Implementers Forum to a specific company.
type VendorId = Word16
-- | A 16-bit number used to identify a USB device. Each company which is
-- assigned a VendorId can assign a product ID to its USB-based
-- products.
type ProductId = Word16
-- | Get a USB configuration descriptor based on its index.
--
-- This is a non-blocking function which does not involve any requests
-- being sent to the device.
--
-- Exceptions:
--
--
getConfigDesc :: Device -> Word8 -> IO ConfigDesc
-- | A structure representing the standard USB configuration descriptor.
--
-- This descriptor is documented in section 9.6.3 of the USB 2.0
-- specification.
--
-- This structure can be retrieved by getConfigDesc.
data ConfigDesc
ConfigDesc :: !ConfigValue -> !(Maybe StrIx) -> !ConfigAttribs -> !Word8 -> !(Vector Interface) -> !ByteString -> ConfigDesc
-- | Identifier value for the configuration.
configValue :: ConfigDesc -> !ConfigValue
-- | Optional index of string descriptor describing the configuration.
configStrIx :: ConfigDesc -> !(Maybe StrIx)
-- | Configuration characteristics.
configAttribs :: ConfigDesc -> !ConfigAttribs
-- | Maximum power consumption of the USB device from the bus in the
-- configuration when the device is fully operational. Expressed in 2 mA
-- units (i.e., 50 = 100 mA).
configMaxPower :: ConfigDesc -> !Word8
-- | Vector of interfaces supported by the configuration.
configInterfaces :: ConfigDesc -> !(Vector Interface)
-- | Extra descriptors. If libusb encounters unknown configuration
-- descriptors, it will store them here, should you wish to parse them.
configExtra :: ConfigDesc -> !ByteString
-- | The USB 2.0 specification specifies that the configuration attributes
-- only describe the device status.
type ConfigAttribs = DeviceStatus
-- | The status of a USB device.
data DeviceStatus
DeviceStatus :: !Bool -> !Bool -> DeviceStatus
-- | The Remote Wakeup field indicates whether the device is currently
-- enabled to request remote wakeup. The default mode for devices that
-- support remote wakeup is disabled.
remoteWakeup :: DeviceStatus -> !Bool
-- | The Self Powered field indicates whether the device is currently
-- self-powered
selfPowered :: DeviceStatus -> !Bool
-- | An interface is represented as a vector of alternate interface
-- settings.
type Interface = Vector InterfaceDesc
-- | A structure representing the standard USB interface descriptor.
--
-- This descriptor is documented in section 9.6.5 of the USB 2.0
-- specification.
--
-- This structure can be retrieved using configInterfaces.
data InterfaceDesc
InterfaceDesc :: !InterfaceNumber -> !InterfaceAltSetting -> !Word8 -> !Word8 -> !Word8 -> !(Maybe StrIx) -> !(Vector EndpointDesc) -> !ByteString -> InterfaceDesc
-- | Number of the interface.
interfaceNumber :: InterfaceDesc -> !InterfaceNumber
-- | Value used to select the alternate setting for the interface.
interfaceAltSetting :: InterfaceDesc -> !InterfaceAltSetting
-- | USB-IF class code for the interface.
interfaceClass :: InterfaceDesc -> !Word8
-- | USB-IF subclass code for the interface, qualified by the
-- interfaceClass value.
interfaceSubClass :: InterfaceDesc -> !Word8
-- | USB-IF protocol code for the interface, qualified by the
-- interfaceClass and interfaceSubClass values.
interfaceProtocol :: InterfaceDesc -> !Word8
-- | Optional index of string descriptor describing the interface.
interfaceStrIx :: InterfaceDesc -> !(Maybe StrIx)
-- | Vector of endpoints supported by the interface.
interfaceEndpoints :: InterfaceDesc -> !(Vector EndpointDesc)
-- | Extra descriptors. If libusb encounters unknown interface
-- descriptors, it will store them here, should you wish to parse them.
interfaceExtra :: InterfaceDesc -> !ByteString
-- | A structure representing the standard USB endpoint descriptor.
--
-- This descriptor is documented in section 9.6.3 of the USB 2.0
-- specification.
--
-- This structure can be retrieved by using interfaceEndpoints.
data EndpointDesc
EndpointDesc :: !EndpointAddress -> !EndpointAttribs -> !MaxPacketSize -> !Word8 -> !Word8 -> !Word8 -> !ByteString -> EndpointDesc
-- | The address of the endpoint described by the descriptor.
endpointAddress :: EndpointDesc -> !EndpointAddress
-- | Attributes which apply to the endpoint when it is configured using the
-- configValue.
endpointAttribs :: EndpointDesc -> !EndpointAttribs
-- | Maximum packet size the endpoint is capable of sending/receiving.
endpointMaxPacketSize :: EndpointDesc -> !MaxPacketSize
-- | Interval for polling endpoint for data transfers. Expressed in frames
-- or microframes depending on the device operating speed (i.e., either 1
-- millisecond or 125 μs units).
endpointInterval :: EndpointDesc -> !Word8
-- | For audio devices only: the rate at which synchronization
-- feedback is provided.
endpointRefresh :: EndpointDesc -> !Word8
-- | For audio devices only: the address of the synch endpoint.
endpointSynchAddress :: EndpointDesc -> !Word8
-- | Extra descriptors. If libusb encounters unknown endpoint
-- descriptors, it will store them here, should you wish to parse them.
endpointExtra :: EndpointDesc -> !ByteString
-- | The address of an endpoint.
data EndpointAddress
EndpointAddress :: !Int -> !TransferDirection -> EndpointAddress
-- | Must be >= 0 and <= 15
endpointNumber :: EndpointAddress -> !Int
-- | The direction of data transfer relative to the host of this endpoint.
transferDirection :: EndpointAddress -> !TransferDirection
-- | The direction of data transfer relative to the host.
data TransferDirection
-- | Out transfer direction (host -> device) used for writing.
Out :: TransferDirection
-- | In transfer direction (device -> host) used for reading.
In :: TransferDirection
-- | The USB 2.0 specification specifies that the endpoint attributes only
-- describe the endpoint transfer type.
type EndpointAttribs = TransferType
-- | Describes what types of transfers are allowed on the endpoint.
data TransferType
-- | Control transfers are typically used for command and status
-- operations.
Control :: TransferType
-- | Isochronous transfers occur continuously and periodically.
Isochronous :: !Synchronization -> !Usage -> TransferType
-- | Bulk transfers can be used for large bursty data.
Bulk :: TransferType
-- | Interrupt transfers are typically non-periodic, small device
-- "initiated" communication requiring bounded latency.
Interrupt :: TransferType
-- | See section 5.12.4.1 of the USB 2.0 specification.
data Synchronization
-- | No Synchonisation.
NoSynchronization :: Synchronization
-- | Unsynchronized, although sinks provide data rate feedback.
Asynchronous :: Synchronization
-- | Synchronized using feedback or feedforward data rate information
Adaptive :: Synchronization
-- | Synchronized to the USB’s SOF (Start Of Frame)
Synchronous :: Synchronization
-- | See section 5.12.4.2 of the USB 2.0 specification.
data Usage
Data :: Usage
Feedback :: Usage
Implicit :: Usage
-- | Maximum packet size.
data MaxPacketSize
MaxPacketSize :: !Size -> !TransactionOpportunities -> MaxPacketSize
maxPacketSize :: MaxPacketSize -> !Size
transactionOpportunities :: MaxPacketSize -> !TransactionOpportunities
-- | Number of additional transaction oppurtunities per microframe.
--
-- See table 9-13 of the USB 2.0 specification.
data TransactionOpportunities
-- | None (1 transaction per microframe)
Zero :: TransactionOpportunities
-- | 1 additional (2 per microframe)
One :: TransactionOpportunities
-- | 2 additional (3 per microframe)
Two :: TransactionOpportunities
-- | Calculate the maximum packet size which a specific endpoint is capable
-- of sending or receiving in the duration of 1 microframe.
--
-- If acting on an Isochronous or Interrupt endpoint, this
-- function will multiply the maxPacketSize by the additional
-- transactionOpportunities. If acting on another type of endpoint
-- only the maxPacketSize is returned.
--
-- This function is mainly useful for setting up isochronous
-- transfers.
maxIsoPacketSize :: EndpointDesc -> Size
-- | Retrieve a vector of supported languages.
--
-- This function may throw USBExceptions.
getLanguages :: DeviceHandle -> IO (Vector LangId)
-- | The language ID consists of the primary language identifier and the
-- sublanguage identififier as described in:
--
-- http://www.usb.org/developers/docs/USB_LANGIDs.pdf
--
-- For a mapping between IDs and languages see the usb-id-database
-- package.
--
-- To see which LangIds are supported by a device see
-- getLanguages.
type LangId = (PrimaryLangId, SubLangId)
-- | The primary language identifier.
type PrimaryLangId = Word16
-- | The sublanguage identifier.
type SubLangId = Word16
-- | Type of indici of string descriptors.
--
-- Can be retrieved by all the *StrIx functions.
type StrIx = Word8
-- | Retrieve a string descriptor from a device.
--
-- This function may throw USBExceptions.
getStrDesc :: DeviceHandle -> StrIx -> LangId -> Int -> IO Text
-- | Retrieve a string descriptor from a device using the first supported
-- language.
--
-- This function may throw USBExceptions.
getStrDescFirstLang :: DeviceHandle -> StrIx -> Int -> IO Text
-- | This module provides functions for performing control,
-- bulk and interrupt transfers.
--
-- When your system supports the GHC EventManager this module
-- additionally exports functions for performing isochronous
-- transfers. These are currently not available on Windows.
--
-- WARNING: You need to enable the threaded runtime
-- (-threaded) when using the isochronous functions. They throw
-- a runtime error otherwise!
module System.USB.IO
-- | Handy type synonym for read transfers.
--
-- A ReadAction is a function which takes a Size which
-- defines how many bytes to read and a Timeout. The function
-- returns an IO action which, when executed, performs the actual
-- read and returns the ByteString that was read paired with a
-- Status flag which indicates whether the transfer
-- Completed or TimedOut.
type ReadAction = Size -> Timeout -> IO (ByteString, Status)
-- | Handy type synonym for read transfers that must exactly read the
-- specified number of bytes. An incompleteReadException is thrown
-- otherwise.
type ReadExactAction = Size -> Timeout -> IO ByteString
-- | Handy type synonym for write transfers.
--
-- A WriteAction is a function which takes a ByteString
-- to write and a Timeout. The function returns an IO
-- action which, when exectued, returns the number of bytes that were
-- actually written paired with a Status flag which indicates
-- whether the transfer Completed or TimedOut.
type WriteAction = ByteString -> Timeout -> IO (Size, Status)
-- | Handy type synonym for write transfers that must exactly write all the
-- given bytes. An incompleteWriteException is thrown otherwise.
type WriteExactAction = ByteString -> Timeout -> IO ()
-- | Number of bytes transferred.
type Size = Int
-- | A timeout in milliseconds. A timeout defines how long a transfer
-- should wait before giving up due to no response being received. Use
-- noTimeout for no timeout.
type Timeout = Int
-- | A timeout of 0 denotes no timeout so: noTimeout = 0.
noTimeout :: Timeout
-- | Status of a terminated transfer.
data Status
-- | All bytes were transferred within the maximum allowed Timeout
-- period.
Completed :: Status
-- | Not all bytes were transferred within the maximum allowed
-- Timeout period.
TimedOut :: Status
-- | Setup for control transfers.
data ControlSetup
ControlSetup :: !RequestType -> !Recipient -> !Request -> !Value -> !Index -> ControlSetup
-- | The type of request.
controlSetupRequestType :: ControlSetup -> !RequestType
-- | The recipient of the request.
controlSetupRecipient :: ControlSetup -> !Recipient
-- | The numeric request.
controlSetupRequest :: ControlSetup -> !Request
-- | The value.
controlSetupValue :: ControlSetup -> !Value
-- | The index.
controlSetupIndex :: ControlSetup -> !Index
-- | The type of control requests.
data RequestType
-- | Standard requests are common to all USB device's.
Standard :: RequestType
-- | Class requests are common to classes of drivers. For example, all
-- device's conforming to the HID class will have a common set of class
-- specific requests. These will differ to a device conforming to the
-- communications class and differ again to that of a device conforming
-- to the mass storage class.
Class :: RequestType
-- | These are requests which the USB device designer (you?) can assign.
-- These are normally different from device to device, but this is all up
-- to your implementation and imagination.
Vendor :: RequestType
-- | A common request can be directed to different recipients and based on
-- the recipient perform different functions. A GetStatus
-- Standard request for example, can be directed at the device,
-- interface or endpoint. When directed to a device it returns flags
-- indicating the status of remote wakeup and if the device is self
-- powered. However if the same request is directed at the interface it
-- always returns zero, or should it be directed at an endpoint will
-- return the halt flag for the endpoint.
data Recipient
-- | Directed to the device.
ToDevice :: Recipient
-- | Directed to the interface.
ToInterface :: Recipient
-- | Directed to the endpoint.
ToEndpoint :: Recipient
-- | Directed to something other than the device, interface or endpoint.
ToOther :: Recipient
-- | The actual request code.
type Request = Word8
-- | A potential additional parameter for the request.
--
-- (Host-endian)
type Value = Word16
-- | A potential additional parameter for the request. Usually used as an
-- index or offset.
--
-- (Host-endian)
type Index = Word16
-- | Perform a USB control request that does not transfer data.
--
-- Exceptions:
--
--
control :: DeviceHandle -> ControlSetup -> Timeout -> IO ()
-- | Perform a USB control read.
--
-- Exceptions:
--
--
readControl :: DeviceHandle -> ControlSetup -> ReadAction
-- | A convenience function similar to readControl which checks if
-- the specified number of bytes to read were actually read. Throws an
-- incompleteReadException if this is not the case.
readControlExact :: DeviceHandle -> ControlSetup -> ReadExactAction
-- | Perform a USB control write.
--
-- Exceptions:
--
--
writeControl :: DeviceHandle -> ControlSetup -> WriteAction
-- | A convenience function similar to writeControl which checks if
-- the given bytes were actually fully written. Throws an
-- incompleteWriteException if this is not the case.
writeControlExact :: DeviceHandle -> ControlSetup -> WriteExactAction
-- | Perform a USB bulk read.
--
-- Exceptions:
--
--
readBulk :: DeviceHandle -> EndpointAddress -> ReadAction
-- | Perform a USB bulk write.
--
-- Exceptions:
--
--
writeBulk :: DeviceHandle -> EndpointAddress -> WriteAction
-- | Perform a USB interrupt read.
--
-- Exceptions:
--
--
readInterrupt :: DeviceHandle -> EndpointAddress -> ReadAction
-- | Perform a USB interrupt write.
--
-- Exceptions:
--
--
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
-- | Perform a USB isochronous read.
--
-- WARNING: You need to enable the threaded runtime
-- (-threaded) for this function to work correctly. It throws a
-- runtime error otherwise!
--
-- Exceptions:
--
--
readIsochronous :: DeviceHandle -> EndpointAddress -> Vector Size -> Timeout -> IO (Vector ByteString)
-- | Perform a USB isochronous write.
--
-- WARNING: You need to enable the threaded runtime
-- (-threaded) for this function to work correctly. It throws a
-- runtime error otherwise!
--
-- Exceptions:
--
--
writeIsochronous :: DeviceHandle -> EndpointAddress -> Vector ByteString -> Timeout -> IO (Vector Size)
-- | WARNING: This module is experimental and untested. The API will
-- likely change in future releases.
--
-- WARNING: This module is only available on systems which support
-- the GHC EventManager.
--
-- WARNING: You need to enable the threaded runtime
-- (-threaded) when using this module. The functions throw a
-- runtime error otherwise!
--
-- This modules provides alternative I/O operations than the ones in
-- System.USB.IO. The difference is that this module separates the
-- construction from the execution of a USB transfer. This has the
-- advantage that a transfer can be constructed once and executed
-- multiple times thereby saving repeated allocation costs.
module System.USB.IO.Transfers
-- | A control transfer which doesn't transfer data.
data ControlTransfer
-- | Create a new control transfer which doesn't transfer data.
newControlTransfer :: DeviceHandle -> ControlSetup -> Timeout -> IO ControlTransfer
-- | Execute a control transfer which doesn't transfer data.
performControlTransfer :: ControlTransfer -> IO ()
-- | Update the device handle of a control transfer.
setControlTransferDeviceHandle :: ControlTransfer -> DeviceHandle -> IO ()
-- | Update the timeout of a control transfer.
setControlTransferTimeout :: ControlTransfer -> Timeout -> IO ()
-- | Update the setup parameters of a control transfer.
setControlSetup :: ControlTransfer -> ControlSetup -> IO ()
-- | Retrieve the device handle of a control transfer.
getControlTransferDeviceHandle :: ControlTransfer -> IO DeviceHandle
-- | Retrieve the timeout of a control transfer.
getControlTransferTimeout :: ControlTransfer -> IO Timeout
-- | A control transfer which reads data from a device.
data ControlReadTransfer
-- | Create a new control transfer which can read data from a device.
newControlReadTransfer :: DeviceHandle -> ControlSetup -> Size -> Timeout -> IO ControlReadTransfer
-- | Execute a control transfer to read data from the device.
performControlReadTransfer :: ControlReadTransfer -> IO (ByteString, Status)
-- | Update the device handle of a control transfer that reads data from a
-- device.
setControlReadTransferDeviceHandle :: ControlReadTransfer -> DeviceHandle -> IO ()
-- | Update the timeout of a control transfer that reads data from a
-- device.
setControlReadTransferTimeout :: ControlReadTransfer -> Timeout -> IO ()
-- | Update the setup parameters of a control transfer that reads data from
-- a device..
setControlReadSetup :: ControlReadTransfer -> ControlSetup -> Size -> IO ()
-- | Retrieve the device handle of a control transfer that reads data from
-- a device.
getControlReadTransferDeviceHandle :: ControlReadTransfer -> IO DeviceHandle
-- | Retrieve the timeout of a control transfer that reads data from a
-- device.
getControlReadTransferTimeout :: ControlReadTransfer -> IO Timeout
-- | A control transfer which writes data to a device.
data ControlWriteTransfer
-- | Create a new control transfer which can write data to a device.
newControlWriteTransfer :: DeviceHandle -> ControlSetup -> ByteString -> Timeout -> IO ControlWriteTransfer
-- | Execute a control transfer to write the data to the device.
performControlWriteTransfer :: ControlWriteTransfer -> IO (Size, Status)
-- | Update the device handle of a control transfer that writes data to a
-- device.
setControlWriteTransferDeviceHandle :: ControlWriteTransfer -> DeviceHandle -> IO ()
-- | Update the timeout of a control transfer that writes data to a device.
setControlWriteTransferTimeout :: ControlWriteTransfer -> Timeout -> IO ()
-- | Update the setup parameters of a control transfer that writes data to
-- a device.
setControlWriteSetup :: ControlWriteTransfer -> ControlSetup -> ByteString -> IO ()
-- | Retrieve the device handle of a control transfer that writes data to a
-- device.
getControlWriteTransferDeviceHandle :: ControlWriteTransfer -> IO DeviceHandle
-- | Retrieve the timeout of a control transfer that writes data to a
-- device.
getControlWriteTransferTimeout :: ControlWriteTransfer -> IO Timeout
-- | Type of ReadTransfer or WriteTransfer which can either
-- be bulk or interrupt.
--
-- Note that isochronous transfers are handled differently using the
-- IsochronousReadTransfer or IsochronousWriteTransfer
-- types.
data RepeatableTransferType
BulkTransfer :: RepeatableTransferType
InterruptTransfer :: RepeatableTransferType
-- | A bulk or interrupt read transfer.
data ReadTransfer
-- | Create a new bulk or interrupt transfer that can read data from a
-- device.
newReadTransfer :: RepeatableTransferType -> DeviceHandle -> EndpointAddress -> Size -> Timeout -> IO ReadTransfer
-- | Execute a bulk or interrupt transfer to read data from a device.
performReadTransfer :: ReadTransfer -> IO (ByteString, Status)
-- | Specify whether the transfer should perform bulk or interrupt reads.
setReadTransferType :: ReadTransfer -> RepeatableTransferType -> IO ()
-- | Update the device handle of a bulk or interrupt read transfer.
setReadTransferDeviceHandle :: ReadTransfer -> DeviceHandle -> IO ()
-- | Update the endpoint address of a bulk or interrupt read transfer.
setReadTransferEndpointAddress :: ReadTransfer -> EndpointAddress -> IO ()
-- | Update the timeout of a bulk or interrupt read transfer.
setReadTransferTimeout :: ReadTransfer -> Timeout -> IO ()
-- | Update the number of bytes to read for a bulk or interrupt transfer.
setReadTransferSize :: ReadTransfer -> Size -> IO ()
-- | Check if this transfer does bulk or interrupt reads.
getReadTransferType :: ReadTransfer -> IO RepeatableTransferType
-- | Retrieve the device handle of a bulk or interrupt read transfer.
getReadTransferDeviceHandle :: ReadTransfer -> IO DeviceHandle
-- | Retrieve the endpoint address of a bulk or interrupt read transfer.
getReadTransferEndpointAddress :: ReadTransfer -> IO EndpointAddress
-- | Retrieve the timeout of a bulk or interrupt read transfer.
getReadTransferTimeout :: ReadTransfer -> IO Timeout
-- | Retreive the number of bytes to read for a bulk or interrupt transfer.
getReadTransferSize :: ReadTransfer -> IO Size
-- | A bulk or interrupt write transfer.
data WriteTransfer
-- | Create a new bulk or interrupt transfer that can write data to a
-- device.
newWriteTransfer :: RepeatableTransferType -> DeviceHandle -> EndpointAddress -> ByteString -> Timeout -> IO WriteTransfer
-- | Execute a bulk or interrupt transfer to write data to a device.
performWriteTransfer :: WriteTransfer -> IO (Size, Status)
-- | Specify whether the transfer should perform bulk or interrupt writes.
setWriteTransferType :: WriteTransfer -> RepeatableTransferType -> IO ()
-- | Update the device handle of a bulk or interrupt write transfer.
setWriteTransferDeviceHandle :: WriteTransfer -> DeviceHandle -> IO ()
-- | Update the endpoint address of a bulk or interrupt write transfer.
setWriteTransferEndpointAddress :: WriteTransfer -> EndpointAddress -> IO ()
-- | Update the timeout of a bulk or interrupt write transfer.
setWriteTransferTimeout :: WriteTransfer -> Timeout -> IO ()
-- | Update the bytes to write for a bulk or interrupt transfer.
setWriteTransferInput :: WriteTransfer -> ByteString -> IO ()
-- | Check if this transfer does bulk or interrupt writes.
getWriteTransferType :: WriteTransfer -> IO RepeatableTransferType
-- | Retrieve the device handle of a bulk or interrupt write transfer.
getWriteTransferDeviceHandle :: WriteTransfer -> IO DeviceHandle
-- | Retrieve the endpoint address of a bulk or interrupt write transfer.
getWriteTransferEndpointAddress :: WriteTransfer -> IO EndpointAddress
-- | Retrieve the timeout of a bulk or interrupt write transfer.
getWriteTransferTimeout :: WriteTransfer -> IO Timeout
-- | Retreive the bytes to write from a bulk or interrupt transfer.
getWriteTransferInput :: WriteTransfer -> IO ByteString
-- | An isochronous read transfer.
data IsochronousReadTransfer
-- | Create a new isochronous transfer that can read isochronous packets
-- from a device.
newIsochronousReadTransfer :: DeviceHandle -> EndpointAddress -> Vector Size -> Timeout -> IO IsochronousReadTransfer
-- | Execute a transfer to read isochronous packets from a device.
performIsochronousReadTransfer :: IsochronousReadTransfer -> IO (Vector ByteString)
-- | Update the device handle of an isochronous read transfer.
setIsochronousReadTransferDeviceHandle :: IsochronousReadTransfer -> DeviceHandle -> IO ()
-- | Update the endpoint address of an isochronous read transfer.
setIsochronousReadTransferEndpointAddress :: IsochronousReadTransfer -> EndpointAddress -> IO ()
-- | Update the size of packets to read for an isochronous transfer.
setIsochronousReadTransferSizes :: IsochronousReadTransfer -> Vector Size -> IO ()
-- | Retrieve the device handle of an isochronous read transfer.
getIsochronousReadTransferDeviceHandle :: IsochronousReadTransfer -> IO DeviceHandle
-- | Retrieve the endpoint address of an isochronous read transfer.
getIsochronousReadTransferEndpointAddress :: IsochronousReadTransfer -> IO EndpointAddress
-- | Retrieve the packets sizes to read for an isochronous transfer.
getIsochronousReadTransferSizes :: IsochronousReadTransfer -> IO (Vector Size)
-- | An isochronous write transfer.
data IsochronousWriteTransfer
-- | Create a new isochronous transfer that can write isochronous packets
-- to a device.
newIsochronousWriteTransfer :: DeviceHandle -> EndpointAddress -> Vector ByteString -> Timeout -> IO IsochronousWriteTransfer
-- | Execute a transfer to write isochronous packets to a device.
performIsochronousWriteTransfer :: IsochronousWriteTransfer -> IO (Vector Size)
-- | Update the device handle of an isochronous write transfer.
setIsochronousWriteTransferDeviceHandle :: IsochronousWriteTransfer -> DeviceHandle -> IO ()
-- | Update the endpoint address of an isochronous write transfer.
setIsochronousWriteTransferEndpointAddress :: IsochronousWriteTransfer -> EndpointAddress -> IO ()
-- | Update the packets to write for an isochronous transfer.
setIsochronousWriteTransferPackets :: IsochronousWriteTransfer -> Vector ByteString -> IO ()
-- | Retrieve the device handle of an isochronous write transfer.
getIsochronousWriteTransferDeviceHandle :: IsochronousWriteTransfer -> IO DeviceHandle
-- | Retrieve the endpoint address of an isochronous write transfer.
getIsochronousWriteTransferEndpointAddress :: IsochronousWriteTransfer -> IO EndpointAddress
-- | Retrieve the packets to write for an isochronous transfer.
getIsochronousWriteTransferPackets :: IsochronousWriteTransfer -> IO (Vector ByteString)
module System.USB.Exceptions
-- | Type of USB exceptions.
data USBException
-- | Input/output exception.
IOException :: String -> USBException
-- | Invalid parameter.
InvalidParamException :: USBException
-- | Access denied (insufficient permissions). It may help to run your
-- program with elevated privileges or change the permissions of your
-- device using something like udev.
AccessException :: USBException
-- | No such device (it may have been disconnected).
NoDeviceException :: USBException
-- | Entity not found.
NotFoundException :: USBException
-- | Resource busy.
BusyException :: USBException
-- | Operation timed out.
TimeoutException :: USBException
-- | If the device offered to much data. See Packets and overflows
-- in the libusb documentation.
OverflowException :: USBException
-- | Pipe exception.
PipeException :: USBException
-- | System call interrupted (perhaps due to signal).
InterruptedException :: USBException
-- | Insufficient memory.
NoMemException :: USBException
-- | Operation not supported or unimplemented on this platform. If
-- possible, it's recommended the check if a certain operation is
-- supported by using the hasCapability API.
NotSupportedException :: USBException
-- | Other exception.
OtherException :: USBException
-- | A general IOException.
ioException :: USBException
-- | IOException that is thrown when the number of bytes read
-- doesn't equal the requested number.
incompleteReadException :: USBException
-- | IOException that is thrown when the number of bytes
-- written doesn't equal the requested number.
incompleteWriteException :: USBException
-- | A convenience module which re-exports all the important modules.
module System.USB