X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Flib%2Fcc-usbdev.c;h=6c3ba5910b3602465e918dc38f7bcec04d700e9f;hp=d8bb8b117c7124dec9304a1d650038d4798e76c2;hb=fce4e6926de7cb5ef6ea64a8db134c442b86153b;hpb=0c771d999914f9d17c723900f2987acc45fd0fbb diff --git a/ao-tools/lib/cc-usbdev.c b/ao-tools/lib/cc-usbdev.c index d8bb8b11..6c3ba591 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 #include #include @@ -64,6 +64,23 @@ load_hex(char *dir, char *file) return i; } +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) { @@ -115,11 +132,23 @@ usb_tty(char *sys) /* Check for tty/ttyACMx style names */ tty_dir = cc_fullname(endpoint_full, "tty"); - free(endpoint_full); ntty = scandir(tty_dir, &namelist, dir_filter_tty, alphasort); free (tty_dir); + if (ntty > 0) { + tty = cc_fullname("/dev", namelist[0]->d_name); + free(endpoint_full); + free(namelist); + return tty; + } + + /* Check for ttyACMx style names + */ + ntty = scandir(endpoint_full, &namelist, + dir_filter_tty, + alphasort); + free(endpoint_full); if (ntty > 0) { tty = cc_fullname("/dev", namelist[0]->d_name); free(namelist); @@ -141,7 +170,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 +183,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); } @@ -179,8 +209,17 @@ dir_filter_dev(const struct dirent *d) return 1; } +static int +is_am(int idVendor, int idProduct) { + if (idVendor == 0xfffe) + return 1; + if (idVendor == 0x0403 && idProduct == 0x6015) + return 1; + return 0; +} + struct cc_usbdevs * -cc_usbdevs_scan(void) +cc_usbdevs_scan(int non_tty) { int e; struct dirent **ents; @@ -202,10 +241,10 @@ cc_usbdevs_scan(void) dir = cc_fullname(USB_DEVICES, ents[e]->d_name); dev = usb_scan_device(dir); free(dir); - if (dev->idVendor == 0xfffe && dev->tty) { + if (is_am(dev->idVendor, dev->idProduct) && (non_tty || dev->tty)) { if (devs->dev) devs->dev = realloc(devs->dev, - devs->ndev + 1 * sizeof (struct usbdev *)); + (devs->ndev + 1) * sizeof (struct usbdev *)); else devs->dev = malloc (sizeof (struct usbdev *)); devs->dev[devs->ndev++] = dev; @@ -226,3 +265,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(FALSE); + if (!devs) + return NULL; + for (i = 0; i < devs->ndev; i++) { + dev = devs->dev[i]; + if (product && strncmp (product, dev->product, strlen(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 = strtol(arg, &end, 0); + if (end != arg) { + if (*end != '\0') + return NULL; + product = NULL; + } else { + /* check for : */ + 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; +}