úÎ þú!=      !"#$%&'()*+,-./0123456789:;<#Bas van Dijk <v.dijk.bas@gmail.com>30Control transfers can have three request types: Standard, Class and Vendor. We disallow Standard, requests however because with them you can 9destroy the safety guarantees that this module provides. =-Class of transfer types that support writing Write bytes to an  endpoint with either a  or   transfer type. (Handy type synonym for write transfers. A  WriteAction; is a function which takes a timeout and the bytestring to Owrite. The function returns an action which, when exectued, returns the number Nof bytes that were actually written paired with an indication if the transfer  timed out. >.Class of transfer types that support reading. Read bytes from an  endpoint with either a  or   transfer type. 'Handy type synonym for read transfers. A  ReadActionB is a function which takes a timeout and a size which defines how Imany bytes to read. The function returns an action which, when executed, Qperforms the actual read and returns the bytestring that was read paired with an &indication if the transfer timed out. 9In transfer direction (device -> host) used for reading. :Out transfer direction (host -> device) used for writing. I/CO operations on endpoints are type-safe. You can only read from an endpoint with an : transfer direction and you can only write to an endpoint with an  transfer direction. JReading and writing also have different implementations for the different endpoint transfer types like:  and . I/O with endpoints of other transfer types like   and   is not possible. LThis type lifts the transfer direction and transfer type information to the type-level so that I/O operations like  and  can &specify which endpoints they support. 8You can retrieve the endpoints of an alternate by using 1. (A handle to a setted alternate setting. 'You get a handle to an alternate using ., / or 0. The type variable sAlt is used to ensure that you can't )return this handle from these functions.  A supported  alternate setting. AHandy type synonym for a regional handle to a claimed interface. DA regional handle to a claimed interface can be created by applying , or ?% to the interface you wish to claim. MHandy type synonym for a region in which interfaces can be claimed which are 3automatically released when the region terminates. %You can run an interface region with @. FA supported interface of a configuration which you can retrieve using  +. To retrieve the A! descriptors of an interface use !. !This exception will be thrown in * or 0 to I indicate that no setting was found which satisfies the given predicate.  This exception can be thrown in ) to indicate that the $device is currently not configured. !This exception can be thrown in:  &  (, ) or *  ., / or 0 Cto indicate that the device was already configured with a setting. A handle to an active  which you can get using: (, ) or *. The type variable sCfg is used to ensure that you can'+t return this handle from these functions. FA supported configuration of a USB device parameterized by the region r in which it was created. QNote that, just like a regional device handle, a configuration can be duplicated to a parent region using B. !*Get the descriptor of a given USB entity. "BHandy type synonym for a regional handle to an opened USB device. EA regional handle to an opened USB device can be created by applying C or ?% to the USB device you wish to open. Note that you can also  duplicate& a regional device handle by applying B to it. #1Handy type synonym for a device region which has D as its parent region which enables it to be:  directly executed in D using E, * concurrently executed in a new thread by F. $MHandy type synonym for a region in which USB devices can be opened which are 1automatically closed when the region terminates. !You can run a device region with @. %GConvenience function for retrieving the device from the given regional  handle. &KPerform a USB port reset to reinitialize a device. The system will attempt Qto restore the previous configuration and alternate settings after the reset has  completed. Note the constraint: pr `ParentOf` cr". This allows this function to be executed in any child region cr of the parent region pr in which the given regional handle was created. <You can only reset a device when all computations passed to (, ) and *# have been terminated. If you call  resetDevice+ and such a computation is still running a  exception is thrown. LIf the reset fails, the descriptors change, or the previous state cannot be Prestored, the device will appear to be disconnected and reconnected. This means Othat 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. OTODO: Think about how to handle the implications of the the previous paragraph! EThis is a blocking function which usually incurs a noticeable delay.  Exceptions:  NotFoundException* if re-enumeration is required, or if the ! device has been disconnected.  ' if a configuration has been set using (,  ) and *.  Another  USBException. 'FRetrieve the supported configurations from the given regional handle. @Note that the configuration is parameterized by the same region r in which the Lregional handle was created. This ensures you can never use a configuration outside that region. (LSet the active configuration for a device and then apply the given function 'to the resulting configuration handle. OUSB devices support multiple configurations of which only one can be active at 2any given time. When a configuration is set using (, ) or *> no threads can set a new configuration until the computation Apassed to these functions terminates. If you do try to set one a  exception will be thrown. PThe operating system may or may not have already set an active configuration on Pthe device. It is up to your application to ensure the correct configuration is Qselected before you attempt to claim interfaces and perform other operations. If 5you want to use the current active configuration use ). KIf you call this function on a device already configured with the selected Mconfiguration, then this function will act as a lightweight device reset: it Pwill issue a SET_CONFIGURATION request using the current configuration, causing Nmost USB-related device state to be reset (altsetting reset to zero, endpoint halts cleared, toggles reset). You cannot change/:reset configuration if other applications or drivers have claimed interfaces. This is a blocking function.  Exceptions:   BusyException& if interfaces are currently claimed.  NoDeviceException% if the device has been disconnected  / if a configuration has already been set using  (, ) or *.  Another  USBException. G If the given MVar was set a  exception will be O thrown. If not it will be set before the given computation will be performed. )KApply the given function to the configuration handle of the current active *configuration of the given device handle. HThis function needs to determine the current active configuration. This <information may be cached by the operating system. If it isn't cached this Jfunction will block while a control transfer is submitted to retrieve the  information.  Exceptions:  NoDeviceException& if the device has been disconnected.  / if a configuration has already been set using  (, ) or *.  " if the device is not configured.  Aanother  USBException. *MConvenience function which finds the first configuration of the given device Mhandle which satisfies the given predicate on its descriptor, then sets that Lconfiguration and applies the given function to the resulting configuration handle. This function calls ( so do see its documentation.  Exceptions:  7 if no configuration is found that satisfies the given  predicate.   BusyException& if interfaces are currently claimed.  NoDeviceException% if the device has been disconnected  / if a configuration has already been set using  (, ) or *.  Another  USBException. +ARetrieve the supported interfaces from the configuration handle. 0Note that the interface is parameterized by the sCfg of the configuration Ohandle it is derived from. This ensures that it can never be returned from the 2functions that created this configuration handle: (, ) and *. NThe latter is useful because outside those functions the active configuration Emay change. If at that moment you still have an interface of the old -configuration claiming it would be an error. ,3Claim the given interface in the interface region.  Note that: claim = C, which just reads better when applied to an  interface. ?Note that it is allowed to claim an already-claimed interface. LClaiming of interfaces is a purely logical operation; it does not cause any Mrequests to be sent over the bus. Interface claiming is used to instruct the Nunderlying operating system that your application wishes to take ownership of the interface. !This is a non-blocking function.  Exceptions:   BusyException& if the interface is already claimed.  NoDeviceException& if the device has been disconnected.  Another  USBException. HCConvenience function which finds the first interfaces of the given Qconfiguration handle which satisfies the given predicate on its descriptor, then Pclaims that interfaces and applies the given function on the resulting regional handle. -ERetrieve the supported alternate settings from the interface handle. ONote that the alternate setting is parameterized by the same type variables as Jthe interface handle. This ensures you can never use an alternate setting >outside the region in which the interface handle was created. .HActivate an alternate setting for an interface and then apply the given ,function to the resulting alternate handle. OSimillary to configurations, interfaces support multiple alternate settings of Owhich only one can be active at any given time. When an alternate is set using ., / or 0 no threads can set a Qnew alternate until the computation passed to these functions terminates. If you do try to set one a  exception will be thrown. QThe operating system may already have set an alternate for the interface. If you .want to use this current active alternate use /. This is a blocking function.  Exceptions:  NoDeviceException& if the device has been disconnected.  , if an alternate has already been set using  ., / or 0.  Another  USBException. /GApply the given function to the alternate handle of the current active (alternate of the give interface handle. KTo determine the current active alternate this function will block while a ;control transfer is submitted to retrieve the information.  Exceptions:  NoDeviceException& if the device has been disconnected.  , if an alternate has already been set using  ., / or 0.  Aanother  USBException. 0LConvenience function which finds the first alternate of the given interface Mhandle which satisfies the given predicate on its descriptor, then sets that Lalternate and applies the given function to the resulting alternate handle. This function calls . so do see its documentation.  Exceptions:  3 if no alternate is found that satisfies the given  predicate.  NoDeviceException& if the device has been disconnected.  , if an alternate has already been set using  ., / or 0.  Another  USBException. 1LRetrieve all the endpoints from the given alternate handle which are of the - given transfer direction and transfer type. 2Clear the halt/!stall condition for an endpoint. QEndpoints with halt status are unable to receive or transmit data until the halt condition is stalled. LYou should cancel all pending transfers before attempting to clear the halt  condition. This is a blocking function.  Exceptions:  NoDeviceException& if the device has been disconnected.  Another  USBException. 3Perform a USB control& request that does not transfer data. The value and index3 values should be given in host-endian byte order.  Exceptions:  TimeoutException if the transfer timed out.   PipeException8 if the control request was not supported by the device  NoDeviceException& if the device has been disconnected.  Another  USBException. 4Perform a USB control read. The value and index3 values should be given in host-endian byte order.  Exceptions:   PipeException8 if the control request was not supported by the device  NoDeviceException& if the device has been disconnected.  Another  USBException. 5Perform a USB control write. The value and index3 values should be given in host-endian byte order.  Exceptions:   PipeException8 if the control request was not supported by the device  NoDeviceException& if the device has been disconnected.  Another  USBException. 6(Retrieve a list of supported languages. This function may throw  USBExceptions. 7,Retrieve a string descriptor from a device. PThis is a convenience function which formulates the appropriate control message Oto retrieve the descriptor. The string returned is Unicode, as detailed in the USB specifications. This function may throw  USBExceptions. /TODO: The following can be made more type-safe!  When I call 74 I would like the type system to guarantee that the given StrIx and LangId actually belong to the given Handle . In other Nwords I would like to get a type error when they are some arbitrary number or come from another device. 8ERetrieve a string descriptor from a device using the first supported  language. PThis is a convenience function which formulates the appropriate control message Oto retrieve the descriptor. The string returned is Unicode, as detailed in the USB specifications. This function may throw  USBExceptions. 98Determine if a kernel driver is active on an interface. QIf a kernel driver is active, you cannot claim the interface, and libusb will be unable to perform I/O.  Exceptions:  NoDeviceException& if the device has been disconnected.  Another  USBException. :*Detach a kernel driver from an interface. IIf successful, you will then be able to claim the interface and perform I/O.  Exceptions:  NotFoundException! if no kernel driver was active.  InvalidParamException" if the interface does not exist.  NoDeviceException& if the device has been disconnected.  Another  USBException. ;Re-attach an interface'&s kernel driver, which was previously detached using :.  Exceptions:  NotFoundException! if no kernel driver was active.  InvalidParamException" if the interface does not exist.  NoDeviceException& if the device has been disconnected.   BusyException8 if the driver cannot be attached because the interface & is claimed by a program or driver.  Another  USBException. <FIf a kernel driver is active on the specified interface the driver is Pdetached and the given action is executed. If the action terminates, whether by Mnormal termination or by raising an exception, the kernel driver is attached Qagain. If a kernel driver is not active on the specified interface the action is just executed.  Exceptions:  NoDeviceException& if the device has been disconnected.  Another  USBException. IMonadic if ... then ... else ... F?CFE@JKLB  !"#$%&'()*+,-./0123456789:;<=$#"% !&'()*+,-./012  3456789:;<=   !!"#$%&'()*+,-./0123456789:;<M      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI"JKLMNOPQRSTUV usb-safe-0.4System.USB.Safe regions-0.1#Control.Monad.Trans.Region.Internalusb-0.3System.USB.Descriptorsbase System.IO RequestTypeVendorClass writeEndpoint WriteAction readEndpoint ReadAction INTERRUPTBULK ISOCHRONOUSCONTROL TransferType InterruptBulk IsochronousControlINOUTTransferDirectionInOutEndpointAlternateHandle AlternateRegionalIfHandle IfRegionT InterfaceNotFoundNoActiveConfigSettingAlreadySet ConfigHandleConfig GetDescriptorgetDescRegionalDeviceHandleTopDeviceRegion DeviceRegionT getDevice resetDevice getConfigs setConfiguseActiveConfigsetConfigWhich getInterfacesclaim getAlternates setAlternateuseActiveAlternatesetAlternateWhich getEndpoints clearHaltcontrol readControl writeControl getLanguages getStrDescgetStrDescFirstLangkernelDriverActivedetachKernelDriverattachKernelDriverwithDetachedKernelDriver WriteEndpoint ReadEndpointwith runRegionTSystem.USB.Internaldupopen GHC.IOBaseIO runTopRegion forkTopRegionwithUnsettedMVarwithInterfaceWhichifMRegionT TopRegionRegionalHandle