Implemented async USB write

This commit is contained in:
Ingo Ruhnke 2011-03-23 17:58:57 +01:00
parent 15ebae464b
commit b0daa43fd0
5 changed files with 63 additions and 25 deletions

2
TODO
View file

@ -79,6 +79,8 @@ Checklist
* check that --quit works, currently broken
* search for "#ifdef FIXME"
Stuff to do before 0.7.4 release:
=================================

View file

@ -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)
{

View file

@ -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&);

View file

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

View file

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