blob: 13a5e3107909e26876f142cb61fad6c0b7f524df [file] [log] [blame]
Austin Schuh9b360e92013-03-27 04:47:04 +00001#include "libusb_wrap.h"
2
Brian Silverman798c7782013-03-28 16:48:02 -07003#include <iostream>
4
5#include "aos/common/logging/logging.h"
6
Austin Schuh9b360e92013-03-27 04:47:04 +00007LibUSB::LibUSB() {
Brian Silverman798c7782013-03-28 16:48:02 -07008 if (libusb_init(&ctx_) < 0) {
9 LOG(FATAL, "libusb_init(%p) failed\n", &ctx_);
10 }
Austin Schuh9b360e92013-03-27 04:47:04 +000011 libusb_set_debug(ctx_, 3);
12}
13
14LibUSBDeviceHandle *LibUSB::FindDeviceWithVIDPID(int vid, int pid) {
15 int r;
16 libusb_device **devs;
17 libusb_device_handle *dev_handle;
18
19 ssize_t cnt;
20 cnt = libusb_get_device_list(ctx_, &devs);
Brian Silverman798c7782013-03-28 16:48:02 -070021 if (cnt < 0) {
22 LOG(ERROR, "Get Device Error\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000023 return NULL;
24 }
Brian Silverman798c7782013-03-28 16:48:02 -070025 LOG(INFO, "%d Devices in list.\n", cnt);
Austin Schuh9b360e92013-03-27 04:47:04 +000026 bool found = false;
27 for (int i = 0; i < cnt; ++i) {
28 struct libusb_device_descriptor desc;
29 r = libusb_get_device_descriptor(devs[i], &desc);
Brian Silverman798c7782013-03-28 16:48:02 -070030 if (r < 0) {
31 LOG(FATAL, "lib_usb_get_device_descriptor(%p, %p) failed\n",
32 devs[i], &desc);
33 }
Austin Schuh9b360e92013-03-27 04:47:04 +000034 if (desc.idVendor == vid && desc.idProduct == pid) {
Brian Silverman798c7782013-03-28 16:48:02 -070035 LOG(INFO, "Device %d:%d matches\n",
36 (int)libusb_get_bus_number(devs[i]),
37 (int)libusb_get_device_address(devs[i]));
Austin Schuh9b360e92013-03-27 04:47:04 +000038 r = libusb_open(devs[i], &dev_handle);
39 if (libusb_kernel_driver_active(dev_handle, 0) == 1) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070040 LOG(INFO, "Device already in use, trying next one.\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000041 continue;
42 }
43 if (r < 0) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070044 LOG(WARNING, "Failed to open device.\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000045 } else {
46 found = true;
47 break;
48 }
49 }
50 }
51 libusb_free_device_list(devs, 1);
52 if (!found) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070053 LOG(ERROR, "Couldn't open device.\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000054 return NULL;
55 }
56
57 if (libusb_kernel_driver_active(dev_handle, 0) == 1) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070058 LOG(INFO, "Kernel Driver Active\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000059 if (libusb_detach_kernel_driver(dev_handle, 0) == 0) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070060 LOG(INFO, "Kernel Driver Detached!\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000061 } else {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070062 LOG(ERROR, "Couldn't detach kernel driver.\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000063 return NULL;
64 }
65 }
66
67 r = libusb_claim_interface(dev_handle, 0);
68 if (r < 0) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070069 LOG(ERROR, "Cannot Claim Interface\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000070 return 0;
71 }
Brian Silvermana4f9ef22013-03-30 14:31:16 -070072 LOG(INFO, "Claimed Interface\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000073 return new LibUSBDeviceHandle(dev_handle);
74}
75
76LibUSB::~LibUSB() {
77 libusb_exit(ctx_);
78}
79
80LibUSBDeviceHandle::LibUSBDeviceHandle(
81 libusb_device_handle *dev_handle) : dev_handle_(dev_handle) { }
82
83LibUSBDeviceHandle::~LibUSBDeviceHandle() {
Brian Silverman2e0dcfd2013-03-30 22:44:40 -070084 int r = libusb_release_interface(dev_handle_, 0);
Austin Schuh9b360e92013-03-27 04:47:04 +000085 if (r != 0) {
Brian Silvermana4f9ef22013-03-30 14:31:16 -070086 LOG(FATAL, "Cannot Release Interface\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000087 }
Brian Silvermana4f9ef22013-03-30 14:31:16 -070088 LOG(INFO, "Released Interface\n");
Austin Schuh9b360e92013-03-27 04:47:04 +000089
90 libusb_close(dev_handle_);
91}
92
93int LibUSBDeviceHandle::interrupt_transfer(
94 unsigned char endpoint, unsigned char *data, int length,
95 int *transferred, unsigned int timeout) {
96 return libusb_interrupt_transfer(dev_handle_, endpoint, data, length,
97 transferred, timeout);
98}
99
100int LibUSBDeviceHandle::bulk_transfer(
101 unsigned char endpoint, unsigned char *data,
102 int length, int *transferred, unsigned int timeout) {
103 return libusb_bulk_transfer(dev_handle_, endpoint, data, length,
104 transferred, timeout);
105}