mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-04 23:49:42 +02:00
tools/lib: atusb can now be selected by bus/device or by bus-port path
Examples: usb:1/6 select logical device 6 on bus 1 usb:1-3.1.4 starting at bus 1, choose ports 3, 1, and 4 - usbopen.c (initialize, open_usb): moved libusb initialization to separate function, to allow for sharing - usbopen.h (restrict_usb_path), usbopen.c (restricted_path, open_usb, restrict_usb_dev, restrict_usb_by_dev, read_num, restrict_usb_by_port, restrict_usb_path): added mechanism to restrict USB path - atusb.c (atusb_open): if an argument is given, call restrict_usb_path with it
This commit is contained in:
parent
a75edf0cc0
commit
fc1ad9fffd
@ -54,6 +54,8 @@ static void *atusb_open(const char *arg)
|
||||
{
|
||||
usb_dev_handle *dev;
|
||||
|
||||
if (arg)
|
||||
restrict_usb_path(arg);
|
||||
dev = open_usb(USB_VENDOR, USB_PRODUCT);
|
||||
if (dev) {
|
||||
error = 0;
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* lib/usbopen.c - Common USB device lookup and open code
|
||||
*
|
||||
* Written 2008-2010 by Werner Almesberger
|
||||
* Copyright 2008-2010 Werner Almesberger
|
||||
* Written 2008-2011 by Werner Almesberger
|
||||
* Copyright 2008-2011 Werner Almesberger
|
||||
*
|
||||
* 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
|
||||
@ -12,16 +12,37 @@
|
||||
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <usb.h>
|
||||
|
||||
#include "usbopen.h"
|
||||
|
||||
|
||||
#define USB_PATH_ROOT "/sys/bus/usb/devices/"
|
||||
#define USB_BUS_LEAF "/busnum"
|
||||
#define USB_DEV_LEAF "/devnum"
|
||||
|
||||
static uint16_t vendor = 0;
|
||||
static uint16_t product = 0;
|
||||
static const struct usb_device *restricted_path = NULL;
|
||||
|
||||
|
||||
static void initialize(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = 1;
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
}
|
||||
|
||||
|
||||
usb_dev_handle *open_usb(uint16_t default_vendor, uint16_t default_product)
|
||||
@ -33,12 +54,12 @@ usb_dev_handle *open_usb(uint16_t default_vendor, uint16_t default_product)
|
||||
int res;
|
||||
#endif
|
||||
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
initialize();
|
||||
|
||||
for (bus = usb_get_busses(); bus; bus = bus->next)
|
||||
for (dev = bus->devices; dev; dev = dev->next) {
|
||||
if (restricted_path && restricted_path != dev)
|
||||
continue;
|
||||
if (dev->descriptor.idVendor !=
|
||||
(vendor ? vendor : default_vendor))
|
||||
continue;
|
||||
@ -99,3 +120,111 @@ void parse_usb_id(const char *id)
|
||||
bad_id(id);
|
||||
product = tmp;
|
||||
}
|
||||
|
||||
|
||||
static void restrict_usb_dev(int bus_num, int dev_num)
|
||||
{
|
||||
const struct usb_bus *bus;
|
||||
const struct usb_device *dev;
|
||||
|
||||
initialize();
|
||||
|
||||
for (bus = usb_busses; bus; bus = bus->next) {
|
||||
if (atoi(bus->dirname) != bus_num)
|
||||
continue;
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
if (dev->devnum == dev_num) {
|
||||
restricted_path = dev;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "no device %d/%d\n", bus_num, dev_num);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void restrict_usb_by_dev(const char *path)
|
||||
{
|
||||
int bus_num, dev_num;
|
||||
|
||||
if (sscanf(path, "%d/%d", &bus_num, &dev_num) != 2) {
|
||||
fprintf(stderr, "invalid device syntax \"%s\"\n", path);
|
||||
exit(1);
|
||||
}
|
||||
restrict_usb_dev(bus_num, dev_num);
|
||||
}
|
||||
|
||||
|
||||
static int read_num(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
FILE *file;
|
||||
char *buf;
|
||||
int n, num;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
buf = malloc(n+1);
|
||||
if (!buf) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
file = fopen(buf, "r");
|
||||
if (!file) {
|
||||
perror(buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n = fscanf(file, "%d", &num);
|
||||
if (n <0) {
|
||||
perror(buf);
|
||||
exit(1);
|
||||
}
|
||||
if (n != 1) {
|
||||
fprintf(stderr, "%s: can't read number\n", buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
free(buf);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
static void restrict_usb_by_port(const char *path)
|
||||
{
|
||||
const char *p;
|
||||
int bus_num, dev_num;
|
||||
|
||||
/*
|
||||
* We sanitize the path, in case we're part of a program running with
|
||||
* suid.
|
||||
*/
|
||||
for (p = path; *p; p++)
|
||||
if (!strchr("0123456789-.", *p)) {
|
||||
fprintf(stderr,
|
||||
"invalid character \'%c\' in USB path\n", *p);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bus_num = read_num("%s%s%s", USB_PATH_ROOT, path, USB_BUS_LEAF);
|
||||
dev_num = read_num("%s%s%s", USB_PATH_ROOT, path, USB_DEV_LEAF);
|
||||
restrict_usb_dev(bus_num, dev_num);
|
||||
}
|
||||
|
||||
|
||||
void restrict_usb_path(const char *path)
|
||||
{
|
||||
if (strchr(path, '/'))
|
||||
restrict_usb_by_dev(path);
|
||||
else
|
||||
restrict_usb_by_port(path);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* lib/usbopen.h - Common USB device lookup and open code
|
||||
*
|
||||
* Written 2008-2010 by Werner Almesberger
|
||||
* Copyright 2008-2010 Werner Almesberger
|
||||
* Written 2008-2011 by Werner Almesberger
|
||||
* Copyright 2008-2011 Werner Almesberger
|
||||
*
|
||||
* 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
|
||||
@ -20,5 +20,6 @@
|
||||
|
||||
usb_dev_handle *open_usb(uint16_t default_vendor, uint16_t default_product);
|
||||
void parse_usb_id(const char *id);
|
||||
void restrict_usb_path(const char *path);
|
||||
|
||||
#endif /* !USB_OPEN_H */
|
||||
|
Loading…
Reference in New Issue
Block a user