-- 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