ocaml-libusb/lib/libusb.mli
Matthieu Dubuget 3e672915f3 Documentations
2018-06-24 12:14:05 +02:00

168 lines
6.3 KiB
OCaml

(** Binding to a tiny part of {{:http://libusb.info} libusb}. *)
(** For a more complete binding, have a look at the more complete and more advanced
{{:https://github.com/letoh/ocaml-usb} ocaml-usb}.
I wrote this alternate binding:
- in order to experiment more in depth with {{:https://github.com/ocamllabs/ocaml-ctypes} Ctypes};
- and because I needed something more portable than {{:https://github.com/letoh/ocaml-usb} ocaml-usb}: this one is working on Windows. *)
open Ctypes
include module type of T
(** {1 Getting more of {! error}s} *)
val string_of_error: error -> string
val description_of_error: error -> string
(** {1 Flags} *)
(** {2 Request types} *)
val request_type_standard: int
val request_type_class: int
val request_type_vendor: int
val request_type_reserved: int
(** {2 Endpoint directions} *)
val endpoint_direction_in: int
val endpoint_direction_out: int
(** {2 Recipients} *)
val recipient_device: int
val recipient_interface: int
val recipient_endpoint: int
val recipient_other: int
(** {1 Initialisation} *)
val init_libusb: unit -> (unit, error) result
(** This function must be called before calling any other libusb function. *)
val exit_libusb: unit -> unit
(** Should be called after closing all open devices and before your application
terminates. *)
val get_version: unit -> version
(** @return the version of the used C libusb library *)
(** {1 Devices enumeration} *)
type device
(** Opaque type representing a C pointer to a device *)
val get_device_list: unit -> (device list, error) result
(** @return a list of C pointers to libusb devices.
Each device returned in the list has it's reference counter set to 1. Do not
forget to {!Libusb.unref_device} each of them after use (see below). *)
val unref_device: device -> unit
(** [unref_device d] decrements the reference count of [d].
If the decrement operation causes the reference count to reach zero, the
device shall be destroyed by libusb C library. *)
val unref_devices: device list -> unit
(** [unref_devices l == List.iter unref_device l] *)
val is_vendor: int -> device -> bool
(** [is_vendor vend d] checks if device [d] vendor id is [vend] *)
val is_product: int -> device -> bool
(** [is_product prod d] checks if device [d] product id is [prod] *)
val filter_devices: (device -> bool) -> device list -> device list
(** [filter_devices f dl] filters [dl] devices list using [f].
The devices of [dl] which are not part of the returned list are
unreferenced with {!Libusb.unref_device}. *)
(** {1 Device opening} *)
type device_handle
(** A opaque type to manipulate opened devices *)
val open_device: ?unref:bool -> device -> (device_handle, error) result
(** The C libusb library device opening increments the device reference count.
If the operation is successfull, and if [unref] is true (which is it's
default value) {!Libusb.open_device} decrements the device reference counter
of the device: this allows the device to be destroyed automatically when
{!Libusb.close_device} will be called. *)
val close_device: device_handle -> unit
(** Closes the device. This operation decrements the reference counter.
TODO: make the reference counter decrement optionnal? *)
val get_device_descriptor: device -> (device_descriptor, error) result
val get_string_descriptor: device_handle -> int -> (string, error) result
val claim_interface: device_handle -> int -> (unit, error) result
(** 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
libusb 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. *)
val release_interface: device_handle -> int -> (unit, error) result
(** Release an interface previously claimed with {! claim_interface}.
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. *)
(** {1 Synchronous device I/O} *)
val control_transfer: device_handle:device_handle -> request_type:int -> request:int -> value:int -> index:int -> buffer:(char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t -> timeout:int -> unit -> error
(** Perform a USB control transfer.
@param request_type is a bitfield used to parameter the transfer. It can be
constructed with a logical or between constants. By instance, to make a
vendor request output, this parameter can be set to [(]{!
endpoint_direction_in} [ lor ] {! request_type_vendor} [ lor ] {!
recipient_device} [)].
The [value] and [index] fields values should be given in host-endian byte
order. TODO: check if something can be done to have the OCaml binding take
care of this. *)
val bulk_transfer: device_handle:device_handle -> endpoint:int -> buffer:(char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t -> timeout:int -> unit -> (int, error) result
(** Perform a USB bulk transfer.
The direction of the transfer is inferred from the direction bits of the
[endpoint] address. By instance, to write on the [#1] endpoint, [endpoint]
should be passed : [(] {! Libusb.endpoint_direction_out} [ lor 1] [)].
For bulk reads, the length of [buffer] indicates the maximum length of data
you are expecting to receive. If less data arrives than expected, this
function will return that data, so be sure to check the transferred output
parameter.
You should also check the transferred parameter for bulk writes. Not all of
the data may have been written.
Also check transferred when dealing with a timeout error code. libusb may
have to split your transfer into a number of chunks to satisfy underlying O/S
requirements, meaning that the timeout may expire after the first few chunks
have completed. libusb is careful not to lose any data that may have been
transferred; do not assume that timeout conditions indicate a complete lack of
I/O. *)