-- 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
--   <tt>bindings-libusb</tt>
--   (<a>http://hackage.haskell.org/package/bindings-libusb</a>) which is a
--   low-level binding to the C library: <tt>libusb-1.*</tt>
--   (<a>http://libusb.org/</a>).
--   
--   The USB transfer functions in this library have a simple synchronous
--   interface (they block) but are implemented using the <tt>libusb</tt>
--   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 <tt>libusb</tt> 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
--   (<a>http://www.usb.org/developers/docs/</a>).
--   
--   For an example how to use this library see the <tt>usb-example</tt>
--   package (<a>https://github.com/basvandijk/usb-example</a>) or the
--   <tt>ls-usb</tt> package
--   (<a>http://hackage.haskell.org/package/ls-usb</a>).
--   
--   Besides this API documentation the following sources might be
--   interesting:
--   
--   <ul>
--   <li>The <tt>libusb 1.0</tt> documentation
--   (<a>http://libusb.sourceforge.net/api-1.0/</a>).</li>
--   <li>The USB 2.0 specification
--   (<a>http://www.usb.org/developers/docs/</a>).</li>
--   <li>The <tt>bindings-libusb</tt> documentation
--   (<a>http://hackage.haskell.org/package/bindings-libusb</a>).</li>
--   <li>"USB in a NutShell"
--   (<a>http://www.beyondlogic.org/usbnutshell/usb1.htm</a>).</li>
--   </ul>
@package usb
@version 1.3.0.5


-- | 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 (<a>StrIx</a>) 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 <a>USBException</a>s.
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 <a>getDeviceDesc</a>.
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
--   <a>deviceClass</a> value.
[deviceSubClass] :: DeviceDesc -> !Word8

-- | USB-IF protocol code for the device, qualified by the
--   <a>deviceClass</a> and <a>deviceSubClass</a> 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 <a>VendorId</a> 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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if the configuration does not exist.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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 <a>getConfigDesc</a>.
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 <tt>libusb</tt> 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 <a>configInterfaces</a>.
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
--   <a>interfaceClass</a> value.
[interfaceSubClass] :: InterfaceDesc -> !Word8

-- | USB-IF protocol code for the interface, qualified by the
--   <a>interfaceClass</a> and <a>interfaceSubClass</a> 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 <tt>libusb</tt> 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 <a>interfaceEndpoints</a>.
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
--   <a>configValue</a>.
[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

-- | <i>For audio devices only:</i> the rate at which synchronization
--   feedback is provided.
[endpointRefresh] :: EndpointDesc -> !Word8

-- | <i>For audio devices only:</i> the address of the synch endpoint.
[endpointSynchAddress] :: EndpointDesc -> !Word8

-- | Extra descriptors. If <tt>libusb</tt> 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 &gt;= 0 and &lt;= 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 -&gt; device) used for writing.
Out :: TransferDirection

-- | In transfer direction (device -&gt; 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 (<i>Start Of Frame</i>)
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 <a>Isochronous</a> or <a>Interrupt</a> endpoint, this
--   function will multiply the <a>maxPacketSize</a> by the additional
--   <a>transactionOpportunities</a>. If acting on another type of endpoint
--   only the <a>maxPacketSize</a> is returned.
--   
--   This function is mainly useful for setting up <i>isochronous</i>
--   transfers.
maxIsoPacketSize :: EndpointDesc -> Size

-- | Retrieve a vector of supported languages.
--   
--   This function may throw <a>USBException</a>s.
getLanguages :: DeviceHandle -> IO (Vector LangId)

-- | The language ID consists of the primary language identifier and the
--   sublanguage identififier as described in:
--   
--   <a>http://www.usb.org/developers/docs/USB_LANGIDs.pdf</a>
--   
--   For a mapping between IDs and languages see the <a>usb-id-database</a>
--   package.
--   
--   To see which <a>LangId</a>s are supported by a device see
--   <a>getLanguages</a>.
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 <a>USBException</a>s.
getStrDesc :: DeviceHandle -> StrIx -> LangId -> Int -> IO Text

-- | Retrieve a string descriptor from a device using the first supported
--   language.
--   
--   This function may throw <a>USBException</a>s.
getStrDescFirstLang :: DeviceHandle -> StrIx -> Int -> IO Text


-- | 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 <a>openDevice</a>.
--   
--   A device handle is used to perform I/O and other operations. When
--   finished with a device handle you should close it by applying
--   <a>closeDevice</a> 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 <a>withDeviceHandle</a> because it
--   automatically closes the device when the computation terminates.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>NoMemException</a> if there is a memory allocation
--   failure.</li>
--   <li><a>AccessException</a> if the user has insufficient
--   permissions.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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 ()

-- | <tt>withDeviceHandle dev act</tt> opens the <a>Device</a> <tt>dev</tt>
--   and passes the resulting handle to the computation <tt>act</tt>. The
--   handle will be closed on exit from <tt>withDeviceHandle</tt> whether
--   by normal termination or by raising an exception.
withDeviceHandle :: Device -> (DeviceHandle -> IO a) -> IO a

-- | Retrieve the <a>Device</a> from the <a>DeviceHandle</a>.
getDevice :: DeviceHandle -> Device

-- | Identifier for configurations.
--   
--   Can be retrieved by <a>getConfig</a> or by <a>configValue</a>.
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 <a>Nothing</a> if the device is in unconfigured
--   state.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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 <a>releaseInterface</a> first.
--   You cannot change/reset configuration if other applications or drivers
--   have claimed interfaces.
--   
--   A configuration value of <a>Nothing</a> 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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if the requested configuration does not
--   exist.</li>
--   <li><a>BusyException</a> if interfaces are currently claimed.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
setConfig :: DeviceHandle -> Maybe ConfigValue -> IO ()

-- | Identifier for interfaces.
--   
--   Can be retrieved by <a>interfaceNumber</a>.
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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if the requested interface does not
--   exist.</li>
--   <li><a>BusyException</a> if the interface is already claimed.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
claimInterface :: DeviceHandle -> InterfaceNumber -> IO ()

-- | Release an interface previously claimed with <a>claimInterface</a>.
--   
--   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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if the interface was not claimed.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
releaseInterface :: DeviceHandle -> InterfaceNumber -> IO ()

-- | <tt>withClaimedInterface</tt> claims the interface on the given device
--   handle then executes the given computation. On exit from
--   <tt>withClaimedInterface</tt>, 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 <a>interfaceAltSetting</a>.
type InterfaceAltSetting = Word8

-- | Activate an alternate setting for an interface.
--   
--   The interface must have been previously claimed with
--   <a>claimInterface</a>.
--   
--   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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if the interface was not claimed or the
--   requested alternate setting does not exist.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if the endpoint does not exist.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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 <a>NotFoundException</a>
--   is raised to indicate that this is the case.
--   
--   This is a blocking function which usually incurs a noticeable delay.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>NotFoundException</a> if re-enumeration is required, or if the
--   device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
resetDevice :: DeviceHandle -> IO ()

-- | Enable/disable <tt>libusb's</tt> automatic kernel driver detachment.
--   When this is enabled <tt>libusb</tt> 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 <a>SupportsDetachKernelDriver</a>
--   capability this function will throw a <a>NotSupportedException</a>,
--   and <tt>libusb</tt> 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:
--   
--   <ul>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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:
--   
--   <ul>
--   <li><a>NotFoundException</a> if no kernel driver was active.</li>
--   <li><a>InvalidParamException</a> if the interface does not exist.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
detachKernelDriver :: DeviceHandle -> InterfaceNumber -> IO ()

-- | Re-attach an interface's kernel driver, which was previously detached
--   using <a>detachKernelDriver</a>.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>NotFoundException</a> if no kernel driver was active.</li>
--   <li><a>InvalidParamException</a> if the interface does not exist.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li><a>BusyException</a> if the driver cannot be attached because the
--   interface is claimed by a program or driver.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
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:
--   
--   <ul>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
withDetachedKernelDriver :: DeviceHandle -> InterfaceNumber -> IO a -> IO a


-- | 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 <a>getDevices</a> function.
--   
--   Certain operations can be performed on a device, but in order to do
--   any I/O you will have to first obtain a <a>DeviceHandle</a> using
--   <a>openDevice</a>.
--   
--   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 <a>getDeviceDesc</a>.
data Device

-- | Returns a vector of USB devices currently attached to the system.
--   
--   This is your entry point into finding a USB device.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>NoMemException</a> on a memory allocation failure.</li>
--   </ul>
getDevices :: Ctx -> IO (Vector Device)

-- | The set of hotplug events to trigger the callback in
--   <a>registerHotplugCallback</a>.
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 <a>closeDevice</a> on any
--   handle associated with a disconnected device. It is safe to call
--   <a>getDeviceDesc</a> on a device that has left.
deviceLeft :: HotplugEvent

-- | Determine if the set of events contains a <a>deviceArrived</a> event.
matchDeviceArrived :: HotplugEvent -> Bool

-- | Determine if the set of events contains a <a>deviceLeft</a> event.
matchDeviceLeft :: HotplugEvent -> Bool

-- | Set of configuration flags for <a>registerHotplugCallback</a>.
data HotplugFlag

-- | Fire events for all matching currently attached devices.
enumerate :: HotplugFlag

-- | Hotplug callback function type used in <a>registerHotplugCallback</a>.
--   
--   <tt>libusb</tt> will call this function, once registered using
--   <a>registerHotplugCallback</a>, when a matching event has 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 <a>registerHotplugCallback</a> or
--   <a>deregisterHotplugCallback</a> from within a callback function.
--   
--   Should return a <a>CallbackRegistrationStatus</a> which indicates
--   whether this callback is finished processing events. Returning
--   <a>DeregisterThisCallback</a> 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:
--   
--   <pre>
--   waitForMyDevice :: Ctx
--                   -&gt; Maybe VendorId
--                   -&gt; Maybe ProductId
--                   -&gt; Maybe Word8
--                   -&gt; IO Device
--   waitForMyDevice ctx mbVendorId mbProductId mbDevClass = do
--     mv &lt;- 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 &lt;- registerHotplugCallback ctx
--                                    deviceArrived
--                                    enumerate
--                                    mbVendorId
--                                    mbProductId
--                                    mbDevClass
--                                    (\dev event -&gt;
--                                       tryPutMVar mv (dev, event) $&gt;
--                                         DeregisterThisCallback)
--       (dev, _event) &lt;- takeMVar mv
--                          `onException`
--                            deregisterHotplugCallback h
--       return dev
--   </pre>
type HotplugCallback = Device -> HotplugEvent -> IO CallbackRegistrationStatus

-- | Returned from a <a>HotplugCallback</a> 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 <a>registerHotplugCallback</a> and
--   can be used to deregister callbacks. Callback handles are unique per
--   <a>Ctx</a> and it is safe to call <a>deregisterHotplugCallback</a> on
--   an already deregisted callback.
data HotplugCallbackHandle

-- | <i>WARNING:</i> see the note on <a>HotplugCallback</a> 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
--   <a>deregisterHotplugCallback</a> or the supplied callback returns
--   <a>DeregisterThisCallback</a> to indicate it is finished processing
--   events.
--   
--   If the <a>enumerate</a> flag is passed the callback will be called
--   with a <a>deviceArrived</a> for all devices already plugged into the
--   machine. Note that <tt>libusb</tt> modifies its internal device list
--   from a separate thread, while calling hotplug callbacks from
--   <tt>libusb_handle_events()</tt>, 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 <a>enumerate</a> flag, your callback may be called
--   twice for the arrival of the same device, once from
--   <a>registerHotplugCallback</a> and once from
--   <tt>libusb_handle_events()</tt>; 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 <a>Ctx</a>. 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.
--   
--   <a>Nothing</a> 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


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 <tt>udev</tt>.
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 <a>Packets and overflows</a>
--   in the <tt>libusb</tt> 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 <a>hasCapability</a> API.
NotSupportedException :: USBException

-- | Other exception.
OtherException :: USBException

-- | A general <a>IOException</a>.
ioException :: USBException

-- | <a>IOException</a> that is thrown when the number of bytes <i>read</i>
--   doesn't equal the requested number.
incompleteReadException :: USBException

-- | <a>IOException</a> that is thrown when the number of bytes
--   <i>written</i> doesn't equal the requested number.
incompleteWriteException :: USBException


-- | This module provides functions for performing <i>control</i>,
--   <i>bulk</i> and <i>interrupt</i> transfers.
--   
--   When your system supports the GHC <a>EventManager</a> this module
--   additionally exports functions for performing <i>isochronous</i>
--   transfers. These are currently not available on Windows.
--   
--   <i>WARNING:</i> You need to enable the threaded runtime
--   (<tt>-threaded</tt>) when using the isochronous functions. They throw
--   a runtime error otherwise!
module System.USB.IO

-- | Handy type synonym for read transfers.
--   
--   A <tt>ReadAction</tt> is a function which takes a <a>Size</a> which
--   defines how many bytes to read and a <a>Timeout</a>. The function
--   returns an <a>IO</a> action which, when executed, performs the actual
--   read and returns the <a>ByteString</a> that was read paired with a
--   <a>Status</a> flag which indicates whether the transfer
--   <a>Completed</a> or <a>TimedOut</a>.
type ReadAction = Size -> Timeout -> IO (ByteString, Status)

-- | Handy type synonym for read transfers that must exactly read the
--   specified number of bytes. An <a>incompleteReadException</a> is thrown
--   otherwise.
type ReadExactAction = Size -> Timeout -> IO ByteString

-- | Handy type synonym for write transfers.
--   
--   A <tt>WriteAction</tt> is a function which takes a <a>ByteString</a>
--   to write and a <a>Timeout</a>. The function returns an <a>IO</a>
--   action which, when exectued, returns the number of bytes that were
--   actually written paired with a <a>Status</a> flag which indicates
--   whether the transfer <a>Completed</a> or <a>TimedOut</a>.
type WriteAction = ByteString -> Timeout -> IO (Size, Status)

-- | Handy type synonym for write transfers that must exactly write all the
--   given bytes. An <a>incompleteWriteException</a> 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
--   <a>noTimeout</a> for no timeout.
type Timeout = Int

-- | A timeout of 0 denotes no timeout so: <tt>noTimeout = 0</tt>.
noTimeout :: Timeout

-- | Status of a terminated transfer.
data Status

-- | All bytes were transferred within the maximum allowed <a>Timeout</a>
--   period.
Completed :: Status

-- | Not all bytes were transferred within the maximum allowed
--   <a>Timeout</a> 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 <tt>GetStatus</tt>
--   <a>Standard</a> 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 <i>control</i> request that does not transfer data.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>TimeoutException</a> if the transfer timed out.</li>
--   <li><a>PipeException</a> if the control request was not supported by
--   the device</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
control :: DeviceHandle -> ControlSetup -> Timeout -> IO ()

-- | Perform a USB <i>control</i> read.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the control request was not supported by
--   the device</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
readControl :: DeviceHandle -> ControlSetup -> ReadAction

-- | A convenience function similar to <a>readControl</a> which checks if
--   the specified number of bytes to read were actually read. Throws an
--   <a>incompleteReadException</a> if this is not the case.
readControlExact :: DeviceHandle -> ControlSetup -> ReadExactAction

-- | Perform a USB <i>control</i> write.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the control request was not supported by
--   the device</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
writeControl :: DeviceHandle -> ControlSetup -> WriteAction

-- | A convenience function similar to <a>writeControl</a> which checks if
--   the given bytes were actually fully written. Throws an
--   <a>incompleteWriteException</a> if this is not the case.
writeControlExact :: DeviceHandle -> ControlSetup -> WriteExactAction

-- | Perform a USB <i>bulk</i> read.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the endpoint halted.</li>
--   <li><a>OverflowException</a> if the device offered more data, see
--   <a>Packets and overflows</a> in the <tt>libusb</tt>
--   documentation.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
readBulk :: DeviceHandle -> EndpointAddress -> ReadAction

-- | Perform a USB <i>bulk</i> write.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the endpoint halted.</li>
--   <li><a>OverflowException</a> if the device offered more data, see
--   <a>Packets and overflows</a> in the <tt>libusb</tt>
--   documentation.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
writeBulk :: DeviceHandle -> EndpointAddress -> WriteAction

-- | Perform a USB <i>interrupt</i> read.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the endpoint halted.</li>
--   <li><a>OverflowException</a> if the device offered more data, see
--   <a>Packets and overflows</a> in the <tt>libusb</tt>
--   documentation.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
readInterrupt :: DeviceHandle -> EndpointAddress -> ReadAction

-- | Perform a USB <i>interrupt</i> write.
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the endpoint halted.</li>
--   <li><a>OverflowException</a> if the device offered more data, see
--   <a>Packets and overflows</a> in the <tt>libusb</tt>
--   documentation.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction

-- | Perform a USB <i>isochronous</i> read.
--   
--   <i>WARNING:</i> You need to enable the threaded runtime
--   (<tt>-threaded</tt>) for this function to work correctly. It throws a
--   runtime error otherwise!
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the endpoint halted.</li>
--   <li><a>OverflowException</a> if the device offered more data, see
--   <a>Packets and overflows</a> in the <tt>libusb</tt>
--   documentation.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
readIsochronous :: DeviceHandle -> EndpointAddress -> Vector Size -> Timeout -> IO (Vector ByteString)

-- | Perform a USB <i>isochronous</i> write.
--   
--   <i>WARNING:</i> You need to enable the threaded runtime
--   (<tt>-threaded</tt>) for this function to work correctly. It throws a
--   runtime error otherwise!
--   
--   Exceptions:
--   
--   <ul>
--   <li><a>PipeException</a> if the endpoint halted.</li>
--   <li><a>OverflowException</a> if the device offered more data, see
--   <a>Packets and overflows</a> in the <tt>libusb</tt>
--   documentation.</li>
--   <li><a>NoDeviceException</a> if the device has been disconnected.</li>
--   <li>Another <a>USBException</a>.</li>
--   </ul>
writeIsochronous :: DeviceHandle -> EndpointAddress -> Vector ByteString -> Timeout -> IO (Vector Size)


-- | <i>WARNING:</i> This module is experimental and untested. The API will
--   likely change in future releases.
--   
--   <i>WARNING:</i> This module is only available on systems which support
--   the GHC <a>EventManager</a>.
--   
--   <i>WARNING:</i> You need to enable the threaded runtime
--   (<tt>-threaded</tt>) when using this module. The functions throw a
--   runtime error otherwise!
--   
--   This modules provides alternative I/O operations than the ones in
--   <a>System.USB.IO</a>. 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 <a>ReadTransfer</a> or <a>WriteTransfer</a> which can either
--   be <i>bulk</i> or <i>interrupt</i>.
--   
--   Note that isochronous transfers are handled differently using the
--   <a>IsochronousReadTransfer</a> or <a>IsochronousWriteTransfer</a>
--   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)


-- | This module provides functionality for initializing the <tt>usb</tt>
--   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 <a>newCtx</a> and are
--   automatically closed when they are garbage collected.
--   
--   The only functions that receive a <tt>Ctx</tt> are
--   <a>hasCapability</a>, <a>setDebug</a> and <a>getDevices</a>.
data Ctx

-- | Create and initialize a new USB context.
--   
--   This function may throw <a>USBException</a>s.
--   
--   Note that the internal <tt>libusb</tt> event handling can return
--   errors. These errors occur in the thread that is executing the event
--   handling loop. <a>newCtx</a> will print these errors to <a>stderr</a>.
--   If you need to handle the errors yourself (for example log them in an
--   application specific way) please use <a>newCtx'</a>.
newCtx :: IO Ctx

-- | Like <a>newCtx</a> but enables you to specify the way errors should be
--   handled that occur while handling <tt>libusb</tt> events.
newCtx' :: (USBException -> IO ()) -> IO Ctx

-- | Set message verbosity.
--   
--   The default level is <a>PrintNothing</a>. 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
--   <tt>stdout</tt>/<tt>stderr</tt> file descriptors.
--   
--   You are advised to set the debug level to <a>PrintWarnings</a>. 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 <tt>libusb</tt> was compiled without any message logging, this
--   function does nothing: you'll never get any messages.
--   
--   If <tt>libusb</tt> 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 <tt>stderr</tt>.
PrintErrors :: Verbosity

-- | Warning and error messages are printed to <tt>stderr</tt>.
PrintWarnings :: Verbosity

-- | Informational messages are printed to <tt>stdout</tt>, warning and
--   error messages are printed to <tt>stderr</tt>.
PrintInfo :: Verbosity

-- | Debug and informational messages are printed to <tt>stdout</tt>,
--   warnings and errors to <tt>stderr</tt>.
PrintDebug :: Verbosity


-- | This module provides miscellaneous functionality.
module System.USB.Misc

-- | Capabilities supported by an instance of <tt>libusb</tt> on the
--   current running platform.
--   
--   Test if the loaded <tt>libusb</tt> library supports a given capability
--   by calling <a>hasCapability</a>.
data Capability

-- | The <a>hasCapability</a> 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 <tt>libusb</tt> functions such as
--   <a>detachKernelDriver</a>.
HasHidAccess :: Capability

-- | The library supports detaching of the default USB driver, using
--   <a>detachKernelDriver</a>, if one is set by the OS kernel.
SupportsDetachKernelDriver :: Capability

-- | Check at runtime if the loaded <tt>libusb</tt> library has a given
--   capability.
--   
--   This call should be performed after <a>newCtx</a>, to ensure the
--   backend has updated its capability set. For this reason you need to
--   apply it to a <a>Ctx</a>.
hasCapability :: Ctx -> Capability -> Bool

-- | Structure providing the version of the <tt>libusb</tt> 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. <tt>"-rc4"</tt>.
[rc] :: LibusbVersion -> String

-- | Returns the version (major, minor, micro, nano and rc) of the loaded
--   <tt>libusb</tt> library.
libusbVersion :: LibusbVersion

-- | Convert a <a>LibusbVersion</a> to a <a>Version</a> for easy
--   comparison.
toVersion :: LibusbVersion -> Version


-- | A convenience module which re-exports all the important modules.
module System.USB
