blob: 1f54998aeee422bfade66730257f9675cd799578 [file] [log] [blame]
Austin Schuh9b360e92013-03-27 04:47:04 +00001#include <libusb.h>
2#include <google/gflags.h>
3#include <glog/logging.h>
4#include <iostream>
5
6#include "libusb_wrap.h"
7
8LibUSB::LibUSB() {
9 CHECK_GE(libusb_init(&ctx_), 0) << ": LibUSB failed to initialize.";
10 libusb_set_debug(ctx_, 3);
11}
12
13LibUSBDeviceHandle *LibUSB::FindDeviceWithVIDPID(int vid, int pid) {
14 int r;
15 libusb_device **devs;
16 libusb_device_handle *dev_handle;
17
18 ssize_t cnt;
19 cnt = libusb_get_device_list(ctx_, &devs);
20 if(cnt < 0) {
21 LOG(ERROR) << "Get Device Error";
22 return NULL;
23 }
24 LOG(INFO) << cnt << " Devices in list.";
25 bool found = false;
26 for (int i = 0; i < cnt; ++i) {
27 struct libusb_device_descriptor desc;
28 r = libusb_get_device_descriptor(devs[i], &desc);
29 CHECK_GE(r, 0) << ": Couldn't get device descriptor, error " << r;
30 if (desc.idVendor == vid && desc.idProduct == pid) {
31 LOG(INFO) << "Device " << (int)libusb_get_bus_number(devs[i]) << ":"
32 << (int)libusb_get_device_address(devs[i]) << " matches";
33 r = libusb_open(devs[i], &dev_handle);
34 if (libusb_kernel_driver_active(dev_handle, 0) == 1) {
35 LOG(INFO) << "Device already in use, trying next one.";
36 continue;
37 }
38 if (r < 0) {
39 LOG(WARNING) << "Failed to open device.";
40 } else {
41 found = true;
42 break;
43 }
44 }
45 }
46 libusb_free_device_list(devs, 1);
47 if (!found) {
48 LOG(ERROR) << "Couldn't open device.";
49 return NULL;
50 }
51
52 if (libusb_kernel_driver_active(dev_handle, 0) == 1) {
53 LOG(INFO) << "Kernel Driver Active";
54 if (libusb_detach_kernel_driver(dev_handle, 0) == 0) {
55 LOG(INFO) << "Kernel Driver Detached!";
56 } else {
57 LOG(ERROR) << "Couldn't detach kernel driver.";
58 return NULL;
59 }
60 }
61
62 r = libusb_claim_interface(dev_handle, 0);
63 if (r < 0) {
64 LOG(ERROR) << "Cannot Claim Interface";
65 return 0;
66 }
67 LOG(INFO) << "Claimed Interface";
68 return new LibUSBDeviceHandle(dev_handle);
69}
70
71LibUSB::~LibUSB() {
72 libusb_exit(ctx_);
73}
74
75LibUSBDeviceHandle::LibUSBDeviceHandle(
76 libusb_device_handle *dev_handle) : dev_handle_(dev_handle) { }
77
78LibUSBDeviceHandle::~LibUSBDeviceHandle() {
79 int r;
80 r = libusb_release_interface(dev_handle_, 0);
81 if (r != 0) {
82 LOG(FATAL) << "Cannot Release Interface";
83 }
84 LOG(INFO) << "Released Interface";
85
86 libusb_close(dev_handle_);
87}
88
89int LibUSBDeviceHandle::interrupt_transfer(
90 unsigned char endpoint, unsigned char *data, int length,
91 int *transferred, unsigned int timeout) {
92 return libusb_interrupt_transfer(dev_handle_, endpoint, data, length,
93 transferred, timeout);
94}
95
96int LibUSBDeviceHandle::bulk_transfer(
97 unsigned char endpoint, unsigned char *data,
98 int length, int *transferred, unsigned int timeout) {
99 return libusb_bulk_transfer(dev_handle_, endpoint, data, length,
100 transferred, timeout);
101}