diff --git a/libusb.odin b/libusb.odin index cae68b6..af336eb 100644 --- a/libusb.odin +++ b/libusb.odin @@ -2,6 +2,7 @@ package libusb import "core:c" import "core:fmt" +import "core:sys/posix" //TODO: Probably want to switch this to being statically linked foreign import lib "system:usb-1.0" @@ -804,8 +805,7 @@ Transfer_Status :: enum c.int { OVERFLOW, } -// This is not compatible with the C enum and is meant to always be used with [Transfer_Set]. -Transfer_Flags :: enum u8 { +Transfer_Flag_Bits :: enum u8 { /** Report short frames as errors */ SHORT_NOT_OK, /** Automatically free() transfer buffer during libusb_free_transfer(). @@ -845,7 +845,7 @@ Transfer_Flags :: enum u8 { ADD_ZERO_PACKET, } -Transfer_Set :: bit_set[Transfer_Flags;u8] +Transfer_Flag :: bit_set[Transfer_Flag_Bits;u8] /** \ingroup libusb_asyncio * Isochronous packet descriptor. */ @@ -870,7 +870,7 @@ Transfer :: struct { /** Handle of the device that this transfer will be submitted to */ dev_handle: ^Device_Handle, /** A bitwise OR combination of \ref libusb_transfer_flags. */ - flags: Transfer_Set, + flags: Transfer_Flag, /** Address of the endpoint where this transfer will be sent. */ endpoint: c.char, /** Type of the transfer from \ref libusb_transfer_type */ @@ -1076,7 +1076,7 @@ HOTPLUG_NO_FLAGS :: 0 * Wildcard matching for hotplug events */ HOTPLUG_MATCH_ANY :: -1 -Hotplug_Callback_Fn :: #type proc "c" ( +Hotplug_Callback :: #type proc "c" ( ctx: Context, device: ^Device, event: Hotplug_Event, @@ -1084,6 +1084,51 @@ Hotplug_Callback_Fn :: #type proc "c" ( ) -> c.int Callback_Handle :: distinct c.int +Transfer_Type :: enum c.int { + CONTROL = 0, + ISOCHRONOUS = 1, + BULK = 2, + INTERRUPT = 3, + STREAM = 4, +} + +/** \ingroup libusb_asyncio + * Transfer status codes */ +Transfer_Status :: enum c.int { + /** Transfer completed without error. Note that this does not indicate + * that the entire amount of requested data was transferred. */ + COMPLETED, + /** Transfer failed */ + ERROR, + /** Transfer timed out */ + TIMED_OUT, + /** Transfer was cancelled */ + CANCELLED, + /** For bulk/interrupt endpoints: halt condition detected (endpoint + * stalled). For control endpoints: control request not supported. */ + STALL, + /** Device was disconnected */ + NO_DEVICE, + /** Device sent more data than requested */ + OVERFLOW, + /* NB! Remember to update libusb_error_name() + when adding new status codes here. */ +} + +Poll_Fd :: struct { + /** Numeric file descriptor */ + fd: posix.FD, + /** Event flags to poll for from . POLLIN indicates that you + * should monitor this file descriptor for becoming ready to read from, + * and POLLOUT indicates that you should monitor this file descriptor for + * nonblocking write readiness. */ + events: posix.Poll_Event, +} + +Poll_FD_Added_CB :: #type proc "c" (fd: posix.FD, events: posix.Poll_Event, user_date: rawptr) + +Poll_FD_Removed_CB :: #type proc "c" (fd: posix.FD, user_data: rawptr) + @(default_calling_convention = "c", link_prefix = "libusb_") foreign lib { //----- Library initialization/deinitialization ---------------------------------- @@ -1158,7 +1203,36 @@ foreign lib { hotplug_deregister_callback :: proc(ctx: Context, hotplug_callback_handle: Callback_Handle) --- hotplug_get_user_data :: proc(ctx: Context, hotplug_callback_handle: Callback_Handle) -> rawptr --- - //TODO: Asynchronous device I/O + //----- Asynchronous device I/O ---------------------------------- + alloc_streams :: proc(dev_handle: Device_Handle, num_streams: u32, endpoints: [^]u8, num_endpoints: c.int) -> c.int --- + free_streams :: proc(dev_handle: Device_Handle, endpoints: [^]u8, num_endpoints: c.int) -> Error --- + dev_mem_alloc :: proc(dev_handle: Device_Handle, length: c.size_t) -> [^]u8 --- + dev_mem_free :: proc(dev_handle: Device_Handle, buffer: [^]u8, length: c.size_t) -> Error --- + alloc_transfer :: proc(iso_packets: c.int = 0) -> ^Transfer --- + free_transfer :: proc(transfer: ^Transfer) --- + submit_transfer :: proc(transfer: ^Transfer) -> Error --- + cancel_transfer :: proc(transfer: ^Transfer) -> Error --- + transfer_set_stream_id :: proc(transfer: ^Transfer, stream_id: u32) --- + transfer_get_stream_id :: proc(transfer: ^Transfer) -> u32 --- + + //----- Polling and timing ---------------------------------- + try_lock_events :: proc(ctx: Context) -> c.int --- + lock_events :: proc(ctx: Context) --- + unlock_events :: proc(ctx: Context) --- + event_handling_ok :: proc(ctx: Context) -> c.int --- + event_handler_active :: proc(ctx: Context) -> c.int --- + interrupt_event_handler :: proc(ctx: Context) --- + lock_event_waiters :: proc(ctx: Context) --- + unlock_event_waiters :: proc(ctx: Context) --- + wait_for_event :: proc(ctx: Context, tv: ^posix.timeval) -> c.int --- + handle_events_timeout_completed :: proc(ctx: Context, tv: ^posix.timeval, completed: ^c.int) -> Error --- + handle_events_completed :: proc(ctx: Context, completed: ^c.int) -> Error --- + handle_events_locked :: proc(ctx: Context, tv: ^posix.timeval) -> Error --- + pollfds_handle_timeouts :: proc(ctx: Context) -> c.int --- + get_next_timeout :: proc(ctx: Context, tv: ^posix.timeval) --- + set_poll_fd_notifiers :: proc(ctx: Context, added_cb: Poll_FD_Added_CB, removed_cb: Poll_FD_Removed_CB, user_data: rawptr) --- + get_pollfds :: proc(ctx: Context) -> ^[^]Poll_Fd --- + free_fds :: proc(pollfds: ^[^]Poll_Fd) --- //----- Synchronous device I/O ---------------------------------- control_transfer :: proc(dev_handle: ^Device_Handle, bmRequestType: u8, bRequest: u8, wValue: u16, wIndex: u16, data: [^]u8, wLength: u16, timeout: c.uint) -> Error ---