summaryrefslogtreecommitdiff
path: root/ao-tools/lib/cc-usbdev.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-09-04 14:21:19 -0700
committerKeith Packard <keithp@keithp.com>2009-09-04 14:21:19 -0700
commit0935d6a7e907e20381a42882ae728051f9bece02 (patch)
treeb2a591c1679a9c7f38dfbf8bb419556405857d74 /ao-tools/lib/cc-usbdev.c
parent0c771d999914f9d17c723900f2987acc45fd0fbb (diff)
Parse the USB serial number as an integer.
AltOS devices use simple integer serial numbers, so parse the USB value as such to make matching values more forgiving. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'ao-tools/lib/cc-usbdev.c')
-rw-r--r--ao-tools/lib/cc-usbdev.c97
1 files changed, 93 insertions, 4 deletions
diff --git a/ao-tools/lib/cc-usbdev.c b/ao-tools/lib/cc-usbdev.c
index d8bb8b11..ed39c062 100644
--- a/ao-tools/lib/cc-usbdev.c
+++ b/ao-tools/lib/cc-usbdev.c
@@ -16,8 +16,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
+#define _GNU_SOURCE
#include "cc.h"
-
#include <ctype.h>
#include <dirent.h>
#include <stdio.h>
@@ -65,6 +65,23 @@ load_hex(char *dir, char *file)
}
static int
+load_dec(char *dir, char *file)
+{
+ char *line;
+ char *end;
+ long i;
+
+ line = load_string(dir, file);
+ if (!line)
+ return -1;
+ i = strtol(line, &end, 10);
+ free(line);
+ if (end == line)
+ return -1;
+ return i;
+}
+
+static int
dir_filter_tty_colon(const struct dirent *d)
{
return strncmp(d->d_name, "tty:", 4) == 0;
@@ -141,7 +158,7 @@ usb_scan_device(char *sys)
usbdev->sys = strdup(sys);
usbdev->manufacturer = load_string(sys, "manufacturer");
usbdev->product = load_string(sys, "product");
- usbdev->serial = load_string(sys, "serial");
+ usbdev->serial = load_dec(sys, "serial");
usbdev->idProduct = load_hex(sys, "idProduct");
usbdev->idVendor = load_hex(sys, "idVendor");
usbdev->tty = usb_tty(sys);
@@ -154,8 +171,9 @@ usbdev_free(struct cc_usbdev *usbdev)
free(usbdev->sys);
free(usbdev->manufacturer);
free(usbdev->product);
- free(usbdev->serial);
- free(usbdev->tty);
+ /* this can get used as a return value */
+ if (usbdev->tty)
+ free(usbdev->tty);
free(usbdev);
}
@@ -226,3 +244,74 @@ cc_usbdevs_free(struct cc_usbdevs *usbdevs)
usbdev_free(usbdevs->dev[i]);
free(usbdevs);
}
+
+static char *
+match_dev(char *product, int serial)
+{
+ struct cc_usbdevs *devs;
+ struct cc_usbdev *dev;
+ int i;
+ char *tty = NULL;
+
+ devs = cc_usbdevs_scan();
+ if (!devs)
+ return NULL;
+ for (i = 0; i < devs->ndev; i++) {
+ dev = devs->dev[i];
+ if (product && strcmp (product, dev->product) != 0)
+ continue;
+ if (serial && serial != dev->serial)
+ continue;
+ break;
+ }
+ if (i < devs->ndev) {
+ tty = devs->dev[i]->tty;
+ devs->dev[i]->tty = NULL;
+ }
+ cc_usbdevs_free(devs);
+ return tty;
+}
+
+char *
+cc_usbdevs_find_by_arg(char *arg, char *default_product)
+{
+ char *product;
+ int serial;
+ char *end;
+ char *colon;
+ char *tty;
+
+ if (arg)
+ {
+ /* check for <serial> */
+ serial = strtol(arg, &end, 0);
+ if (end != arg) {
+ if (*end != '\0')
+ return NULL;
+ product = NULL;
+ } else {
+ /* check for <product>:<serial> */
+ colon = strchr(arg, ':');
+ if (colon) {
+ product = strndup(arg, colon - arg);
+ serial = strtol(colon + 1, &end, 0);
+ if (*end != '\0')
+ return NULL;
+ } else {
+ product = arg;
+ serial = 0;
+ }
+ }
+ } else {
+ product = NULL;
+ serial = 0;
+ }
+ tty = NULL;
+ if (!product && default_product)
+ tty = match_dev(default_product, serial);
+ if (!tty)
+ tty = match_dev(product, serial);
+ if (product && product != arg)
+ free(product);
+ return tty;
+}