/******************************************************************************!
* \file device.cpp
* \author Sebastien Beaugrand
* \sa http://beaugrand.chez.com/
* \copyright CeCILL 2.1 Free Software license
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "device.h"
namespace USB {
/******************************************************************************!
* \fn Device
******************************************************************************/
Device::Device() :
mDev(NULL),
mTransfer(NULL),
mBuff(NULL)
{
}
/******************************************************************************!
* \fn ~Device
******************************************************************************/
Device::~Device()
{
this->close();
}
/******************************************************************************!
* \fn open
******************************************************************************/
void
Device::open(uint16_t vendor_id, uint16_t device_id)
{
int r = libusb_init(NULL);
this->status("libusb_init", r);
mDev = libusb_open_device_with_vid_pid(NULL, vendor_id, device_id);
this->status("libusb_open_device_with_vid_pid", (mDev == NULL) ? -1 : 0);
if (libusb_kernel_driver_active(mDev, 0)) {
r = libusb_detach_kernel_driver(mDev, 0);
this->status("libusb_detach_kernel_driver", r);
}
r = libusb_claim_interface(mDev, 0);
this->status("libusb_claim_interface", r);
}
/******************************************************************************!
* \fn close
******************************************************************************/
void
Device::close()
{
if (mTransfer != NULL) {
libusb_cancel_transfer(mTransfer);
libusb_free_transfer(mTransfer);
mTransfer = NULL;
}
if (mBuff != NULL) {
delete[] mBuff;
mBuff = NULL;
}
if (mDev != NULL) {
libusb_release_interface(mDev, 0);
libusb_close(mDev);
mDev = NULL;
libusb_exit(NULL);
}
}
/******************************************************************************!
* \fn submit
******************************************************************************/
void
Device::submit(UChar endpoint, int length,
void (* callback)(struct libusb_transfer* transfer))
{
mTransfer = libusb_alloc_transfer(0);
this->status("libusb_alloc_transfer", (mTransfer == NULL) ? -1 : 0);
mBuff = new UChar[length];
libusb_fill_interrupt_transfer(mTransfer, mDev, endpoint,
mBuff, length, callback, NULL, 0);
int r = libusb_submit_transfer(mTransfer);
this->status("libusb_submit_transfer", r);
}
/******************************************************************************!
* \fn submit
******************************************************************************/
void
Device::submit(struct libusb_transfer* transfer) const
{
libusb_submit_transfer(transfer);
}
/******************************************************************************!
* \fn status
******************************************************************************/
void
Device::status(const char* str, int code)
{
if (code < 0) {
fprintf(stderr, "error: %s (err=%d)\n", str, code);
this->close();
exit(EXIT_FAILURE);
} else {
fprintf(stderr, "%s: %d\n", str, code);
}
}
} // namespace USB