Skip to content

Commit

Permalink
Issue avrdudes#973: Differentiate multiple USB programmers of the sam…
Browse files Browse the repository at this point in the history
…e VID/PID (libusb or hidapi or libftdi)

Added code for USBasp to check for bus:device match using the -P option. Syntax is -P usb:<bus>:<device> (same as current USBTiny implementation).

This also supports serial number check with the alternative -P usb:<serial_number> format (no ':').

In verbose mode, prints out bus/device/serial number for any found USBasps.

Only tested on Linux, but it works with HAVE_LIBUSB_1_0 on or off (there's some slightly different code in the two versions of usbOpenDevice()).
  • Loading branch information
MikeRaffa committed Dec 4, 2023
1 parent 5501c63 commit 447b176
Showing 1 changed file with 63 additions and 9 deletions.
72 changes: 63 additions & 9 deletions src/usbasp.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,9 @@ static int usbasp_transmit(const PROGRAMMER *pgm, unsigned char receive,
unsigned char functionid, const unsigned char *send,
unsigned char *buffer, int buffersize);
#ifdef USE_LIBUSB_1_0
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName);
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName, const char *port);
#else
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName);
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName, const char *port);
#endif
// interface - prog.
static int usbasp_open(PROGRAMMER *pgm, const char *port);
Expand Down Expand Up @@ -399,6 +399,37 @@ static int usbasp_transmit(const PROGRAMMER *pgm,
return nbytes;
}

static int check_for_port_argument_match(const char *port, char *bus, char *device, char *serial_num) {

if (verbose) {
pmsg_notice("usbOpenDevice(): found USBasp, bus:device: %s:%s, serial_number: %s\n", bus, device, serial_num);
}
const size_t usb_len = strlen("usb");
if(str_starts(port, "usb") && ':' == port[usb_len]) {
port += usb_len + 1;
char *colon_pointer = strchr(port, ':');
if (colon_pointer) {
// Value contains ':' character. Compare with bus/device.
if (strncmp(port, bus, colon_pointer - port)) {
return 1;
}
port = colon_pointer + 1;
if (strcmp(port, device)) {
return 1;
}
return 0;
} else {
// serial number case
if (!str_eq(serial_num, port)) {
return 1;
} else {
return 0;
}
}
}
// Invalid -P option.
return 1;
}

/*
* Try to open USB device with given VID, PID, vendor and product name
Expand All @@ -407,8 +438,8 @@ static int usbasp_transmit(const PROGRAMMER *pgm,
* shared VID/PID
*/
#ifdef USE_LIBUSB_1_0
static int usbOpenDevice(libusb_device_handle **device, int vendor,
const char *vendorName, int product, const char *productName)
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName,
int product, const char *productName, const char *port)
{
libusb_device_handle *handle = NULL;
int errorCode = USB_ERROR_NOTFOUND;
Expand Down Expand Up @@ -463,6 +494,19 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName))
errorCode = USB_ERROR_NOTFOUND;
}
if (errorCode == 0) {
if(!str_eq(port, "usb")) {
// -P option given
libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber, (unsigned char*)string, sizeof(string));
char bus_num[4];
sprintf(bus_num, "%d", libusb_get_bus_number(dev));
char dev_addr[4];
sprintf(dev_addr, "%d", libusb_get_device_address(dev));
if (check_for_port_argument_match(port, bus_num, dev_addr, string)) {
errorCode = USB_ERROR_NOTFOUND;
}
}
}
if (errorCode == 0)
break;
libusb_close(handle);
Expand All @@ -477,8 +521,8 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
return errorCode;
}
#else
static int usbOpenDevice(usb_dev_handle **device, int vendor,
const char *vendorName, int product, const char *productName)
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName,
int product, const char *productName, const char *port)
{
struct usb_bus *bus;
struct usb_device *dev;
Expand Down Expand Up @@ -533,6 +577,16 @@ static int didUsbInit = 0;
if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName))
errorCode = USB_ERROR_NOTFOUND;
}
if (errorCode == 0) {
if(!str_eq(port, "usb")) {
// -P option given
usb_get_string_simple(handle, dev->descriptor.iSerialNumber,
string, sizeof(string));
if (check_for_port_argument_match(port, bus->dirname, dev->filename, string)) {
errorCode = USB_ERROR_NOTFOUND;
}
}
}
if (errorCode == 0)
break;
usb_close(handle);
Expand Down Expand Up @@ -566,14 +620,14 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) {
pid = USBASP_SHARED_PID;
}
vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID;
if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct) != 0) {
if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) {
/* try alternatives */
if(str_eq(pgmid, "usbasp")) {
/* for id usbasp autodetect some variants */
if(str_caseeq(port, "nibobee")) {
pmsg_error("using -C usbasp -P nibobee is deprecated, use -C nibobee instead\n");
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com",
USBASP_NIBOBEE_PID, "NIBObee") != 0) {
USBASP_NIBOBEE_PID, "NIBObee", port) != 0) {
pmsg_error("cannot find USB device NIBObee with vid=0x%x pid=0x%x\n",
USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID);
return -1;
Expand All @@ -582,7 +636,7 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) {
}
/* check if device with old VID/PID is available */
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
USBASP_OLD_PID, "USBasp") == 0) {
USBASP_OLD_PID, "USBasp", port) == 0) {
/* found USBasp with old IDs */
pmsg_error("found USB device USBasp with old VID/PID; please update firmware of USBasp\n");
return 0;
Expand Down

0 comments on commit 447b176

Please sign in to comment.