Skip to content

Commit

Permalink
Merge 043ce97 into 8818716
Browse files Browse the repository at this point in the history
  • Loading branch information
nomis52 committed Nov 24, 2014
2 parents 8818716 + 043ce97 commit d2e2340
Show file tree
Hide file tree
Showing 7 changed files with 1,580 additions and 1 deletion.
366 changes: 366 additions & 0 deletions plugins/usbdmx/LibUsbAdaptor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,366 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* LibUsbAdaptor.cpp
* The wrapper around libusb calls.
* Copyright (C) 2014 Simon Newton
*/

#include "plugins/usbdmx/LibUsbAdaptor.h"

#include <libusb.h>
#include <ola/Logging.h>
#include <string>

#include "plugins/usbdmx/LibUsbThread.h"

namespace ola {
namespace plugin {
namespace usbdmx {

using std::string;

namespace {

/**
* @brief A wrapper around libusb_get_string_descriptor_ascii.
*/
bool GetStringDescriptorAscii(libusb_device_handle *usb_handle,
uint8_t desc_index,
string *data) {
enum { buffer_size = 32 }; // static arrays FTW!
unsigned char buffer[buffer_size];
int r = libusb_get_string_descriptor_ascii(
usb_handle,
desc_index,
buffer,
buffer_size);

if (r <= 0) {
OLA_INFO << "libusb_get_string_descriptor_ascii failed: "
<< libusb_error_name(r);
return false;
}
data->assign(reinterpret_cast<char*>(buffer));
return true;
}

/**
* @brief A wrapper around libusb_open.
*/
bool Open(libusb_device *usb_device,
libusb_device_handle **usb_handle) {
int r = libusb_open(usb_device, usb_handle);
if (r) {
OLA_WARN << "Failed to open libusb device: " << usb_device << ": "
<< libusb_error_name(r);;
return false;
}
return true;
}

bool OpenHandleAndClaimInterface(libusb_device *usb_device,
int interface,
libusb_device_handle **usb_handle) {
if (!Open(usb_device, usb_handle)) {
return false;
}

int r = libusb_claim_interface(*usb_handle, 0);
if (r) {
OLA_WARN << "Failed to claim interface " << interface
<< " on device: " << usb_device << ": "
<< libusb_error_name(r);
libusb_close(*usb_handle);
return false;
}
return true;
}
} // namespace

// LibUsbAdaptor
// ----------------------------------------------------------------------------

bool LibUsbAdaptor::GetDeviceInfo(
struct libusb_device *usb_device,
const struct libusb_device_descriptor &device_descriptor,
DeviceInformation *device_info) {
// Since the calls on the handle are syncronous, we don't bother adding the
// handle to the thread.
libusb_device_handle *usb_handle;
if (!Open(usb_device, &usb_handle)) {
return false;
}

if (!GetStringDescriptorAscii(usb_handle, device_descriptor.iManufacturer,
&device_info->manufacturer)) {
OLA_INFO << "Failed to get manufacturer name";
}

if (!GetStringDescriptorAscii(usb_handle, device_descriptor.iProduct,
&device_info->product)) {
OLA_INFO << "Failed to get product name";
}

if (!GetStringDescriptorAscii(usb_handle, device_descriptor.iSerialNumber,
&device_info->serial)) {
OLA_WARN << "Failed to read serial number, the device probably doesn't "
<< "have one";
}

libusb_close(usb_handle);
return true;
}

bool LibUsbAdaptor::CheckManufacturer(const string &expected,
const string &actual) {
if (expected != actual) {
OLA_WARN << "Manufacturer mismatch: " << expected << " != " << actual;
return false;
}
return true;
}

bool LibUsbAdaptor::CheckProduct(const string &expected, const string &actual) {
if (expected != actual) {
OLA_WARN << "Product mismatch: " << expected << " != " << actual;
return false;
}
return true;
}

// BaseLibUsbAdaptor
// ----------------------------------------------------------------------------
libusb_device* BaseLibUsbAdaptor::RefDevice(libusb_device *dev) {
return libusb_ref_device(dev);
}

void BaseLibUsbAdaptor::UnrefDevice(libusb_device *dev) {
libusb_unref_device(dev);
}

int BaseLibUsbAdaptor::SetConfiguration(libusb_device_handle *dev,
int configuration) {
return libusb_set_configuration(dev, configuration);
}

int BaseLibUsbAdaptor::ClaimInterface(libusb_device_handle *dev,
int interface_number) {
return libusb_claim_interface(dev, interface_number);
}

int BaseLibUsbAdaptor::DetachKernelDriver(libusb_device_handle *dev,
int interface_number) {
if (libusb_kernel_driver_active(dev, interface_number)) {
return libusb_detach_kernel_driver(dev, interface_number);
} else {
return 0;
}
}

int BaseLibUsbAdaptor::GetActiveConfigDescriptor(
libusb_device *dev,
struct libusb_config_descriptor **config) {
return libusb_get_active_config_descriptor(dev, config);
}

int BaseLibUsbAdaptor::GetConfigDescriptor(
libusb_device *dev,
uint8_t config_index,
struct libusb_config_descriptor **config) {
return libusb_get_config_descriptor(dev, config_index, config);
}

void BaseLibUsbAdaptor::FreeConfigDescriptor(
struct libusb_config_descriptor *config) {
libusb_free_config_descriptor(config);
}

struct libusb_transfer* BaseLibUsbAdaptor::AllocTransfer(int iso_packets) {
return libusb_alloc_transfer(iso_packets);
}

void BaseLibUsbAdaptor::FreeTransfer(struct libusb_transfer *transfer) {
return libusb_free_transfer(transfer);
}

int BaseLibUsbAdaptor::SubmitTransfer(struct libusb_transfer *transfer) {
return libusb_submit_transfer(transfer);
}

int BaseLibUsbAdaptor::CancelTransfer(struct libusb_transfer *transfer) {
return libusb_cancel_transfer(transfer);
}

void BaseLibUsbAdaptor::FillControlSetup(unsigned char *buffer,
uint8_t bmRequestType,
uint8_t bRequest,
uint16_t wValue,
uint16_t wIndex,
uint16_t wLength) {
return libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue,
wIndex, wLength);
}

void BaseLibUsbAdaptor::FillControlTransfer(
struct libusb_transfer *transfer,
libusb_device_handle *dev_handle,
unsigned char *buffer,
libusb_transfer_cb_fn callback,
void *user_data,
unsigned int timeout) {
return libusb_fill_control_transfer(transfer, dev_handle, buffer, callback,
user_data, timeout);
}

void BaseLibUsbAdaptor::FillBulkTransfer(struct libusb_transfer *transfer,
libusb_device_handle *dev_handle,
unsigned char endpoint,
unsigned char *buffer,
int length,
libusb_transfer_cb_fn callback,
void *user_data,
unsigned int timeout) {
libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer,
length, callback, user_data, timeout);
}

void BaseLibUsbAdaptor::FillInterruptTransfer(struct libusb_transfer *transfer,
libusb_device_handle *dev_handle,
unsigned char endpoint,
unsigned char *buffer,
int length,
libusb_transfer_cb_fn callback,
void *user_data,
unsigned int timeout) {
libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, buffer,
length, callback, user_data, timeout);
}

