diff --git a/tools/lib/atben.c b/tools/lib/atben.c index 03175ca..fa0c5eb 100644 --- a/tools/lib/atben.c +++ b/tools/lib/atben.c @@ -183,7 +183,7 @@ static void atben_reset_rf(void *handle) } -static void *atben_open(void) +static void *atben_open(const char *arg) { struct atben_dsc *dsc; diff --git a/tools/lib/atrf.c b/tools/lib/atrf.c index 08bc6c1..ab26fe4 100644 --- a/tools/lib/atrf.c +++ b/tools/lib/atrf.c @@ -13,6 +13,8 @@ #include #include +#include +#include /* for strcasecmp */ #include "at86rf230.h" @@ -25,7 +27,7 @@ extern struct atrf_driver atben_driver; struct atrf_dsc { - struct atrf_driver *driver; + const struct atrf_driver *driver; void *handle; enum atrf_chip_id chip_id; }; @@ -85,20 +87,63 @@ static enum atrf_chip_id identify(struct atrf_dsc *dsc) } -struct atrf_dsc *atrf_open(void) +const static struct atrf_driver *drivers[] = { +#ifdef HAVE_BEN + &atben_driver, +#endif +#ifdef HAVE_USB + &atusb_driver, +#endif + NULL +}; + + +static const struct atrf_driver *select_driver(const char *arg, + const char **opt) +{ + const struct atrf_driver **drv; + const char *end; + size_t len; + + if (!*drivers) { + fprintf(stderr, "no drivers defined\n"); + return NULL; + } + + *opt = NULL; + if (!arg) { + return *drivers; + } + + end = strchr(arg, ':'); + if (!end) + end = strchr(arg, 0); + len = arg-end; + for (drv = drivers; *drv; drv++) + if (!strncasecmp((*drv)->name, arg, len) && + strlen((*drv)->name) == len) + break; + if (!*drv) { + fprintf(stderr, "no driver \"%.*s\" found\n", (int) len, arg); + return NULL; + } + if (*end) + *opt = end+1; + return *drv; +} + + +static struct atrf_dsc *do_atrf_open(const char *arg) { struct atrf_dsc *dsc; - struct atrf_driver *driver; + const struct atrf_driver *driver; + const char *opt; void *handle; -#ifdef HAVE_USB - driver = &atusb_driver; -#elif HAVE_BEN - driver = &atben_driver; -#else -#error Need either HAVE_USB or HAVE_BEN -#endif - handle = driver->open(); + driver = select_driver(arg, &opt); + if (!driver) + return NULL; + handle = driver->open(opt); if (!handle) return NULL; dsc = malloc(sizeof(*dsc)); @@ -113,6 +158,12 @@ struct atrf_dsc *atrf_open(void) } +struct atrf_dsc *atrf_open(void) +{ + return do_atrf_open(NULL); +} + + void atrf_close(struct atrf_dsc *dsc) { if (dsc->driver->close) diff --git a/tools/lib/atusb.c b/tools/lib/atusb.c index 63bd8cb..94480b5 100644 --- a/tools/lib/atusb.c +++ b/tools/lib/atusb.c @@ -50,7 +50,7 @@ static int atusb_clear_error(void *dsc) /* ----- open/close -------------------------------------------------------- */ -static void *atusb_open(void) +static void *atusb_open(const char *arg) { usb_dev_handle *dev; @@ -281,7 +281,7 @@ struct atrf_driver atusb_driver = { .reset = atusb_reset, .reset_rf = atusb_reset_rf, .test_mode = atusb_test_mode, - .slp_tr = NULL, /* @@@ not yet * + .slp_tr = NULL, /* @@@ not yet */ .set_clkm = atusb_set_clkm, .reg_write = atusb_reg_write, .reg_read = atusb_reg_read, diff --git a/tools/lib/driver.h b/tools/lib/driver.h index 13d1dc2..e6e499b 100644 --- a/tools/lib/driver.h +++ b/tools/lib/driver.h @@ -19,7 +19,7 @@ struct atrf_driver { const char *name; - void *(*open)(void); + void *(*open)(const char *arg); void (*close)(void *dsc); int (*error)(void *dsc); int (*clear_error)(void *dsc);