Skip to content

Commit 2876705

Browse files
committed
Enable the user to specify the serial number
1 parent e98b506 commit 2876705

1 file changed

Lines changed: 40 additions & 6 deletions

File tree

teensy_loader_cli.c

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void usage(const char *err)
4141
"\t-w : Wait for device to appear\n"
4242
"\t-r : Use hard reboot if device not online\n"
4343
"\t-s : Use soft reboot if device not online (Teensy3.x only)\n"
44+
"\t--serial-number=SERIAL_NUMBER : Serial number to use in conjunction with soft reboot (UNIX only).\n"
4445
"\t-n : No reboot after programming\n"
4546
"\t-b : Boot only, do not program\n"
4647
"\t-v : Verbose output\n"
@@ -74,6 +75,7 @@ void boot(unsigned char *buf, int write_size);
7475
int wait_for_device_to_appear = 0;
7576
int hard_reboot_device = 0;
7677
int soft_reboot_device = 0;
78+
const char * soft_reboot_serial_number = NULL;
7779
int reboot_after_programming = 1;
7880
int verbose = 0;
7981
int boot_only = 0;
@@ -227,13 +229,14 @@ int main(int argc, char **argv)
227229
// http://libusb.sourceforge.net/doc/index.html
228230
#include <usb.h>
229231

230-
usb_dev_handle * open_usb_device(int vid, int pid)
232+
usb_dev_handle * open_usb_device(int vid, int pid, const char *serial_number)
231233
{
232234
struct usb_bus *bus;
233235
struct usb_device *dev;
234236
usb_dev_handle *h;
235237
char buf[128];
236-
int r;
238+
const char * read_serial_number = NULL;
239+
int r, i;
237240

238241
usb_init();
239242
usb_find_busses();
@@ -253,6 +256,33 @@ usb_dev_handle * open_usb_device(int vid, int pid)
253256
printf_verbose("Found device but unable to open\n");
254257
continue;
255258
}
259+
260+
if (serial_number != NULL) {
261+
if (dev->descriptor.iSerialNumber) {
262+
// langid 0x0409 is English US
263+
r = usb_get_string(h, dev->descriptor.iSerialNumber, 0x0409, buf, 128);
264+
if (r < 0) {
265+
usb_close(h);
266+
continue;
267+
}
268+
// Seemsl like 16 bit wide chars are being sent
269+
for (i=0; i < r/2; i++){
270+
buf[i] = buf[i * 2];
271+
}
272+
// The first char seems to be of value 16
273+
// meaning DATA LINK ESCAPE. Who knows what that means???
274+
read_serial_number = &buf[1];
275+
} else {
276+
// No serial number
277+
usb_close(h);
278+
continue;
279+
}
280+
if(strncmp(serial_number, read_serial_number, strlen(serial_number))) {
281+
// Serial number doesn't match
282+
usb_close(h);
283+
continue;
284+
}
285+
}
256286
#ifdef LIBUSB_HAS_GET_DRIVER_NP
257287
r = usb_get_driver_np(h, 0, buf, sizeof(buf));
258288
if (r >= 0) {
@@ -287,7 +317,7 @@ static usb_dev_handle *libusb_teensy_handle = NULL;
287317
int teensy_open(void)
288318
{
289319
teensy_close();
290-
libusb_teensy_handle = open_usb_device(0x16C0, 0x0478);
320+
libusb_teensy_handle = open_usb_device(0x16C0, 0x0478, NULL);
291321
if (libusb_teensy_handle) return 1;
292322
return 0;
293323
}
@@ -321,7 +351,7 @@ int hard_reboot(void)
321351
usb_dev_handle *rebootor;
322352
int r;
323353

324-
rebootor = open_usb_device(0x16C0, 0x0477);
354+
rebootor = open_usb_device(0x16C0, 0x0477, NULL);
325355
if (!rebootor) return 0;
326356
r = usb_control_msg(rebootor, 0x21, 9, 0x0200, 0, "reboot", 6, 100);
327357
usb_release_interface(rebootor, 0);
@@ -334,7 +364,7 @@ int soft_reboot(void)
334364
{
335365
usb_dev_handle *serial_handle = NULL;
336366

337-
serial_handle = open_usb_device(0x16C0, 0x0483);
367+
serial_handle = open_usb_device(0x16C0, 0x0483, soft_reboot_serial_number);
338368
if (!serial_handle) {
339369
char *error = usb_strerror();
340370
printf("Error opening USB device: %s\n", error);
@@ -373,6 +403,8 @@ int soft_reboot(void)
373403
#include <ddk/hidsdi.h>
374404
#include <ddk/hidclass.h>
375405

406+
// Serial number checking not implemented on Windows
407+
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/hidsdi/nf-hidsdi-hidd_getserialnumberstring
376408
HANDLE open_usb_device(int vid, int pid)
377409
{
378410
GUID guid;
@@ -1149,7 +1181,6 @@ void parse_options(int argc, char **argv)
11491181
if(strncmp(arg, "-mmcu=", 6) == 0) {
11501182
read_mcu(strchr(arg, '=') + 1);
11511183
}
1152-
11531184
else if(arg[0] == '-') {
11541185
if(arg[1] == '-') {
11551186
char *name = &arg[2];
@@ -1167,6 +1198,9 @@ void parse_options(int argc, char **argv)
11671198
if(strcasecmp(name, "help") == 0) usage(NULL);
11681199
else if(strcasecmp(name, "mcu") == 0) read_mcu(val);
11691200
else if(strcasecmp(name, "list-mcus") == 0) list_mcus();
1201+
else if(strcasecmp(name, "serial-number") == 0) {
1202+
soft_reboot_serial_number = val;
1203+
}
11701204
else {
11711205
fprintf(stderr, "Unknown option \"%s\"\n\n", arg);
11721206
usage(NULL);

0 commit comments

Comments
 (0)