aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport/libusb1_base.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport/libusb1_base.cpp')
-rw-r--r--host/lib/transport/libusb1_base.cpp56
1 files changed, 51 insertions, 5 deletions
diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index d4ec874f1..8bd0f4354 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2013 Ettus Research LLC
//
// 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
@@ -19,10 +19,13 @@
#include <uhd/exception.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/utils/log.hpp>
+#include <uhd/utils/tasks.hpp>
#include <uhd/types/dict.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <cstdlib>
#include <iostream>
using namespace uhd;
@@ -36,9 +39,11 @@ public:
libusb_session_impl(void){
UHD_ASSERT_THROW(libusb_init(&_context) == 0);
libusb_set_debug(_context, debug_level);
+ task_handler = task::make(boost::bind(&libusb_session_impl::libusb_event_handler_task, this, _context));
}
~libusb_session_impl(void){
+ task_handler.reset();
libusb_exit(_context);
}
@@ -48,6 +53,21 @@ public:
private:
libusb_context *_context;
+ 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;
+ libusb_handle_events_timeout(context, &tv);
+ }
};
libusb::session::sptr libusb::session::get_global_session(void){
@@ -59,6 +79,15 @@ libusb::session::sptr libusb::session::get_global_session(void){
//create a new global session
sptr new_global_session(new libusb_session_impl());
global_session = new_global_session;
+
+ //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);
+ }
+
return new_global_session;
}
@@ -137,8 +166,13 @@ public:
return _desc;
}
- std::string get_ascii_serial(void) const{
- if (this->get().iSerialNumber == 0) return "";
+ std::string get_ascii_property(const std::string &what) const
+ {
+ boost::uint8_t off = 0;
+ 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 "";
libusb::device_handle::sptr handle(
libusb::device_handle::get_cached_handle(_dev)
@@ -146,7 +180,7 @@ public:
unsigned char buff[512];
ssize_t ret = libusb_get_string_descriptor_ascii(
- handle->get(), this->get().iSerialNumber, buff, sizeof(buff)
+ handle->get(), off, buff, sizeof(buff)
);
if (ret < 0) return ""; //on error, just return empty string
@@ -240,7 +274,15 @@ public:
}
std::string get_serial(void) const{
- return libusb::device_descriptor::make(this->get_device())->get_ascii_serial();
+ 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");
}
boost::uint16_t get_vendor_id(void) const{
@@ -251,6 +293,10 @@ public:
return libusb::device_descriptor::make(this->get_device())->get().idProduct;
}
+ bool firmware_loaded() {
+ return (get_manufacturer() == "Ettus Research LLC");
+ }
+
private:
libusb::device::sptr _dev; //always keep a reference to device
};