diff --git a/INSTALL b/INSTALL index fcde39fce..9de096dd7 100644 --- a/INSTALL +++ b/INSTALL @@ -250,13 +250,13 @@ MS Windows ./configure --host=i686-w64-mingw32 -- Specifying the directory of libusb for a Windows build using MinGW as - libusb must be installed separately, use the following environment +- Specifying the directory of libusb-1.0 for a Windows build using MinGW as + libusb-1.0 must be installed separately, use the following environment variables after all other options. ./configure [other options] \ - CPPFLAGS="-I/path_to_libusb/include" \ - LDFLAGS="-L/path_to_libusb/lib/gcc" + CPPFLAGS="-I/path_to_libusb-1.0/include" \ + LDFLAGS="-L/path_to_libusb-1.0/lib/gcc" - Mingw compiler under Cygwin @@ -333,12 +333,12 @@ Note, the following is still experimental. application may be thought to ease its distribution. As a static library is built by default the following notes may assist application authors. - The 'kit' backend depends on libusb. To link libusb statically set the + The 'kit' backend depends on libusb-1.0. To link libusb-1.0 statically set the following environment variable on the 'configure' command line: - LIBUSB_LIBS="/usr/lib/i386-linux-gnu/libusb.a" + LIBUSB_LIBS="/usr/lib/i386-linux-gnu/libusb-1.0.a" -do note that the absolute path to 'libusb.a' may well be quite different on +do note that the absolute path to 'libusb-1.0.a' may well be quite different on other systems. By default the GNU linker (ld) will include most all symbols in a static @@ -358,7 +358,7 @@ nor does 'rotctl' contain any rig symbols. ./configure --disable-shared --prefix="$HOME/local" --without-cxx-binding \ --disable-winradio CFLAGS="-fdata-sections -ffunction-sections" \ - LDFLAGS="-Wl,--gc-sections" LIBUSB_LIBS="/usr/lib/i386-linux-gnu/libusb.a" + LDFLAGS="-Wl,--gc-sections" LIBUSB_LIBS="/usr/lib/i386-linux-gnu/libusb-1.0.a" -to make a static only Hamlib library, statically link libusb, and include only +to make a static only Hamlib library, statically link libusb-1.0, and include only the needed symbols in the Hamlib utilities linking to libhamlib.a. diff --git a/README.betatester b/README.betatester index 329ebdfd2..bf30bebbc 100644 --- a/README.betatester +++ b/README.betatester @@ -86,12 +86,12 @@ Optional, but highly recommended for a complete build: * zlib devel # Needed by configure's test for Python * libxml2 devel # xml2-config --version * libgd2 devel # gdlib-config --version -* libusb devel # libusb-config --version (not 1.0.0!) +* libusb-1.0 devel # ver 1.0 or newer (not 0.1!) * libreadline devel # ver 5.2 or newer N.B The libusb package is required for building most of the 'kit' backend. -The older version is needed, not 1.0.0 or higher. Debian and derivatives -package libusb 0.1.12 which is what is needed. +The newer version is needed, not 0.1. Debian and derivatives +package libusb-1.0 which is what is needed. Documentation: * Doxygen diff --git a/android/config.h b/android/config.h index c4043bebf..dc3ac17e6 100644 --- a/android/config.h +++ b/android/config.h @@ -222,8 +222,8 @@ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 -/* Define to 1 if you have the header file. */ -#define HAVE_USB_H 1 +/* Define to 1 if you have the header file. */ +#define HAVE_LIBUSB_H 1 /* Define to 1 if you have the `usleep' function. */ #define HAVE_USLEEP 1 diff --git a/configure.ac b/configure.ac index 647604fcb..287869e3e 100644 --- a/configure.ac +++ b/configure.ac @@ -309,23 +309,23 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], dnl Check for libusb, treat LIBUSB_LIBS and LIBUSB_CFLAGS as precious variables AC_ARG_VAR([LIBUSB_CFLAGS], [C compiler flags for libusb, overriding configure defaults]) -AC_ARG_VAR([LIBUSB_LIBS], [linker flags for libusb, overriding configure check (useful for specifying static libusb.a (see INSTALL))]) +AC_ARG_VAR([LIBUSB_LIBS], [linker flags for libusb, overriding configure check (useful for specifying static libusb-1.0.a (see INSTALL))]) cf_with_libusb="no" AS_IF([test -z $LIBUSB_LIBS], - [AC_CHECK_LIB([usb], [usb_init], [LIBUSB_LIBS="-lusb" cf_with_libusb="yes"], - [AC_MSG_WARN([usb_init was not found in libusb--USB backends will be disabled])]) + [AC_CHECK_LIB([usb-1.0], [libusb_init], [LIBUSB_LIBS="-lusb-1.0" cf_with_libusb="yes"], + [AC_MSG_WARN([libusb_init was not found in libusb-1.0--USB backends will be disabled])]) ], [cf_with_libusb="yes"]) LIBUSB="" AS_IF([test x"${cf_with_libusb}" = "xyes"], - [AC_CHECK_HEADERS([usb.h]) + [AC_CHECK_HEADERS([libusb.h]) AC_DEFINE([HAVE_LIBUSB], [1], - [Define if libusb is available]) - LIBUSB="libusb"]) + [Define if libusb-1.0 is available]) + LIBUSB="libusb-1.0"]) # Only used in hamlib.pc.in AC_SUBST([LIBUSB]) diff --git a/kit/dwt.c b/kit/dwt.c index 1ff8a0e1d..503860837 100644 --- a/kit/dwt.c +++ b/kit/dwt.c @@ -235,7 +235,7 @@ int dwtdll_init(RIG *rig) if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", - __FUNCTION__, DWTDLL); + __func__, DWTDLL); free(priv); return -RIG_EIO; /* huh! */ } @@ -456,11 +456,11 @@ static const char* dwtdll_get_info(RIG *rig) } -#elif defined(HAVE_LIBUSB) && defined(HAVE_USB_H) +#elif defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) #include -#include +#include #include "token.h" @@ -495,7 +495,7 @@ const struct rig_caps dwt_caps = { .rig_model = RIG_MODEL_DWT, .model_name = "Digital World Traveller", .mfg_name = "Coding Technologies", -.version = "0.1", +.version = "0.2", .copyright = "LGPL", .status = RIG_STATUS_UNTESTED, .rig_type = RIG_TYPE_TUNER, @@ -583,7 +583,7 @@ int dwt_init(RIG *rig) #define MSG_LEN 16 int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int request, value, index; unsigned char buf[MSG_LEN] = { 0x4a, 0x00, 0x03, 0x00, 0xff, 0xff, 0x32 }; int requesttype, r; @@ -597,27 +597,30 @@ int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq) buf[8] = ifreq & 0xff; buf[7] = (ifreq>>8) & 0xff; - r = usb_control_msg (udh, requesttype, request, value, index, - (char *) buf, 9, 1000); + + r = libusb_control_transfer (udh, requesttype, request, value, index, + buf, 9, 1000); if (r < 0) { - /* we get EPIPE if the firmware stalls the endpoint. */ - if (errno != EPIPE) - rig_debug (RIG_DEBUG_ERR, - "usb_control_msg failed: %s\n", - usb_strerror ()); + rig_debug (RIG_DEBUG_ERR, + "libusb_control_transfer failed: %s\n", + libusb_error_name (r)); return -RIG_EIO; } return RIG_OK; } +/* Rem: not reentrant */ const char * dwt_get_info(RIG *rig) { static char buf[64]; - struct usb_dev_handle *udh = rig->state.rigport.handle; - struct usb_device *q = usb_device(udh); + libusb_device_handle *udh = rig->state.rigport.handle; + struct libusb_device_descriptor desc; - sprintf(buf, "Dev %04d", q->descriptor.bcdDevice); + /* always succeeds since libusb-1.0.16 */ + libusb_get_device_descriptor(libusb_get_device(udh), &desc); + + sprintf(buf, "Dev %04d", desc.bcdDevice); return buf; } diff --git a/kit/elektor507.c b/kit/elektor507.c index c36e887f1..dff543686 100644 --- a/kit/elektor507.c +++ b/kit/elektor507.c @@ -33,7 +33,7 @@ #ifdef _WIN32 #define USE_FTDI_DLL -#elif defined(HAVE_LIBUSB) && defined(HAVE_USB_H) +#elif defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) #define USE_LIBUSB #endif @@ -145,7 +145,7 @@ struct elektor507_extra_priv_data { #include -#include +#include #define USB_VID_FTDI 0x0403 /* Future Technology Devices International */ @@ -236,7 +236,7 @@ int elektor507_init(RIG *rig) if (!extra_priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", - __FUNCTION__, ELEKTOR507_DLL); + __func__, ELEKTOR507_DLL); free(priv); return -RIG_EIO; /* huh! */ } @@ -273,7 +273,7 @@ int elektor507_ftdi_write_data(RIG *rig, void *FTOutBuf, unsigned long BufferSiz FT_Result ret; int Result; - rig_debug(RIG_DEBUG_TRACE,"%s called, %d bytes\n", __FUNCTION__, BufferSize); + rig_debug(RIG_DEBUG_TRACE,"%s called, %d bytes\n", __func__, BufferSize); /* Open FTDI */ ret = extra_priv->FT_Open(0, &extra_priv->ftHandle); @@ -376,32 +376,36 @@ int elektor507_cleanup(RIG *rig) return RIG_OK; } +/* Rem: not reentrant */ const char * elektor507_get_info(RIG *rig) { static char buf[64]; - struct usb_dev_handle *udh = rig->state.rigport.handle; - struct usb_device *q = usb_device(udh); + libusb_device_handle *udh = rig->state.rigport.handle; + struct libusb_device_descriptor desc; - sprintf(buf, "USB dev %04d", q->descriptor.bcdDevice); + /* always succeeds since libusb-1.0.16 */ + libusb_get_device_descriptor(libusb_get_device(udh), &desc); + + sprintf(buf, "USB dev %04d", desc.bcdDevice); return buf; } int elektor507_libusb_setup(RIG *rig) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; unsigned short index=0, usb_val; - rig_debug(RIG_DEBUG_TRACE,"%s called\n", __FUNCTION__); + rig_debug(RIG_DEBUG_TRACE,"%s called\n", __func__); /* Reset the ftdi device */ #if 1 - ret = usb_control_msg(udh, 0x40, 0, 0, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); + ret = libusb_control_transfer(udh, 0x40, 0, 0, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg reset failed: %s\n", - __FUNCTION__, - usb_strerror ()); + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer reset failed: %s\n", + __func__, + libusb_error_name (ret)); return -RIG_EIO; } #endif @@ -412,11 +416,11 @@ int elektor507_libusb_setup(RIG *rig) usb_val = 0xff; /* low byte: bitmask */ usb_val |= (0x01 << 8); /* Basic bitbang_mode: 0x01 */ - ret = usb_control_msg(udh, 0x40, 0x0B, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); + ret = libusb_control_transfer(udh, 0x40, 0x0B, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg bitbangmode failed: %s\n", - __FUNCTION__, - usb_strerror ()); + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer bitbangmode failed: %s\n", + __func__, + libusb_error_name (ret)); return -RIG_EIO; } @@ -426,11 +430,11 @@ int elektor507_libusb_setup(RIG *rig) */ usb_val = 49230; /* magic value for 38400 bauds */ index = 0; - ret = usb_control_msg(udh, 0x40, 3, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); + ret = libusb_control_transfer(udh, 0x40, 3, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg baudrate failed: %s\n", - __FUNCTION__, - usb_strerror ()); + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer baudrate failed: %s\n", + __func__, + libusb_error_name (ret)); return -RIG_EIO; } @@ -439,18 +443,16 @@ int elektor507_libusb_setup(RIG *rig) int elektor507_ftdi_write_data(RIG *rig, void *FTOutBuf, unsigned long BufferSize) { - struct usb_dev_handle *udh = rig->state.rigport.handle; - int ret; + libusb_device_handle *udh = rig->state.rigport.handle; + int ret, actual_length; - rig_debug(RIG_DEBUG_TRACE,"%s called, %d bytes\n", __FUNCTION__, BufferSize); + rig_debug(RIG_DEBUG_TRACE,"%s called, %d bytes\n", __func__, BufferSize); - ret = usb_bulk_write(udh, FTDI_IN_EP, FTOutBuf, BufferSize, FTDI_USB_WRITE_TIMEOUT); + ret = libusb_bulk_transfer(udh, FTDI_IN_EP, FTOutBuf, BufferSize, &actual_length, FTDI_USB_WRITE_TIMEOUT); if (ret < 0) { - /* we get EPIPE if the firmware stalls the endpoint. */ - if (errno != EPIPE) - rig_debug (RIG_DEBUG_ERR, - "usb_bulk_write failed: %s\n", - usb_strerror ()); + rig_debug (RIG_DEBUG_ERR, + "usb_bulk_write failed: %s\n", + libusb_error_name (ret)); return -RIG_EIO; } @@ -495,7 +497,7 @@ const struct rig_caps elektor507_caps = { .rig_model = RIG_MODEL_ELEKTOR507, .model_name = "Elektor SDR-USB", .mfg_name = "Elektor", -.version = "0.3.1", +.version = "0.3.2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, @@ -625,7 +627,7 @@ int elektor507_open(RIG *rig) struct elektor507_priv_data *priv = (struct elektor507_priv_data *)rig->state.priv; int ret; - rig_debug(RIG_DEBUG_TRACE,"%s called\n", __FUNCTION__); + rig_debug(RIG_DEBUG_TRACE,"%s called\n", __func__); /* * Setup the FT232R. @@ -758,7 +760,7 @@ static void find_P_Q_DIV1N(struct elektor507_priv_data *priv, freq_t freq) VCO = ((double)priv->osc_freq/priv->Q)*priv->P; if (VCO < 100e3 || VCO > 400e3) rig_debug(RIG_DEBUG_VERBOSE, "%s: Unstable parameters for VCO=%.1f\n", - __FUNCTION__, VCO); + __func__, VCO); } #endif /* ORIG_ALGORITHM */ @@ -826,7 +828,7 @@ static void find_P_Q_DIV1N(struct elektor507_priv_data *priv, freq_t freq) VCO = ((double)priv->osc_freq/priv->Q)*priv->P; if (VCO < vco_min || VCO > 400e3) rig_debug(RIG_DEBUG_VERBOSE, "%s: Unstable parameters for VCO=%.1f\n", - __FUNCTION__, VCO); + __func__, VCO); } #endif /* default alternative to ORIG_ALGORITHM */ @@ -902,12 +904,12 @@ int elektor507_set_freq(RIG *rig, vfo_t vfo, freq_t freq) elektor507_get_freq(rig, vfo, &final_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq=%.0f kHz, delta=%d Hz, Div1N=%d, P=%d, Q=%d, FREQ_ALGORITHM=%d\n", - __FUNCTION__, freq/kHz(1), (int)(final_freq-freq), priv->Div1N, priv->P, priv->Q, FREQ_ALGORITHM); + __func__, freq/kHz(1), (int)(final_freq-freq), priv->Div1N, priv->P, priv->Q, FREQ_ALGORITHM); if ((double)priv->osc_freq/priv->Q < 250) rig_debug(RIG_DEBUG_WARN, "%s: Unstable parameters for REF/Qtotal=%.1f\n", - __FUNCTION__, (double)priv->osc_freq/priv->Q); + __func__, (double)priv->osc_freq/priv->Q); ret = cy_update_pll(rig, CY_I2C_RAM_ADR); @@ -990,7 +992,7 @@ int elektor507_set_ant(RIG * rig, vfo_t vfo, ant_t ant) struct elektor507_priv_data *priv = (struct elektor507_priv_data *)rig->state.priv; int ret, Mux; - rig_debug(RIG_DEBUG_TRACE,"%s called\n", __FUNCTION__); + rig_debug(RIG_DEBUG_TRACE,"%s called\n", __func__); /* * FTDI: RTS, CTS, DTR @@ -1240,7 +1242,7 @@ int load_ftdi_code(RIG *rig, unsigned char IICadr, const unsigned char code[]) int ret; int i, j; - rig_debug(RIG_DEBUG_TRACE,"%s called\n", __FUNCTION__); + rig_debug(RIG_DEBUG_TRACE,"%s called\n", __func__); for (i = 0; i<16; i++) { diff --git a/kit/fifisdr.c b/kit/fifisdr.c index 276b7198f..04ea6fb8b 100644 --- a/kit/fifisdr.c +++ b/kit/fifisdr.c @@ -41,10 +41,10 @@ /* * Compile this model only if libusb is available */ -#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H) +#if defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) #include -#include +#include @@ -120,7 +120,7 @@ const struct rig_caps fifisdr_caps = { .rig_model = RIG_MODEL_FIFISDR, .model_name = "FiFi-SDR", .mfg_name = "FiFi", - .version = "0.5", + .version = "0.6", .copyright = "LGPL", .status = RIG_STATUS_BETA, @@ -261,20 +261,20 @@ static uint32_t fifisdr_fromle32 (uint32_t x) /** USB OUT transfer via vendor device command. */ static int fifisdr_usb_write (RIG *rig, int request, int value, int index, - char *bytes, int size) + unsigned char *bytes, int size) { int ret; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, + ret = libusb_control_transfer(udh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, request, value, index, bytes, size, rig->state.rigport.timeout); if (ret != size) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg (%d/%d) failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer (%d/%d) failed: %s\n", __func__, request, value, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -286,20 +286,20 @@ static int fifisdr_usb_write (RIG *rig, /** USB IN transfer via vendor device command. */ static int fifisdr_usb_read (RIG *rig, int request, int value, int index, - char *bytes, int size) + unsigned char *bytes, int size) { int ret; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + ret = libusb_control_transfer(udh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, request, value, index, bytes, size, rig->state.rigport.timeout); if (ret != size) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg (%d/%d) failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer (%d/%d) failed: %s\n", __func__, request, value, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -365,7 +365,7 @@ int fifisdr_open (RIG *rig) /* The VCO is a multiple of the RX frequency. Typically 4 */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 11, /* Read virtual VCO factor */ - (char *)&multiply, sizeof(multiply)); + (unsigned char *)&multiply, sizeof(multiply)); if (ret == RIG_OK) { priv->multiplier = fifisdr_fromle32(multiply); } @@ -381,7 +381,7 @@ const char * fifisdr_get_info (RIG *rig) int ret; uint32_t svn_version; - ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 0, (char *)&svn_version, sizeof(svn_version)); + ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 0, (unsigned char *)&svn_version, sizeof(svn_version)); if (ret != RIG_OK) { return NULL; } @@ -406,7 +406,7 @@ int fifisdr_set_freq (RIG *rig, vfo_t vfo, freq_t freq) freq1121 = fifisdr_tole32(round(mhz * 2097152.0)); ret = fifisdr_usb_write(rig, REQUEST_SET_FREQ_BY_VALUE, 0, 0, - (char *)&freq1121, sizeof(freq1121)); + (unsigned char *)&freq1121, sizeof(freq1121)); if (ret != RIG_OK) { return -RIG_EIO; } @@ -423,7 +423,7 @@ int fifisdr_get_freq (RIG *rig, vfo_t vfo, freq_t *freq) uint32_t freq1121; - ret = fifisdr_usb_read(rig, REQUEST_READ_FREQUENCY, 0, 0, (char *)&freq1121, sizeof(freq1121)); + ret = fifisdr_usb_read(rig, REQUEST_READ_FREQUENCY, 0, 0, (unsigned char *)&freq1121, sizeof(freq1121)); if (ret == RIG_OK) { freq1121 = fifisdr_fromle32(freq1121); @@ -461,7 +461,7 @@ static int fifisdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 15, /* Demodulator mode */ - (char *)&fifi_mode, sizeof(fifi_mode)); + (unsigned char *)&fifi_mode, sizeof(fifi_mode)); if (ret != RIG_OK) { return -RIG_EIO; } @@ -470,7 +470,7 @@ static int fifisdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) fifi_width = fifisdr_tole32(width); ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 16, /* Filter width */ - (char *)&fifi_width, sizeof(fifi_width)); + (unsigned char *)&fifi_width, sizeof(fifi_width)); if (ret != RIG_OK) { return -RIG_EIO; } @@ -490,7 +490,7 @@ static int fifisdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t * widt /* Read current mode */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 15, /* Demodulator mode */ - (char *)&fifi_mode, sizeof(fifi_mode)); + (unsigned char *)&fifi_mode, sizeof(fifi_mode)); if (ret != RIG_OK) { return -RIG_EIO; @@ -516,7 +516,7 @@ static int fifisdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t * widt /* Read current filter width */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 16, /* Filter width */ - (char *)&fifi_width, sizeof(fifi_width)); + (unsigned char *)&fifi_width, sizeof(fifi_width)); if (ret != RIG_OK) { return -RIG_EIO; } @@ -547,7 +547,7 @@ static int fifisdr_set_level (RIG * rig, vfo_t vfo, setting_t level, value_t val } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 19, /* Preamp */ - (char *)&fifi_preamp, sizeof(fifi_preamp)); + (unsigned char *)&fifi_preamp, sizeof(fifi_preamp)); break; /* RX volume control */ @@ -562,7 +562,7 @@ static int fifisdr_set_level (RIG * rig, vfo_t vfo, setting_t level, value_t val } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 14, /* Demodulator volume */ - (char *)&fifi_volume, sizeof(fifi_volume)); + (unsigned char *)&fifi_volume, sizeof(fifi_volume)); break; /* Squelch level */ @@ -577,7 +577,7 @@ static int fifisdr_set_level (RIG * rig, vfo_t vfo, setting_t level, value_t val } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 20, /* Squelch control */ - (char *)&fifi_squelch, sizeof(fifi_squelch)); + (unsigned char *)&fifi_squelch, sizeof(fifi_squelch)); break; /* AGC */ @@ -595,7 +595,7 @@ static int fifisdr_set_level (RIG * rig, vfo_t vfo, setting_t level, value_t val } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 21, /* AGC template */ - (char *)&fifi_agc, sizeof(fifi_agc)); + (unsigned char *)&fifi_agc, sizeof(fifi_agc)); break; /* Unsupported option */ @@ -623,7 +623,7 @@ static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_PREAMP: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 19, /* Preamp */ - (char *)&fifi_preamp, sizeof(fifi_preamp)); + (unsigned char *)&fifi_preamp, sizeof(fifi_preamp)); if (ret == RIG_OK) { /* Value can be 0 (0 dB) or 1 (+6 dB) */ val->i = 0; @@ -637,7 +637,7 @@ static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_AF: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 14, /* Demodulator volume */ - (char *)&fifi_volume, sizeof(fifi_volume)); + (unsigned char *)&fifi_volume, sizeof(fifi_volume)); if (ret == RIG_OK) { /* Value is in % (0...100) */ val->f = 0.0f; @@ -651,7 +651,7 @@ static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_SQL: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 20, /* Squelch control */ - (char *)&fifi_squelch, sizeof(fifi_squelch)); + (unsigned char *)&fifi_squelch, sizeof(fifi_squelch)); if (ret == RIG_OK) { /* Value is in % (0...100) */ val->f = 0.0f; @@ -665,7 +665,7 @@ static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_AGC: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 21, /* AGC template */ - (char *)&fifi_agc, sizeof(fifi_agc)); + (unsigned char *)&fifi_agc, sizeof(fifi_agc)); if (ret == RIG_OK) { val->i = 0; switch (fifi_agc) { @@ -684,7 +684,7 @@ static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) case RIG_LEVEL_STRENGTH: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 17, /* S-Meter */ - (char *)&fifi_meter, sizeof(fifi_meter)); + (unsigned char *)&fifi_meter, sizeof(fifi_meter)); if (ret == RIG_OK) { val->i = fifisdr_fromle32(fifi_meter); } @@ -711,7 +711,7 @@ static int fifisdr_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *va case TOK_LVL_FMCENTER: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 18, /* FM center frequency */ - (char *)&u32, sizeof(u32)); + (unsigned char *)&u32, sizeof(u32)); if (ret == RIG_OK) { val->f = Hz((int32_t)fifisdr_fromle32(u32)); } @@ -725,4 +725,4 @@ static int fifisdr_get_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t *va return ret; } -#endif /* defined(HAVE_LIBUSB) && defined(HAVE_USB_H) */ +#endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ diff --git a/kit/funcube.c b/kit/funcube.c index bf1c98e57..bab100442 100644 --- a/kit/funcube.c +++ b/kit/funcube.c @@ -42,10 +42,10 @@ /* * Compile this model only if libusb is available */ -#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H) +#if defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) #include -#include +#include #include "funcube.h" @@ -63,8 +63,8 @@ static const struct confparams funcube_cfg_params[] = { }; // functions used set / read frequency, working on FUNcube version 0 and 1 -int set_freq_v0(usb_dev_handle *udh, unsigned int f, int timeout); -int set_freq_v1(usb_dev_handle *udh, unsigned int f, int timeout); +int set_freq_v0(libusb_device_handle *udh, unsigned int f, int timeout); +int set_freq_v1(libusb_device_handle *udh, unsigned int f, int timeout); /* * Common data struct @@ -86,7 +86,7 @@ const struct rig_caps funcube_caps = { .rig_model = RIG_MODEL_FUNCUBEDONGLE, .model_name = "FUNcube Dongle", .mfg_name = "AMSAT-UK", -.version = "0.2", +.version = "0.3", .copyright = "GPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, @@ -148,7 +148,7 @@ const struct rig_caps funcubeplus_caps = { .rig_model = RIG_MODEL_FUNCUBEDONGLEPLUS, .model_name = "FUNcube Dongle Pro+", .mfg_name = "AMSAT-UK", -.version = "0.2", +.version = "0.3", .copyright = "GPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, @@ -271,55 +271,60 @@ int funcube_cleanup(RIG *rig) return RIG_OK; } +/* Rem: not reentrant */ const char * funcube_get_info(RIG *rig) { static char buf[64]; - struct usb_dev_handle *udh = rig->state.rigport.handle; - struct usb_device *q = usb_device(udh); + libusb_device_handle *udh = rig->state.rigport.handle; + struct libusb_device_descriptor desc; - sprintf(buf, "USB dev %04d", q->descriptor.bcdDevice); + /* always succeeds since libusb-1.0.16 */ + libusb_get_device_descriptor(libusb_get_device(udh), &desc); + + sprintf(buf, "Dev %04d", desc.bcdDevice); return buf; } -int set_freq_v0(usb_dev_handle *udh, unsigned int f, int timeout) +int set_freq_v0(libusb_device_handle *udh, unsigned int f, int timeout) { int ret; + int actual_length; - char au8BufOut[64]; // endpoint size - char au8BufIn[64]; // endpoint size + unsigned char au8BufOut[64]; // endpoint size + unsigned char au8BufIn[64]; // endpoint size // frequency is in Hz, while the dongle expects it in kHz - f = f / 1e3; + f = f / 1000; au8BufOut[0]=REQUEST_SET_FREQ; // Command to Set Frequency on dongle - au8BufOut[1]=(char)f; - au8BufOut[2]=(char)(f>>8); - au8BufOut[3]=(char)(f>>16); + au8BufOut[1]=(unsigned char)f; + au8BufOut[2]=(unsigned char)(f>>8); + au8BufOut[3]=(unsigned char)(f>>16); rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", - __func__, (unsigned)au8BufOut[0] & 0xFF, (unsigned)au8BufOut[1] & 0xFF, (unsigned)au8BufOut[2] & 0xFF, (unsigned)au8BufOut[3] & 0xFF); + __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); - ret = usb_interrupt_write(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), timeout); + ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, timeout); if( ret < 0 ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_write failed (%d): %s\n", - __func__,ret, usb_strerror ()); - return -RIG_EIO; + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", + __func__,ret, libusb_error_name (ret)); + return -RIG_EIO; } - ret = usb_interrupt_read(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), timeout); + ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, timeout); - if( ret != sizeof(au8BufIn) ) + if( ret < 0 || actual_length != sizeof(au8BufIn) ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_read failed (%d): %s\n", - __func__, ret, usb_strerror ()); - return -RIG_EIO; + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", + __func__, ret, libusb_error_name (ret)); + return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", - __func__, (unsigned)au8BufIn[0] & 0xFF, (unsigned)au8BufIn[1] & 0xFF); + __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug (RIG_DEBUG_ERR, "%s: REQUEST_SET_FREQ not supported\n", @@ -330,46 +335,47 @@ int set_freq_v0(usb_dev_handle *udh, unsigned int f, int timeout) return RIG_OK; } -int set_freq_v1(usb_dev_handle *udh, unsigned int f, int timeout) +int set_freq_v1(libusb_device_handle *udh, unsigned int f, int timeout) { int ret; + int actual_length; - char au8BufOut[64]; // endpoint size - char au8BufIn[64]; // endpoint size + unsigned char au8BufOut[64]; // endpoint size + unsigned char au8BufIn[64]; // endpoint size au8BufOut[0]=REQUEST_SET_FREQ_HZ; // Command to Set Frequency in Hz on dongle - au8BufOut[1]=(char)f; - au8BufOut[2]=(char)(f>>8); - au8BufOut[3]=(char)(f>>16); - au8BufOut[4]=(char)(f>>24); + au8BufOut[1]=(unsigned char)f; + au8BufOut[2]=(unsigned char)(f>>8); + au8BufOut[3]=(unsigned char)(f>>16); + au8BufOut[4]=(unsigned char)(f>>24); rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x%02x\n", - __func__, (unsigned)au8BufOut[0] & 0xFF, (unsigned)au8BufOut[1] & 0xFF, (unsigned)au8BufOut[2] & 0xFF, (unsigned)au8BufOut[3] & 0xFF, - (unsigned)au8BufOut[4] & 0xFF); + __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF, + au8BufOut[4] & 0xFF); - ret = usb_interrupt_write(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), timeout); + ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, timeout); if( ret < 0 ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_write failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__,ret, - usb_strerror ()); - return -RIG_EIO; + libusb_error_name (ret)); + return -RIG_EIO; } - ret = usb_interrupt_read(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), timeout); + ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, timeout); - if( ret != sizeof(au8BufIn) ) + if( ret < 0 || actual_length != sizeof(au8BufIn) ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_read failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, - usb_strerror ()); - return -RIG_EIO; + libusb_error_name (ret)); + return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x%02x%02x%02x\n", - __func__, (unsigned)au8BufIn[0] & 0xFF, (unsigned)au8BufIn[1] & 0xFF, (unsigned)au8BufIn[2] & 0xFF, (unsigned)au8BufIn[3] & 0xFF, - (unsigned)au8BufIn[4] & 0xFF, (unsigned)au8BufIn[5] & 0xFF); + __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF, au8BufIn[3] & 0xFF, + au8BufIn[4] & 0xFF, au8BufIn[5] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug (RIG_DEBUG_ERR, "%s: REQUEST_SET_FREQ_HZ not supported\n", @@ -383,7 +389,7 @@ int set_freq_v1(usb_dev_handle *udh, unsigned int f, int timeout) int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct funcube_priv_data *priv = (struct funcube_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; if ((ret = set_freq_v1(udh, freq, rig->state.rigport.timeout)) != RIG_OK) { @@ -410,39 +416,40 @@ int get_freq_v0(RIG *rig, vfo_t vfo, freq_t *freq) int get_freq_v1(RIG *rig, vfo_t vfo, freq_t *freq) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; unsigned int f; + int actual_length; - char au8BufOut[64]; // endpoint size - char au8BufIn[64]; // endpoint size + unsigned char au8BufOut[64]; // endpoint size + unsigned char au8BufIn[64]; // endpoint size au8BufOut[0]=REQUEST_GET_FREQ_HZ; // Command to Set Frequency on dongle rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", - __func__, (unsigned)au8BufOut[0] & 0xFF, (unsigned)au8BufOut[1] & 0xFF, (unsigned)au8BufOut[2] & 0xFF, (unsigned)au8BufOut[3] & 0xFF); + __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); - ret = usb_interrupt_write(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), rig->state.rigport.timeout); + ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rig->state.rigport.timeout); if( ret < 0 ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_write failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__,ret, - usb_strerror ()); + libusb_error_name (ret)); } - ret = usb_interrupt_read(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), rig->state.rigport.timeout); + ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rig->state.rigport.timeout); - if( ret != sizeof(au8BufIn) ) + if( ret < 0 || actual_length != sizeof(au8BufIn) ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_read failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, - usb_strerror ()); + libusb_error_name (ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x%02x%02x%02x\n", - __func__, (unsigned)au8BufIn[0] & 0xFF, (unsigned)au8BufIn[1] & 0xFF, (unsigned)au8BufIn[2] & 0xFF, (unsigned)au8BufIn[3] & 0xFF, - (unsigned)au8BufIn[4] & 0xFF, (unsigned)au8BufIn[5] & 0xFF); + __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF, au8BufIn[3] & 0xFF, + au8BufIn[4] & 0xFF, au8BufIn[5] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug (RIG_DEBUG_ERR, "%s: REQUEST_GET_FREQ_HZ not supported\n", @@ -450,8 +457,8 @@ int get_freq_v1(RIG *rig, vfo_t vfo, freq_t *freq) return -RIG_EIO; } - f = ((unsigned int)au8BufIn[2] & 0xFF) | (((unsigned int)au8BufIn[3] & 0xFF) << 8) | - (((unsigned int)au8BufIn[4] & 0xFF) << 16) | (((unsigned int)au8BufIn[5] & 0xFF) << 24), + f = (au8BufIn[2] & 0xFF) | ((au8BufIn[3] & 0xFF) << 8) | + ((au8BufIn[4] & 0xFF) << 16) | ((au8BufIn[5] & 0xFF) << 24), *freq = f; @@ -471,10 +478,11 @@ int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; - char au8BufOut[64]; // endpoint size - char au8BufIn[64]; // endpoint size + int actual_length; + unsigned char au8BufOut[64]; // endpoint size + unsigned char au8BufIn[64]; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: @@ -525,28 +533,28 @@ int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", - __func__, (unsigned)au8BufOut[0] & 0xFF, (unsigned)au8BufOut[1] & 0xFF, (unsigned)au8BufOut[2] & 0xFF, (unsigned)au8BufOut[3] & 0xFF); + __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); - ret = usb_interrupt_write(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), rig->state.rigport.timeout); + ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rig->state.rigport.timeout); if( ret < 0 ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_write failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__,ret, - usb_strerror ()); + libusb_error_name (ret)); } - ret = usb_interrupt_read(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), rig->state.rigport.timeout); + ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rig->state.rigport.timeout); - if( ret != sizeof(au8BufIn) ) + if( ret < 0 || actual_length != sizeof(au8BufIn) ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_read failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, - usb_strerror ()); + libusb_error_name (ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", - __func__, (unsigned)au8BufIn[0] & 0xFF, (unsigned)au8BufIn[1] & 0xFF); + __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug (RIG_DEBUG_ERR, "%s: REQUEST_GET_FREQ_HZ not supported\n", @@ -558,10 +566,11 @@ int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) } int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; - char au8BufOut[64]; // endpoint size - char au8BufIn[64]; // endpoint size + int actual_length; + unsigned char au8BufOut[64]; // endpoint size + unsigned char au8BufIn[64]; // endpoint size switch (level) { case RIG_LEVEL_ATT: @@ -579,28 +588,28 @@ int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) } rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", - __func__, (unsigned)au8BufOut[0] & 0xFF, (unsigned)au8BufOut[1] & 0xFF, (unsigned)au8BufOut[2] & 0xFF, (unsigned)au8BufOut[3] & 0xFF); + __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); - ret = usb_interrupt_write(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), rig->state.rigport.timeout); + ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rig->state.rigport.timeout); if( ret < 0 ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_write failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__,ret, - usb_strerror ()); + libusb_error_name (ret)); } - ret = usb_interrupt_read(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), rig->state.rigport.timeout); + ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rig->state.rigport.timeout); - if( ret != sizeof(au8BufIn) ) + if( ret < 0 || actual_length != sizeof(au8BufIn) ) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_interrupt_read failed (%d): %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, - usb_strerror ()); + libusb_error_name (ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x\n", - __func__, (unsigned)au8BufIn[0] & 0xFF, (unsigned)au8BufIn[1] & 0xFF, (unsigned)au8BufIn[2] & 0xFF); + __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug (RIG_DEBUG_ERR, "%s: REQUEST_GET_FREQ_HZ not supported\n", @@ -658,4 +667,4 @@ int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) return RIG_OK; } -#endif /* defined(HAVE_LIBUSB) && defined(HAVE_USB_H) */ +#endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ diff --git a/kit/kit.c b/kit/kit.c index 0c9c94415..0222dbc08 100644 --- a/kit/kit.c +++ b/kit/kit.c @@ -46,7 +46,7 @@ DECLARE_INITRIG_BACKEND(kit) rig_register(&miniVNA_caps); rig_register(&hiqsdr_caps); -#if (defined(HAVE_LIBUSB) && defined(HAVE_USB_H)) +#if (defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H)) rig_register(&si570avrusb_caps); rig_register(&si570picusb_caps); rig_register(&si570peaberry1_caps); @@ -56,7 +56,7 @@ DECLARE_INITRIG_BACKEND(kit) rig_register(&fasdr_caps); rig_register(&funcubeplus_caps); #endif -#if (defined(HAVE_LIBUSB) && defined(HAVE_USB_H)) || defined(_WIN32) +#if (defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H)) || defined(_WIN32) /* rigs with alternate DLL support on Win32 */ rig_register(&dwt_caps); rig_register(&elektor507_caps); diff --git a/kit/si570avrusb.c b/kit/si570avrusb.c index 53e7d82d3..5cdec8f5a 100644 --- a/kit/si570avrusb.c +++ b/kit/si570avrusb.c @@ -41,10 +41,10 @@ /* * Compile this model only if libusb is available */ -#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H) +#if defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) #include -#include +#include #include "si570avrusb.h" @@ -146,7 +146,7 @@ const struct rig_caps si570avrusb_caps = { .rig_model = RIG_MODEL_SI570AVRUSB, .model_name = "Si570 AVR-USB", .mfg_name = "SoftRock", -.version = "0.2", +.version = "0.3", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, @@ -222,7 +222,7 @@ const struct rig_caps si570peaberry1_caps = { .rig_model = RIG_MODEL_SI570PEABERRY1, .model_name = "Si570 Peaberry V1", .mfg_name = "AE9RB", -.version = "0.2", +.version = "0.3", .copyright = "GPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, @@ -379,7 +379,7 @@ const struct rig_caps si570picusb_caps = { .rig_model = RIG_MODEL_SI570PICUSB, .model_name = "Si570 PIC-USB", .mfg_name = "KTH-SDR kit", -.version = "0.2", +.version = "0.3", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, @@ -459,7 +459,7 @@ const struct rig_caps fasdr_caps = { .rig_model = RIG_MODEL_FASDR, .model_name = "FA-SDR", .mfg_name = "Funkamatuer", -.version = "0.1", +.version = "0.2", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_FLAG_TUNER|RIG_FLAG_TRANSMITTER, @@ -527,6 +527,9 @@ const struct rig_caps fasdr_caps = { }; +// libusb control transfer request types +#define REQUEST_TYPE_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN) +#define REQUEST_TYPE_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT) /* * AVR-USB model @@ -722,7 +725,7 @@ int fasdr_init(RIG *rig) int fasdr_open(RIG *rig) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret,i; double f; unsigned char buffer[4]; @@ -731,22 +734,24 @@ int fasdr_open(RIG *rig) rig_debug(RIG_DEBUG_TRACE,"%s called\n", __func__); - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, - (char *) &version, sizeof(version), rig->state.rigport.timeout); + (unsigned char *) &version, sizeof(version), rig->state.rigport.timeout); if (ret != 2) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } + // Does version needs endianess ordering ? + priv->version = version; // Unsure how to get firmware version - ret=usb_control_msg(udh, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, - REQUEST_READ_EEPROM,F_CAL_STATUS,0,(char *) buffer,1, + ret=libusb_control_transfer(udh, + REQUEST_TYPE_IN, + REQUEST_READ_EEPROM,F_CAL_STATUS,0, buffer,1, rig->state.rigport.timeout); if( ret !=1) return -RIG_EIO; @@ -754,9 +759,9 @@ int fasdr_open(RIG *rig) rig_debug(RIG_DEBUG_VERBOSE,"%s: calibration byte %x", __func__,buffer[0]); -// ret = usb_control_msg(udh, -// USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, -// REQUEST_READ_XTALL, 0, 0, (char *) &iFreq, sizeof(iFreq), +// ret = libusb_control_transfer(udh, +// REQUEST_TYPE_IN, +// REQUEST_READ_XTALL, 0, 0, (unsigned char *) &iFreq, sizeof(iFreq), // rig->state.rigport.timeout); if(buffer[0] == 0xFF ) { @@ -765,9 +770,9 @@ int fasdr_open(RIG *rig) } for(i=0; i<4; i++) { - ret = usb_control_msg(udh, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, - REQUEST_READ_EEPROM,F_CRYST + i, 0,(char *) &buffer[i], 1, + ret = libusb_control_transfer(udh, + REQUEST_TYPE_IN, + REQUEST_READ_EEPROM,F_CRYST + i, 0, &buffer[i], 1, rig->state.rigport.timeout); if (ret != 1) return -RIG_EIO; @@ -866,15 +871,17 @@ int si570xxxusb_get_conf(RIG *rig, token_t token, char *val) static int setBPF(RIG *rig, int enable) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; /* allocate enough space for up to 16 filters */ unsigned short FilterCrossOver[16]; int nBytes, i; + // Does FilterCrossOver needs endianess ordering ? + // first find out how may cross over points there are for the 1st bank, use 255 for index - nBytes = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + nBytes = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_FILTERS, 0, 255, - (char *) FilterCrossOver, sizeof(FilterCrossOver), + (unsigned char *) FilterCrossOver, sizeof(FilterCrossOver), rig->state.rigport.timeout); if (nBytes < 0) @@ -882,9 +889,9 @@ static int setBPF(RIG *rig, int enable) if (nBytes > 2) { - nBytes = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + nBytes = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_FILTERS, enable, (nBytes / 2) - 1, - (char *) FilterCrossOver, sizeof(FilterCrossOver), + (unsigned char *) FilterCrossOver, sizeof(FilterCrossOver), rig->state.rigport.timeout); if (nBytes < 0) return -RIG_EIO; @@ -903,7 +910,7 @@ static int setBPF(RIG *rig, int enable) int si570xxxusb_open(RIG *rig) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; unsigned short version; @@ -913,14 +920,14 @@ int si570xxxusb_open(RIG *rig) * Determine firmware */ - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, - (char *) &version, sizeof(version), rig->state.rigport.timeout); + (unsigned char *) &version, sizeof(version), rig->state.rigport.timeout); if (ret != 2) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -931,9 +938,9 @@ int si570xxxusb_open(RIG *rig) rig_debug(RIG_DEBUG_VERBOSE,"%s: detected PE0FKO-like firmware\n", __func__); - ret = usb_control_msg(udh, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, - REQUEST_READ_XTALL, 0, 0, (char *) &iFreq, sizeof(iFreq), + ret = libusb_control_transfer(udh, + REQUEST_TYPE_IN, + REQUEST_READ_XTALL, 0, 0, (unsigned char *) &iFreq, sizeof(iFreq), rig->state.rigport.timeout); if (ret != 4) @@ -955,32 +962,35 @@ int si570xxxusb_open(RIG *rig) } +/* Rem: not reentrant */ const char * si570xxxusb_get_info(RIG *rig) { static char buf[64]; - struct usb_dev_handle *udh = rig->state.rigport.handle; - struct usb_device *q = usb_device(udh); + libusb_device_handle *udh = rig->state.rigport.handle; + struct libusb_device_descriptor desc; int ret; unsigned short version; - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, - (char *) &version, sizeof(version), rig->state.rigport.timeout); + (unsigned char *) &version, sizeof(version), rig->state.rigport.timeout); if (ret != 2) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return NULL; } - sprintf(buf, "USB dev %04d, version: %d.%d", q->descriptor.bcdDevice, + /* always succeeds since libusb-1.0.16 */ + libusb_get_device_descriptor(libusb_get_device(udh), &desc); + + sprintf(buf, "USB dev %04d, version: %d.%d", desc.bcdDevice, (version & 0xFF00) >> 8, version & 0xFF); return buf; } - static const int HS_DIV_MAP[] = {4,5,6,7,-1,9,-1,11}; static int calcDividers(RIG *rig, double f, struct solution* solution) @@ -1057,7 +1067,7 @@ static void setLongWord(uint32_t value, unsigned char * bytes) int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; unsigned char buffer[6]; int request = REQUEST_SET_FREQ; @@ -1093,8 +1103,8 @@ int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq) buffer[0] = theSolution.N1 / 4; buffer[0] = buffer[0] + (theSolution.HS_DIV << 5); - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, - request, value, index, (char*)buffer, sizeof(buffer), rig->state.rigport.timeout); + ret = libusb_control_transfer(udh, REQUEST_TYPE_OUT, + request, value, index, buffer, sizeof(buffer), rig->state.rigport.timeout); rig_debug(RIG_DEBUG_TRACE, "%s: Freq=%.6f MHz, Real=%.6f MHz, buf=%02x%02x%02x%02x%02x%02x\n", __func__, freq/1e6, f, @@ -1102,9 +1112,9 @@ int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq) if (!ret) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -1117,7 +1127,7 @@ int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq) int si570xxxusb_set_freq_by_value(RIG *rig, vfo_t vfo, freq_t freq) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; unsigned char buffer[4]; @@ -1134,13 +1144,13 @@ int si570xxxusb_set_freq_by_value(RIG *rig, vfo_t vfo, freq_t freq) __func__, freq/1e6, f, buffer[0], buffer[1], buffer[2], buffer[3]); - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, - request, value, index, (char*)buffer, sizeof(buffer), rig->state.rigport.timeout); + ret = libusb_control_transfer(udh, REQUEST_TYPE_OUT, + request, value, index, buffer, sizeof(buffer), rig->state.rigport.timeout); if (!ret) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -1182,7 +1192,7 @@ static double calculateFrequency(RIG *rig, const unsigned char * buffer) int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; unsigned char buffer[6]; int ret; @@ -1190,14 +1200,14 @@ int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) rig->caps->rig_model == RIG_MODEL_SI570PEABERRY1 || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY2) return si570xxxusb_get_freq_by_value(rig, vfo, freq); - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_REGISTERS, priv->i2c_addr, 0, - (char *)buffer, sizeof(buffer), rig->state.rigport.timeout); + buffer, sizeof(buffer), rig->state.rigport.timeout); if (ret <= 0) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -1209,18 +1219,20 @@ int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) int si570xxxusb_get_freq_by_value(RIG *rig, vfo_t vfo, freq_t *freq) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *)rig->state.priv; - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; uint32_t iFreq; - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + // Does iFreq needs endianess ordering ? + + ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_FREQUENCY, 0, 0, - (char *)&iFreq, sizeof(iFreq), rig->state.rigport.timeout); + (unsigned char *)&iFreq, sizeof(iFreq), rig->state.rigport.timeout); if (ret != 4) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } @@ -1232,9 +1244,9 @@ int si570xxxusb_get_freq_by_value(RIG *rig, vfo_t vfo, freq_t *freq) int si570xxxusb_set_ptt(RIG * rig, vfo_t vfo, ptt_t ptt) { - struct usb_dev_handle *udh = rig->state.rigport.handle; + libusb_device_handle *udh = rig->state.rigport.handle; int ret; - char buffer[3]; + unsigned char buffer[3]; rig_debug(RIG_DEBUG_TRACE,"%s called: %d\n", __func__, ptt); @@ -1242,17 +1254,17 @@ int si570xxxusb_set_ptt(RIG * rig, vfo_t vfo, ptt_t ptt) buffer[1] = 0; buffer[2] = 0; - ret = usb_control_msg(udh, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, + ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_SET_PTT, (ptt == RIG_PTT_ON) ? 1 : 0, 0, - (char *)buffer, sizeof(buffer), rig->state.rigport.timeout); + buffer, sizeof(buffer), rig->state.rigport.timeout); if (ret < 0) { - rig_debug (RIG_DEBUG_ERR, "%s: usb_control_msg failed: %s\n", + rig_debug (RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, - usb_strerror ()); + libusb_error_name (ret)); return -RIG_EIO; } return RIG_OK; } -#endif /* defined(HAVE_LIBUSB) && defined(HAVE_USB_H) */ +#endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ diff --git a/src/usb_port.c b/src/usb_port.c index b949b821e..9bc6708a7 100644 --- a/src/usb_port.c +++ b/src/usb_port.c @@ -40,7 +40,7 @@ /* * Compile only if libusb is available */ -#if defined(HAVE_LIBUSB) && defined(HAVE_USB_H) +#if defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) #include @@ -51,131 +51,108 @@ #include #include -#include +#include #include "usb_port.h" -/** - * \brief Get ASCII string from USB descriptor - * \param udh - * \param index - * \param langid - * \param buf - * \param buflen - * \return status/len - */ -static int usbGetStringAscii(usb_dev_handle *udh, int index, int langid, char *buf, int buflen) -{ - char buffer[256]; - int rval, i; - - rval = usb_control_msg(udh, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8) + index, langid, buffer, sizeof(buffer), 1000); - - if(rval < 0) - return rval; - - if(buffer[1] != USB_DT_STRING) - return 0; - - if((unsigned char)buffer[0] < rval) - rval = (unsigned char)buffer[0]; - - rval /= 2; - - /* lossy conversion to ISO Latin1 */ - for(i=1;i buflen) /* destination buffer overflow */ - break; - buf[i - 1] = buffer[2 * i]; - if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ - buf[i - 1] = '?'; - } - - buf[i - 1] = 0; - return i - 1; -} /** * \brief Find and open USB device * \param port * \return usb_handle */ -static struct usb_dev_handle *find_and_open_device(const hamlib_port_t *port) +static libusb_device_handle *find_and_open_device(const hamlib_port_t *port) { - struct usb_bus *bus; - struct usb_device *dev; - struct usb_dev_handle *udh; + libusb_device_handle *udh = NULL; + libusb_device *dev, **devs; + struct libusb_device_descriptor desc; char string[256]; - int len; + int i, r; rig_debug(RIG_DEBUG_VERBOSE, "%s: looking for device %04x:%04x...", __func__, port->parm.usb.vid, port->parm.usb.pid); - for (bus = usb_get_busses(); bus != NULL; bus = bus->next) { - for (dev = bus->devices; dev != NULL; dev = dev->next) { + r = libusb_get_device_list(NULL, &devs); + if (r < 0) { + rig_debug(RIG_DEBUG_ERR, "%s: failed getting usb device list: %s", + __func__, libusb_error_name(r)); + return NULL; + } - rig_debug(RIG_DEBUG_VERBOSE, " %04x:%04x,", - dev->descriptor.idVendor, dev->descriptor.idProduct); - if (dev->descriptor.idVendor == port->parm.usb.vid && - dev->descriptor.idProduct == port->parm.usb.pid) { + for (i=0; (dev=devs[i]) != NULL; i++) { - /* we need to open the device in order to query strings */ - udh = usb_open(dev); - if (!udh) { - rig_debug(RIG_DEBUG_WARN, "%s: Warning: Cannot open USB device: %s\n", __func__, usb_strerror()); + libusb_get_device_descriptor(dev, &desc); + + rig_debug(RIG_DEBUG_VERBOSE, " %04x:%04x,", + desc.idVendor, desc.idProduct); + + if (desc.idVendor == port->parm.usb.vid && + desc.idProduct == port->parm.usb.pid) { + + /* we need to open the device in order to query strings */ + r = libusb_open(dev, &udh); + if (r < 0) { + rig_debug(RIG_DEBUG_WARN, "%s: Warning: Cannot open USB device: %s\n", + __func__, libusb_error_name(r)); + continue; + } + + /* now check whether the names match: */ + if (port->parm.usb.vendor_name) { + + string[0] = '\0'; + r = libusb_get_string_descriptor_ascii(udh, desc.iManufacturer, (unsigned char *)string, sizeof(string)); + if (r < 0) { + rig_debug(RIG_DEBUG_WARN, "Warning: cannot query manufacturer for USB device: %s\n", libusb_error_name(r)); + libusb_close(udh); continue; } - /* now check whether the names match: */ - if (port->parm.usb.vendor_name) { - len = usbGetStringAscii(udh, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string)); - if (len < 0) { - rig_debug(RIG_DEBUG_WARN, "Warning: cannot query manufacturer for USB device: %s\n", usb_strerror()); - usb_close(udh); - continue; - } + rig_debug(RIG_DEBUG_VERBOSE, " vendor >%s<", string); - rig_debug(RIG_DEBUG_VERBOSE, " vendor >%s<", string); - - if (strcmp(string, port->parm.usb.vendor_name) != 0) { - rig_debug(RIG_DEBUG_WARN, "%s: Warning: Vendor name string mismatch!\n", __func__); - usb_close(udh); - continue; - } + if (strcmp(string, port->parm.usb.vendor_name) != 0) { + rig_debug(RIG_DEBUG_WARN, "%s: Warning: Vendor name string mismatch!\n", __func__); + libusb_close(udh); + continue; } - - if (port->parm.usb.product) { - len = usbGetStringAscii(udh, dev->descriptor.iProduct, 0x0409, string, sizeof(string)); - if (len < 0) { - rig_debug(RIG_DEBUG_WARN, "Warning: cannot query product for USB device: %s\n", usb_strerror()); - usb_close(udh); - continue; - } - - rig_debug(RIG_DEBUG_VERBOSE, " product >%s<", string); - - if (strcmp(string, port->parm.usb.product) != 0) { - /* Now testing with strncasecmp() for case insensitive - * match. Updating firmware on FUNcube Dongle to v18f resulted - * in product string changing from "FunCube Dongle" to - * "FUNcube Dongle". As new dongles are shipped with - * older firmware, both product strings are valid. Sigh... - */ - if (strncasecmp(string, port->parm.usb.product, sizeof(port->parm.usb.product - 1)) != 0) { - rig_debug(RIG_DEBUG_WARN, "%s: Warning: Product string mismatch!\n", __func__); - usb_close(udh); - continue; - } - } - } - - rig_debug(RIG_DEBUG_VERBOSE, " -> found\n"); - return udh; } + + if (port->parm.usb.product) { + + string[0] = '\0'; + r = libusb_get_string_descriptor_ascii(udh, desc.iProduct, (unsigned char *)string, sizeof(string)); + if (r < 0) { + rig_debug(RIG_DEBUG_WARN, "Warning: cannot query product for USB device: %s\n", libusb_error_name(r)); + libusb_close(udh); + continue; + } + + rig_debug(RIG_DEBUG_VERBOSE, " product >%s<", string); + + if (strcmp(string, port->parm.usb.product) != 0) { + /* Now testing with strncasecmp() for case insensitive + * match. Updating firmware on FUNcube Dongle to v18f resulted + * in product string changing from "FunCube Dongle" to + * "FUNcube Dongle". As new dongles are shipped with + * older firmware, both product strings are valid. Sigh... + */ + if (strncasecmp(string, port->parm.usb.product, sizeof(port->parm.usb.product - 1)) != 0) { + rig_debug(RIG_DEBUG_WARN, "%s: Warning: Product string mismatch!\n", __func__); + libusb_close(udh); + continue; + } + } + } + + libusb_free_device_list(devs, 1); + + rig_debug(RIG_DEBUG_VERBOSE, " -> found\n"); + return udh; } } + libusb_free_device_list(devs, 1); + rig_debug(RIG_DEBUG_VERBOSE, " -> not found\n"); return NULL; /* not found */ } @@ -188,90 +165,97 @@ static struct usb_dev_handle *find_and_open_device(const hamlib_port_t *port) */ int usb_port_open(hamlib_port_t *port) { - struct usb_dev_handle *udh; + static char pathname[FILPATHLEN]; + libusb_device_handle *udh; char *p, *q; + int r; - usb_init (); /* usb library init */ - if (usb_find_busses () < 0) - rig_debug(RIG_DEBUG_ERR, "%s: usb_find_busses failed %s\n", - __func__, usb_strerror()); - if (usb_find_devices() < 0) - rig_debug(RIG_DEBUG_ERR, "%s: usb_find_devices failed %s\n", - __func__, usb_strerror()); + /* init defaut libusb-1.0 library contexte, if needed */ + r = libusb_init (NULL); + if (r < 0) { + rig_debug(RIG_DEBUG_ERR, "%s: libusb_init failed: %s\n", + __func__, libusb_error_name(r)); + return -RIG_EIO; + } - p = port->pathname; + //libusb_set_debug(NULL, 1); + + /* Extract VID/PID/Vendor/Product name from pathname. */ + /* Duplicate the string since we may modify it. */ + strncpy(pathname, port->pathname, sizeof pathname); + pathname[FILPATHLEN-1] = '\0'; + + p = pathname; q = strchr(p, ':'); if (q) { - if (q != p+1) - port->parm.usb.vid = strtol(q, NULL, 16); - p = q+1; + ++q; + port->parm.usb.vid = strtol(q, NULL, 16); + p = q; q = strchr(p, ':'); if (q) { - if (q != p+1) - port->parm.usb.pid = strtol(q, NULL, 16); - p = q+1; + ++q; + port->parm.usb.pid = strtol(q, NULL, 16); + p = q; q = strchr(p, ':'); if (q) { - if (q != p+1) - port->parm.usb.vendor_name = q; - p = q+1; + ++q; + port->parm.usb.vendor_name = q; + p = q; q = strchr(p, ':'); if (q) { - if (q != p+1) - port->parm.usb.product = q; + *q++ = '\0'; + port->parm.usb.product = q; } } } } udh = find_and_open_device(port); - if (udh == 0) + if (udh == 0) { + libusb_exit (NULL); return -RIG_EIO; + } -#ifdef LIBUSB_HAS_GET_DRIVER_NP - /* Try to detach ftdi_sio kernel module + /* Try to detach ftdi_sio kernel module. * This should be performed only for devices using * USB-serial converters (like FTDI chips), for other * devices this may cause problems, so do not do it. */ - char dname[32] = {0}; - int retval = usb_get_driver_np(udh, port->parm.usb.iface, dname, 31); - if (!retval) { - /* Try to detach ftdi_sio kernel module - * Returns ENODATA if driver is not loaded. - * Don't check return value, let it fail later. - */ - usb_detach_kernel_driver_np(udh, port->parm.usb.iface); - } -#endif + (void)libusb_set_auto_detach_kernel_driver(udh, port->parm.usb.iface); if (port->parm.usb.iface >= 0) { #ifdef _WIN32 + /* Is it still needed with libusb-1.0 ? */ if (port->parm.usb.conf >= 0 && - usb_set_configuration (udh, port->parm.usb.conf) < 0) { - rig_debug(RIG_DEBUG_ERR, "%s: usb_set_configuration: failed conf %d: %s\n", - __func__, port->parm.usb.conf, usb_strerror()); - usb_close (udh); + (r=libusb_set_configuration (udh, port->parm.usb.conf)) < 0) { + rig_debug(RIG_DEBUG_ERR, "%s: libusb_set_configuration: failed conf %d: %s\n", + __func__, port->parm.usb.conf, libusb_error_name(r)); + libusb_close (udh); + libusb_exit (NULL); return -RIG_EIO; } #endif rig_debug(RIG_DEBUG_VERBOSE, "%s: claiming %d\n", __func__, port->parm.usb.iface); - if (usb_claim_interface (udh, port->parm.usb.iface) < 0) { - rig_debug(RIG_DEBUG_ERR, "%s:usb_claim_interface: failed interface %d: %s\n", - __func__,port->parm.usb.iface, usb_strerror()); - usb_close (udh); + r = libusb_claim_interface (udh, port->parm.usb.iface); + if (r < 0) { + rig_debug(RIG_DEBUG_ERR, "%s:libusb_claim_interface: failed interface %d: %s\n", + __func__,port->parm.usb.iface, libusb_error_name(r)); + libusb_close (udh); + libusb_exit (NULL); return -RIG_EIO; } #if 0 - if (usb_set_altinterface (udh, port->parm.usb.alt) < 0) { + r = libusb_set_interface_alt_setting(udh, port->parm.usb.iface, port->parm.usb.alt); + if (r < 0) { fprintf (stderr, "%s:usb_set_alt_interface: failed: %s\n", __func__, - usb_strerror()); - usb_release_interface (udh, port->parm.usb.iface); - usb_close (udh); + libusb_error_name(r)); + libusb_release_interface (udh, port->parm.usb.iface); + libusb_close (udh); + libusb_exit (NULL); return -RIG_EIO; } #endif @@ -290,12 +274,15 @@ int usb_port_open(hamlib_port_t *port) */ int usb_port_close(hamlib_port_t *port) { - struct usb_dev_handle *udh = port->handle; + libusb_device_handle *udh = port->handle; - usb_release_interface (udh, port->parm.usb.iface); + libusb_release_interface(udh, port->parm.usb.iface); - /* we're assuming that closing an interface automatically releases it. */ - return usb_close (udh) == 0 ? RIG_OK : -RIG_EIO; + libusb_close(udh); + + libusb_exit (NULL); + + return RIG_OK; } #else @@ -310,6 +297,6 @@ int usb_port_close(hamlib_port_t *port) return -RIG_ENAVAIL; } -#endif /* defined(HAVE_LIBUSB) && defined(HAVE_USB_H) */ +#endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ /** @} */