2010-08-26 19:21:50 +00:00
|
|
|
//
|
2015-03-27 21:20:27 +00:00
|
|
|
// Copyright 2010-2015 Ettus Research LLC
|
2010-08-26 19:21:50 +00:00
|
|
|
//
|
|
|
|
|
// 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 3 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 General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "libusb1_base.hpp"
|
2011-02-24 22:54:24 +00:00
|
|
|
#include <uhd/exception.hpp>
|
2011-10-24 21:42:46 +00:00
|
|
|
#include <uhd/utils/msg.hpp>
|
|
|
|
|
#include <uhd/utils/log.hpp>
|
2013-11-08 23:30:03 +00:00
|
|
|
#include <uhd/utils/tasks.hpp>
|
2010-09-26 04:07:15 +00:00
|
|
|
#include <uhd/types/dict.hpp>
|
2014-02-11 20:25:06 +00:00
|
|
|
#include <uhd/types/serial.hpp>
|
2010-09-26 04:07:15 +00:00
|
|
|
#include <boost/weak_ptr.hpp>
|
2011-10-24 21:42:46 +00:00
|
|
|
#include <boost/thread/mutex.hpp>
|
2010-09-26 04:07:15 +00:00
|
|
|
#include <boost/foreach.hpp>
|
2013-11-08 23:30:03 +00:00
|
|
|
#include <boost/bind.hpp>
|
2013-07-17 17:23:46 +00:00
|
|
|
#include <cstdlib>
|
2010-08-26 19:21:50 +00:00
|
|
|
#include <iostream>
|
|
|
|
|
|
2010-09-30 18:32:21 +00:00
|
|
|
using namespace uhd;
|
2010-08-26 19:21:50 +00:00
|
|
|
using namespace uhd::transport;
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* libusb session
|
|
|
|
|
**********************************************************************/
|
2014-08-13 15:44:31 +00:00
|
|
|
libusb::session::~session(void) {
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
class libusb_session_impl : public libusb::session{
|
|
|
|
|
public:
|
|
|
|
|
libusb_session_impl(void){
|
|
|
|
|
UHD_ASSERT_THROW(libusb_init(&_context) == 0);
|
|
|
|
|
libusb_set_debug(_context, debug_level);
|
2013-11-08 23:30:03 +00:00
|
|
|
task_handler = task::make(boost::bind(&libusb_session_impl::libusb_event_handler_task, this, _context));
|
2010-09-26 04:07:15 +00:00
|
|
|
}
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
virtual ~libusb_session_impl(void);
|
2010-09-26 04:07:15 +00:00
|
|
|
|
|
|
|
|
libusb_context *get_context(void) const{
|
|
|
|
|
return _context;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
libusb_context *_context;
|
2013-11-08 23:30:03 +00:00
|
|
|
task::sptr task_handler;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Task to handle libusb events. There should only be one thread per libusb_context handling events.
|
|
|
|
|
* Using more than one thread can result in excessive CPU usage in kernel space (presumably from locking/waiting).
|
|
|
|
|
* The libusb documentation says it is safe, which it is, but it neglects to state the cost in CPU usage.
|
|
|
|
|
* Just don't do it!
|
|
|
|
|
*/
|
|
|
|
|
UHD_INLINE void libusb_event_handler_task(libusb_context *context)
|
|
|
|
|
{
|
|
|
|
|
timeval tv;
|
|
|
|
|
tv.tv_sec = 0;
|
|
|
|
|
tv.tv_usec = 100000;
|
2015-07-29 23:55:38 +00:00
|
|
|
int ret = libusb_handle_events_timeout(context, &tv);
|
|
|
|
|
switch (ret)
|
|
|
|
|
{
|
|
|
|
|
case LIBUSB_SUCCESS:
|
|
|
|
|
case LIBUSB_ERROR_TIMEOUT:
|
|
|
|
|
break;
|
|
|
|
|
case LIBUSB_ERROR_NO_DEVICE:
|
|
|
|
|
throw uhd::io_error(libusb_strerror(LIBUSB_ERROR_NO_DEVICE));
|
|
|
|
|
default:
|
|
|
|
|
UHD_MSG(error) << __FUNCTION__ << ": " << libusb_strerror((libusb_error)ret) << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-11-08 23:30:03 +00:00
|
|
|
}
|
2010-09-26 04:07:15 +00:00
|
|
|
};
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
libusb_session_impl::~libusb_session_impl(void){
|
|
|
|
|
task_handler.reset();
|
|
|
|
|
libusb_exit(_context);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::session::sptr libusb::session::get_global_session(void){
|
|
|
|
|
static boost::weak_ptr<session> global_session;
|
|
|
|
|
|
|
|
|
|
//not expired -> get existing session
|
|
|
|
|
if (not global_session.expired()) return global_session.lock();
|
|
|
|
|
|
|
|
|
|
//create a new global session
|
|
|
|
|
sptr new_global_session(new libusb_session_impl());
|
|
|
|
|
global_session = new_global_session;
|
2013-07-17 17:23:46 +00:00
|
|
|
|
|
|
|
|
//set logging if envvar is set
|
|
|
|
|
const char *level_string = getenv("LIBUSB_DEBUG_LEVEL");
|
|
|
|
|
if (level_string != NULL)
|
|
|
|
|
{
|
|
|
|
|
const int level = int(level_string[0] - '0'); //easy conversion to integer
|
|
|
|
|
if (level >= 0 and level <= 3) libusb_set_debug(new_global_session->get_context(), level);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
return new_global_session;
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* libusb device
|
|
|
|
|
**********************************************************************/
|
2014-08-13 15:44:31 +00:00
|
|
|
libusb::device::~device(void) {
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
class libusb_device_impl : public libusb::device{
|
|
|
|
|
public:
|
|
|
|
|
libusb_device_impl(libusb_device *dev){
|
|
|
|
|
_session = libusb::session::get_global_session();
|
|
|
|
|
_dev = dev;
|
|
|
|
|
}
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
virtual ~libusb_device_impl(void);
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb_device *get(void) const{
|
|
|
|
|
return _dev;
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
private:
|
|
|
|
|
libusb::session::sptr _session; //always keep a reference to session
|
|
|
|
|
libusb_device *_dev;
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
libusb_device_impl::~libusb_device_impl(void){
|
|
|
|
|
libusb_unref_device(this->get());
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* libusb device list
|
|
|
|
|
**********************************************************************/
|
2014-08-13 15:44:31 +00:00
|
|
|
libusb::device_list::~device_list(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
class libusb_device_list_impl : public libusb::device_list{
|
|
|
|
|
public:
|
|
|
|
|
libusb_device_list_impl(void){
|
|
|
|
|
libusb::session::sptr sess = libusb::session::get_global_session();
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
//allocate a new list of devices
|
|
|
|
|
libusb_device** dev_list;
|
|
|
|
|
ssize_t ret = libusb_get_device_list(sess->get_context(), &dev_list);
|
2011-02-25 00:35:29 +00:00
|
|
|
if (ret < 0) throw uhd::os_error("cannot enumerate usb devices");
|
2010-09-26 04:07:15 +00:00
|
|
|
|
|
|
|
|
//fill the vector of device references
|
|
|
|
|
for (size_t i = 0; i < size_t(ret); i++) _devs.push_back(
|
|
|
|
|
libusb::device::sptr(new libusb_device_impl(dev_list[i]))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
//free the device list but dont unref (done in ~device)
|
|
|
|
|
libusb_free_device_list(dev_list, false/*dont unref*/);
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
virtual ~libusb_device_list_impl(void);
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
size_t size(void) const{
|
|
|
|
|
return _devs.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
libusb::device::sptr at(size_t i) const{
|
|
|
|
|
return _devs.at(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
std::vector<libusb::device::sptr> _devs;
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
libusb_device_list_impl::~libusb_device_list_impl(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::device_list::sptr libusb::device_list::make(void){
|
|
|
|
|
return sptr(new libusb_device_list_impl());
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* libusb device descriptor
|
|
|
|
|
**********************************************************************/
|
2014-08-13 15:44:31 +00:00
|
|
|
libusb::device_descriptor::~device_descriptor(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
class libusb_device_descriptor_impl : public libusb::device_descriptor{
|
|
|
|
|
public:
|
|
|
|
|
libusb_device_descriptor_impl(libusb::device::sptr dev){
|
|
|
|
|
_dev = dev;
|
|
|
|
|
UHD_ASSERT_THROW(libusb_get_device_descriptor(_dev->get(), &_desc) == 0);
|
|
|
|
|
}
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
virtual ~libusb_device_descriptor_impl(void);
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
const libusb_device_descriptor &get(void) const{
|
|
|
|
|
return _desc;
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
2010-09-26 04:07:15 +00:00
|
|
|
|
2013-07-15 22:57:53 +00:00
|
|
|
std::string get_ascii_property(const std::string &what) const
|
|
|
|
|
{
|
2016-10-31 21:30:52 +00:00
|
|
|
uint8_t off = 0;
|
2013-07-15 22:57:53 +00:00
|
|
|
if (what == "serial") off = this->get().iSerialNumber;
|
|
|
|
|
if (what == "product") off = this->get().iProduct;
|
|
|
|
|
if (what == "manufacturer") off = this->get().iManufacturer;
|
|
|
|
|
if (off == 0) return "";
|
2010-09-26 04:07:15 +00:00
|
|
|
|
|
|
|
|
libusb::device_handle::sptr handle(
|
|
|
|
|
libusb::device_handle::get_cached_handle(_dev)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
unsigned char buff[512];
|
2016-06-24 21:21:45 +00:00
|
|
|
int ret = libusb_get_string_descriptor_ascii(
|
|
|
|
|
handle->get(), off, buff, int(sizeof(buff))
|
2010-09-26 04:07:15 +00:00
|
|
|
);
|
|
|
|
|
if (ret < 0) return ""; //on error, just return empty string
|
|
|
|
|
|
2016-06-24 21:21:45 +00:00
|
|
|
std::string string_descriptor((char *)buff, size_t(ret));
|
2014-02-11 20:25:06 +00:00
|
|
|
byte_vector_t string_vec(string_descriptor.begin(), string_descriptor.end());
|
|
|
|
|
std::string out;
|
2016-10-31 21:30:52 +00:00
|
|
|
BOOST_FOREACH(uint8_t byte, string_vec){
|
2014-02-11 20:25:06 +00:00
|
|
|
if (byte < 32 or byte > 127) return out;
|
|
|
|
|
out += byte;
|
|
|
|
|
}
|
|
|
|
|
return out;
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
2010-09-26 04:07:15 +00:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
libusb::device::sptr _dev; //always keep a reference to device
|
|
|
|
|
libusb_device_descriptor _desc;
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
libusb_device_descriptor_impl::~libusb_device_descriptor_impl(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::device_descriptor::sptr libusb::device_descriptor::make(device::sptr dev){
|
|
|
|
|
return sptr(new libusb_device_descriptor_impl(dev));
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* libusb device handle
|
|
|
|
|
**********************************************************************/
|
2014-08-13 15:44:31 +00:00
|
|
|
libusb::device_handle::~device_handle(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
class libusb_device_handle_impl : public libusb::device_handle{
|
|
|
|
|
public:
|
|
|
|
|
libusb_device_handle_impl(libusb::device::sptr dev){
|
|
|
|
|
_dev = dev;
|
|
|
|
|
UHD_ASSERT_THROW(libusb_open(_dev->get(), &_handle) == 0);
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
virtual ~libusb_device_handle_impl(void);
|
2010-09-26 04:07:15 +00:00
|
|
|
|
|
|
|
|
libusb_device_handle *get(void) const{
|
|
|
|
|
return _handle;
|
|
|
|
|
}
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
void claim_interface(int interface){
|
|
|
|
|
UHD_ASSERT_THROW(libusb_claim_interface(this->get(), interface) == 0);
|
|
|
|
|
_claimed.push_back(interface);
|
|
|
|
|
}
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2015-07-27 22:16:49 +00:00
|
|
|
void clear_endpoints(unsigned char recv_endpoint, unsigned char send_endpoint)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
ret = libusb_clear_halt(this->get(), recv_endpoint | 0x80);
|
|
|
|
|
UHD_LOG << "usb device handle: recv endpoint clear: " << libusb_error_name(ret) << std::endl;
|
|
|
|
|
ret = libusb_clear_halt(this->get(), send_endpoint | 0x00);
|
|
|
|
|
UHD_LOG << "usb device handle: send endpoint clear: " << libusb_error_name(ret) << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void reset_device(void)
|
|
|
|
|
{
|
|
|
|
|
int ret = libusb_reset_device(this->get());
|
|
|
|
|
UHD_LOG << "usb device handle: dev Reset: " << libusb_error_name(ret) << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
private:
|
|
|
|
|
libusb::device::sptr _dev; //always keep a reference to device
|
|
|
|
|
libusb_device_handle *_handle;
|
|
|
|
|
std::vector<int> _claimed;
|
|
|
|
|
};
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
libusb_device_handle_impl::~libusb_device_handle_impl(void){
|
|
|
|
|
//release all claimed interfaces
|
|
|
|
|
for (size_t i = 0; i < _claimed.size(); i++){
|
|
|
|
|
libusb_release_interface(this->get(), _claimed[i]);
|
|
|
|
|
}
|
|
|
|
|
libusb_close(_handle);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::device_handle::sptr libusb::device_handle::get_cached_handle(device::sptr dev){
|
|
|
|
|
static uhd::dict<libusb_device *, boost::weak_ptr<device_handle> > handles;
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2011-10-24 21:42:46 +00:00
|
|
|
//lock for atomic access to static table above
|
|
|
|
|
static boost::mutex mutex;
|
|
|
|
|
boost::mutex::scoped_lock lock(mutex);
|
|
|
|
|
|
2010-10-01 18:54:22 +00:00
|
|
|
//not expired -> get existing handle
|
2010-09-26 04:07:15 +00:00
|
|
|
if (handles.has_key(dev->get()) and not handles[dev->get()].expired()){
|
|
|
|
|
return handles[dev->get()].lock();
|
|
|
|
|
}
|
2010-08-26 19:21:50 +00:00
|
|
|
|
2010-10-01 18:54:22 +00:00
|
|
|
//create a new cached handle
|
|
|
|
|
try{
|
|
|
|
|
sptr new_handle(new libusb_device_handle_impl(dev));
|
|
|
|
|
handles[dev->get()] = new_handle;
|
|
|
|
|
return new_handle;
|
|
|
|
|
}
|
2011-07-09 00:55:49 +00:00
|
|
|
catch(const uhd::exception &){
|
2011-10-24 21:42:46 +00:00
|
|
|
#ifdef UHD_PLATFORM_LINUX
|
|
|
|
|
UHD_MSG(error) <<
|
|
|
|
|
"USB open failed: insufficient permissions.\n"
|
|
|
|
|
"See the application notes for your device.\n"
|
|
|
|
|
<< std::endl;
|
|
|
|
|
#else
|
|
|
|
|
UHD_LOG << "USB open failed: device already claimed." << std::endl;
|
|
|
|
|
#endif
|
2011-02-25 00:35:29 +00:00
|
|
|
throw;
|
2010-10-01 18:54:22 +00:00
|
|
|
}
|
2010-09-26 04:07:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
|
* libusb special handle
|
|
|
|
|
**********************************************************************/
|
2014-08-13 15:44:31 +00:00
|
|
|
libusb::special_handle::~special_handle(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
class libusb_special_handle_impl : public libusb::special_handle{
|
|
|
|
|
public:
|
|
|
|
|
libusb_special_handle_impl(libusb::device::sptr dev){
|
|
|
|
|
_dev = dev;
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
virtual ~libusb_special_handle_impl(void);
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::device::sptr get_device(void) const{
|
|
|
|
|
return _dev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string get_serial(void) const{
|
2013-07-15 22:57:53 +00:00
|
|
|
return libusb::device_descriptor::make(this->get_device())->get_ascii_property("serial");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string get_manufacturer() const{
|
|
|
|
|
return libusb::device_descriptor::make(this->get_device())->get_ascii_property("manufacturer");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string get_product() const{
|
|
|
|
|
return libusb::device_descriptor::make(this->get_device())->get_ascii_property("product");
|
2010-09-26 04:07:15 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-31 21:30:52 +00:00
|
|
|
uint16_t get_vendor_id(void) const{
|
2010-09-26 04:07:15 +00:00
|
|
|
return libusb::device_descriptor::make(this->get_device())->get().idVendor;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-31 21:30:52 +00:00
|
|
|
uint16_t get_product_id(void) const{
|
2010-09-26 04:07:15 +00:00
|
|
|
return libusb::device_descriptor::make(this->get_device())->get().idProduct;
|
|
|
|
|
}
|
|
|
|
|
|
2013-11-15 17:50:07 +00:00
|
|
|
bool firmware_loaded() {
|
2015-03-27 21:20:27 +00:00
|
|
|
return (get_manufacturer() == "Ettus Research LLC") or
|
2015-04-02 19:42:45 +00:00
|
|
|
(get_manufacturer() == "National Instruments Corp.") or
|
2015-03-27 21:20:27 +00:00
|
|
|
(get_manufacturer() == "Free Software Folks");
|
2013-11-15 17:50:07 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
private:
|
|
|
|
|
libusb::device::sptr _dev; //always keep a reference to device
|
|
|
|
|
};
|
|
|
|
|
|
2016-06-24 20:48:32 +00:00
|
|
|
libusb_special_handle_impl::~libusb_special_handle_impl(void){
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::special_handle::sptr libusb::special_handle::make(device::sptr dev){
|
|
|
|
|
return sptr(new libusb_special_handle_impl(dev));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
|
* list device handles implementations
|
|
|
|
|
**********************************************************************/
|
2016-06-24 20:48:32 +00:00
|
|
|
usb_device_handle::~usb_device_handle(void) {
|
|
|
|
|
/* NOP */
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-26 04:07:15 +00:00
|
|
|
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(
|
2016-10-31 21:30:52 +00:00
|
|
|
uint16_t vid, uint16_t pid
|
2010-09-26 04:07:15 +00:00
|
|
|
){
|
2014-12-18 23:37:20 +00:00
|
|
|
return usb_device_handle::get_device_list(std::vector<usb_device_handle::vid_pid_pair_t>(1,usb_device_handle::vid_pid_pair_t(vid,pid)));
|
|
|
|
|
}
|
2010-09-26 04:07:15 +00:00
|
|
|
|
2014-12-18 23:37:20 +00:00
|
|
|
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list)
|
|
|
|
|
{
|
|
|
|
|
std::vector<usb_device_handle::sptr> handles;
|
2010-09-26 04:07:15 +00:00
|
|
|
libusb::device_list::sptr dev_list = libusb::device_list::make();
|
2014-12-18 23:37:20 +00:00
|
|
|
for(size_t iter = 0; iter < vid_pid_pair_list.size(); ++iter)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < dev_list->size(); i++){
|
|
|
|
|
usb_device_handle::sptr handle = libusb::special_handle::make(dev_list->at(i));
|
|
|
|
|
if (handle->get_vendor_id() == vid_pid_pair_list[iter].first and handle->get_product_id() == vid_pid_pair_list[iter].second){
|
|
|
|
|
handles.push_back(handle);
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-09-26 04:07:15 +00:00
|
|
|
}
|
|
|
|
|
return handles;
|
2010-08-26 19:21:50 +00:00
|
|
|
}
|