int BaseLibUsbAdaptor::ControlTransfer(
libusb_device_handle *dev_handle,
uint8_t bmRequestType,
uint8_t bRequest,
uint16_t wValue,
uint16_t wIndex,
unsigned char *data,
uint16_t wLength,
unsigned int timeout) {
return libusb_control_transfer(dev_handle, bmRequestType, bRequest, wValue,
wIndex, data, wLength, timeout);
}

int BaseLibUsbAdaptor::BulkTransfer(struct libusb_device_handle *dev_handle,
unsigned char endpoint,
unsigned char *data,
int length,
int *transferred,
unsigned int timeout) {
return libusb_bulk_transfer(dev_handle, endpoint, data, length, transferred,
timeout);
}

int BaseLibUsbAdaptor::InterruptTransfer(libusb_device_handle *dev_handle,
unsigned char endpoint,
unsigned char *data,
int length,
int *actual_length,
unsigned int timeout) {
return libusb_interrupt_transfer(dev_handle, endpoint, data, length,
actual_length, timeout);
}


// SyncronousLibUsbAdaptor
// -----------------------------------------------------------------------------
bool SyncronousLibUsbAdaptor::OpenDevice(libusb_device *usb_device,
libusb_device_handle **usb_handle) {
return Open(usb_device, usb_handle);
}

