summaryrefslogtreecommitdiff
path: root/ao-tools/lib
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
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')
-rw-r--r--ao-tools/lib/cc-usbdev.c97
-rw-r--r--ao-tools/lib/cc.h5
2 files changed, 97 insertions, 5 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;
+}
diff --git a/ao-tools/lib/cc.h b/ao-tools/lib/cc.h
index dad11bf3..0933f272 100644
--- a/ao-tools/lib/cc.h
+++ b/ao-tools/lib/cc.h
@@ -32,7 +32,7 @@ struct cc_usbdev {
char *tty;
char *manufacturer;
char *product;
- char *serial;
+ int serial; /* AltOS always uses simple integer serial numbers */
int idProduct;
int idVendor;
};
@@ -48,4 +48,7 @@ cc_usbdevs_free(struct cc_usbdevs *usbdevs);
struct cc_usbdevs *
cc_usbdevs_scan(void);
+char *
+cc_usbdevs_find_by_arg(char *arg, char *default_product);
+
#endif /* _CC_H_ */