Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add libusb check for known ADALM-Pluto VID:PID #50

Merged
merged 1 commit into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,29 @@ if (LibAD9361_FOUND)
add_definitions(-DHAS_AD9361_IIO)
endif()

########################################################################
# Find libusb
########################################################################
find_package(LibUSB)

if(LibUSB_FOUND)
message(STATUS "LibUSB_INCLUDE_DIRS: ${LibUSB_INCLUDE_DIRS}")
message(STATUS "LibUSB_LIBRARIES: ${LibUSB_LIBRARIES}")
message(STATUS "LibUSB_DEFINITIONS: ${LibUSB_DEFINITIONS}")
include_directories(${LibUSB_INCLUDE_DIRS})
add_definitions(-DHAS_LIBUSB1)
#disable warnings for libusb.h
add_compile_options($<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-Wno-zero-length-array>)
endif()


SOAPY_SDR_MODULE_UTIL(
TARGET PlutoSDRSupport
SOURCES
PlutoSDR_Registration.cpp
PlutoSDR_Settings.cpp
PlutoSDR_Streaming.cpp
LIBRARIES ${LibIIO_LIBRARIES} ${LibAD9361_LIBRARIES}
LIBRARIES ${LibIIO_LIBRARIES} ${LibAD9361_LIBRARIES} ${LIBUSB_LIBRARIES}
)

########################################################################
Expand Down
9 changes: 5 additions & 4 deletions FindLibAD9361.cmake
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# - Try to find libad9361-iio
# Once done this will define
#
# LibAD9361_FOUND - system has libiio
# LibAD9361_INCLUDE_DIRS - the libiio include directory
# LibAD9361_LIBRARIES - Link these to use libiio
# LibAD9361_DEFINITIONS - Compiler switches required for using libiio
# LibAD9361_FOUND - system has libad9361
# LibAD9361_INCLUDE_DIRS - the libad9361 include directory
# LibAD9361_LIBRARIES - Link these to use libad9361
# LibAD9361_DEFINITIONS - Compiler switches required for using libad9361
# LibAD9361_VERSION - the libad9361 version
#
# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
Expand Down
1 change: 1 addition & 0 deletions FindLibIIO.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# LibIIO_INCLUDE_DIRS - the libiio include directory
# LibIIO_LIBRARIES - Link these to use libiio
# LibIIO_DEFINITIONS - Compiler switches required for using libiio
# LibIIO_VERSION - the libiio version
#
# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
Expand Down
54 changes: 54 additions & 0 deletions FindLibUSB.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# - Try to find LibUSB-1.0
# Once done this will define
#
# LibUSB_FOUND - System has libusb
# LibUSB_INCLUDE_DIRS - The libusb include directories
# LibUSB_LIBRARIES - The libraries needed to use libusb
# LibUSB_DEFINITIONS - Compiler switches required for using libusb
# LibUSB_VERSION - the libusb version
#

find_package(PkgConfig)
pkg_check_modules(PC_LibUSB QUIET libusb-1.0)
set(LibUSB_DEFINITIONS ${PC_LibUSB_CFLAGS_OTHER})

find_path(LibUSB_INCLUDE_DIR NAMES libusb.h
HINTS ${PC_LibUSB_INCLUDE_DIRS}
PATH_SUFFIXES libusb-1.0
PATHS
/usr/include
/usr/local/include )

#standard library name for libusb-1.0
set(libusb1_library_names usb-1.0)

#libusb-1.0 compatible library on freebsd
if((CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") OR (CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD"))
list(APPEND libusb1_library_names usb)
endif()

#libusb-1.0 name on Windows (from PothosSDR distribution)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
list(APPEND libusb1_library_names libusb-1.0)
endif()

find_library(LibUSB_LIBRARY
NAMES ${libusb1_library_names}
HINTS ${PC_LibUSB_LIBRARY_DIRS}
PATHS
/usr/lib
/usr/local/lib )

set(LibUSB_VERSION ${PC_LibUSB_VERSION})

include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LibUSB_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LibUSB
REQUIRED_VARS LibUSB_LIBRARY LibUSB_INCLUDE_DIR
VERSION_VAR LibUSB_VERSION)

mark_as_advanced(LibUSB_LIBRARY LibUSB_INCLUDE_DIR LibUSB_VERSION)

set(LibUSB_LIBRARIES ${LibUSB_LIBRARY} )
set(LibUSB_INCLUDE_DIRS ${LibUSB_INCLUDE_DIR} )
60 changes: 59 additions & 1 deletion PlutoSDR_Registration.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#include "SoapyPlutoSDR.hpp"
#include <SoapySDR/Registry.hpp>
#include <sstream>
#include <chrono>
#include <thread>
#ifdef HAS_LIBUSB1
#include <libusb.h>
#endif

static std::vector<SoapySDR::Kwargs> results;
static std::vector<SoapySDR::Kwargs> find_PlutoSDR(const SoapySDR::Kwargs &args) {
Expand All @@ -15,9 +20,62 @@ static std::vector<SoapySDR::Kwargs> find_PlutoSDR(const SoapySDR::Kwargs &args)
SoapySDR::Kwargs options;

// Backends can error, scan each one individually
std::vector<std::string> backends = {"local", "usb", "ip"};
// The filtered "usb" backend is available starting from Libiio 0.24
std::vector<std::string> backends = {"local", "usb=0456:b673", "ip"};
for (std::vector<std::string>::iterator it = backends.begin(); it != backends.end(); it++) {

if (*it == "usb=0456:b673") {
#ifdef HAS_LIBUSB1
// Abort early if no known ADALM-Pluto USB VID:PID (0456:b673) is found,
// that way we won't block USB access for other drivers' enumeration on Libiio before 0.24.
libusb_context *usb_ctx = nullptr;
int r = libusb_init(&usb_ctx);
if (r < 0) {
SoapySDR_logf(SOAPY_SDR_WARNING, "libusb init error (%d)\n", r);
}
else {
// This is what libusb_open_device_with_vid_pid(usb_ctx, 0x0456, 0xb673) does,
// but without actually opening a device.
struct libusb_device **devs;
// this is cached in libusb, we won't block USB access for other drivers
r = libusb_get_device_list(usb_ctx, &devs);
if (r < 0) {
SoapySDR_logf(SOAPY_SDR_WARNING, "libusb get device list error (%d)\n", r);
continue; // iio scan context will most likely fail too?
}

bool found = false;
struct libusb_device *dev;
size_t i = 0;
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
// this is cached in libusb, we won't block USB access for other drivers
r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
break;
}
if (desc.idVendor == 0x0456 && desc.idProduct == 0xb673) {
found = true;
break;
}
}

libusb_free_device_list(devs, 1);

if (found) {
SoapySDR_logf(SOAPY_SDR_DEBUG, "ADALM-Pluto VID:PID found");
}
else {
SoapySDR_logf(SOAPY_SDR_DEBUG, "No ADALM-Pluto VID:PID found");
continue;
}
}
#endif
// Defer to other drivers, prevent a race condition on USB enumeration with Libiio before 0.24,
// the value of 500ms has not been confirmed and might be 50ms to 1s possibly.
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}

scan_ctx = iio_create_scan_context(it->c_str(), 0);
if (scan_ctx == nullptr) {
SoapySDR_logf(SOAPY_SDR_WARNING, "Unable to setup %s scan\n", it->c_str());
Expand Down