bool SyncronousLibUsbAdaptor::OpenDeviceAndClaimInterface(
libusb_device *usb_device,
int interface,
libusb_device_handle **usb_handle) {
return OpenHandleAndClaimInterface(usb_device, interface, usb_handle);
}

void SyncronousLibUsbAdaptor::Close(libusb_device_handle *usb_handle) {
libusb_close(usb_handle);
}

// AsyncronousLibUsbAdaptor
// -----------------------------------------------------------------------------
bool AsyncronousLibUsbAdaptor::OpenDevice(libusb_device *usb_device,
libusb_device_handle **usb_handle) {
bool ok = Open(usb_device, usb_handle);
if (ok) {
m_thread->OpenHandle();
}
return ok;
}

bool AsyncronousLibUsbAdaptor::OpenDeviceAndClaimInterface(
libusb_device *usb_device,
int interface,
libusb_device_handle **usb_handle) {
bool ok = OpenHandleAndClaimInterface(usb_device, interface, usb_handle);
if (ok) {
m_thread->OpenHandle();
}
return ok;
}

void AsyncronousLibUsbAdaptor::Close(libusb_device_handle *handle) {
m_thread->CloseHandle(handle);
}

int AsyncronousLibUsbAdaptor::ControlTransfer(
OLA_UNUSED libusb_device_handle *dev_handle,
OLA_UNUSED uint8_t bmRequestType,
OLA_UNUSED uint8_t bRequest,
OLA_UNUSED uint16_t wValue,
OLA_UNUSED uint16_t wIndex,
OLA_UNUSED unsigned char *data,
OLA_UNUSED uint16_t wLength,
OLA_UNUSED unsigned int timeout) {
OLA_WARN << "libusb_control_transfer in an AsyncronousLibUsbAdaptor";
return LIBUSB_ERROR_NOT_SUPPORTED;
}

int AsyncronousLibUsbAdaptor::BulkTransfer(
OLA_UNUSED struct libusb_device_handle *dev_handle,
OLA_UNUSED unsigned char endpoint,
OLA_UNUSED unsigned char *data,
OLA_UNUSED int length,
OLA_UNUSED int *transferred,
OLA_UNUSED unsigned int timeout) {
OLA_WARN << "libusb_bulk_transfer in an AsyncronousLibUsbAdaptor";
return LIBUSB_ERROR_NOT_SUPPORTED;
}

int AsyncronousLibUsbAdaptor::InterruptTransfer(
OLA_UNUSED libusb_device_handle *dev_handle,
OLA_UNUSED unsigned char endpoint,
OLA_UNUSED unsigned char *data,
OLA_UNUSED int length,
OLA_UNUSED int *actual_length,
OLA_UNUSED unsigned int timeout) {
OLA_WARN << "libusb_interrupt_transfer in an AsyncronousLibUsbAdaptor";
return LIBUSB_ERROR_NOT_SUPPORTED;
}
} // namespace usbdmx
} // namespace plugin
} // namespace ola
Loading

0 comments on commit d2e2340

Please sign in to comment.