Implemented async USB write
This commit is contained in:
parent
15ebae464b
commit
b0daa43fd0
5 changed files with 63 additions and 25 deletions
2
TODO
2
TODO
|
@ -79,6 +79,8 @@ Checklist
|
|||
|
||||
* check that --quit works, currently broken
|
||||
|
||||
* search for "#ifdef FIXME"
|
||||
|
||||
|
||||
Stuff to do before 0.7.4 release:
|
||||
=================================
|
||||
|
|
|
@ -111,8 +111,6 @@ USBController::usb_submit_read(int endpoint, int len)
|
|||
{
|
||||
assert(!m_read_transfer);
|
||||
|
||||
//log_debug("ep: " << endpoint << " len: " << len);
|
||||
|
||||
m_read_transfer = libusb_alloc_transfer(0);
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * len));
|
||||
|
@ -130,6 +128,40 @@ USBController::usb_submit_read(int endpoint, int len)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_write(int endpoint, uint8_t* data_in, int len)
|
||||
{
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER;
|
||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||
|
||||
// copy data into a newly allocated buffer
|
||||
uint8_t* data = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * len));
|
||||
memcpy(data, data_in, len);
|
||||
|
||||
libusb_fill_interrupt_transfer(transfer, m_handle,
|
||||
endpoint | LIBUSB_ENDPOINT_OUT,
|
||||
data, len,
|
||||
&USBController::on_write_data_wrap, this,
|
||||
0); // timeout
|
||||
|
||||
int ret;
|
||||
ret = libusb_submit_transfer(transfer);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_submit_transfer(): " << usb_strerror(ret));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
USBController::on_write_data(libusb_transfer* transfer)
|
||||
{
|
||||
if (transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||
{
|
||||
log_error("USB write failure: " << transfer->length << ": " << usb_transfer_strerror(transfer->status));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_cancel_read()
|
||||
{
|
||||
|
@ -182,27 +214,6 @@ USBController::usb_release_interface(int ifnum)
|
|||
libusb_release_interface(m_handle, ifnum);
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_write(int endpoint, uint8_t* data, int len)
|
||||
{
|
||||
log_error("not implemented");
|
||||
#ifdef FIXME
|
||||
int transferred = 0;
|
||||
int ret = libusb_interrupt_transfer(m_handle, LIBUSB_ENDPOINT_OUT | endpoint,
|
||||
data, len, &transferred, 0);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_interrupt_transfer() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
if (transferred != len)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_interrupt_transfer() short write: "
|
||||
<< len << " - " << transferred);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
USBController::usb_find_ep(int direction, uint8_t if_class, uint8_t if_subclass, uint8_t if_protocol)
|
||||
{
|
||||
|
|
|
@ -47,20 +47,29 @@ public:
|
|||
|
||||
virtual bool parse(uint8_t* data, int len, XboxGenericMsg* msg_out) =0;
|
||||
|
||||
int usb_find_ep(int direction, uint8_t if_class, uint8_t if_subclass, uint8_t if_protocol);
|
||||
|
||||
void usb_claim_interface(int ifnum, bool try_detach);
|
||||
void usb_release_interface(int ifnum);
|
||||
void usb_write(int endpoint, uint8_t* data, int len);
|
||||
int usb_find_ep(int direction, uint8_t if_class, uint8_t if_subclass, uint8_t if_protocol);
|
||||
|
||||
void usb_submit_read(int endpoint, int len);
|
||||
void usb_cancel_read();
|
||||
|
||||
void usb_write(int endpoint, uint8_t* data, int len);
|
||||
|
||||
private:
|
||||
void on_read_data(libusb_transfer *transfer);
|
||||
static void on_read_data_wrap(libusb_transfer *transfer)
|
||||
{
|
||||
static_cast<USBController*>(transfer->user_data)->on_read_data(transfer);
|
||||
}
|
||||
|
||||
void on_write_data(libusb_transfer *transfer);
|
||||
static void on_write_data_wrap(libusb_transfer *transfer)
|
||||
{
|
||||
static_cast<USBController*>(transfer->user_data)->on_write_data(transfer);
|
||||
}
|
||||
|
||||
private:
|
||||
USBController(const USBController&);
|
||||
USBController& operator=(const USBController&);
|
||||
|
|
|
@ -71,6 +71,21 @@ const char* usb_strerror(int err)
|
|||
}
|
||||
}
|
||||
|
||||
const char* usb_transfer_strerror(libusb_transfer_status err)
|
||||
{
|
||||
switch(err)
|
||||
{
|
||||
case LIBUSB_TRANSFER_COMPLETED: return "LIBUSB_TRANSFER_COMPLETED";
|
||||
case LIBUSB_TRANSFER_ERROR: return "LIBUSB_TRANSFER_ERROR";
|
||||
case LIBUSB_TRANSFER_TIMED_OUT: return "LIBUSB_TRANSFER_TIMED_OUT";
|
||||
case LIBUSB_TRANSFER_CANCELLED: return "LIBUSB_TRANSFER_CANCELLED";
|
||||
case LIBUSB_TRANSFER_STALL: return "LIBUSB_TRANSFER_STALL";
|
||||
case LIBUSB_TRANSFER_NO_DEVICE: return "LIBUSB_TRANSFER_NO_DEVICE";
|
||||
case LIBUSB_TRANSFER_OVERFLOW: return "LIBUSB_TRANSFER_OVERFLOW";
|
||||
default: return "<unknown libusb transfer error code>";
|
||||
}
|
||||
}
|
||||
|
||||
libusb_device* usb_find_device_by_path(uint8_t busnum, uint8_t devnum)
|
||||
{
|
||||
libusb_device* ret_device = 0;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
int usb_claim_n_detach_interface(libusb_device_handle* handle, int interface, bool try_detach);
|
||||
const char* usb_strerror(int err);
|
||||
const char* usb_transfer_strerror(libusb_transfer_status err);
|
||||
libusb_device* usb_find_device_by_path(uint8_t busnum, uint8_t devnum);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue