X-Git-Url: https://git.ao2.it/libam7xxx.git/blobdiff_plain/a27837d8dd8b78b4fcc9224d83d2f85fdf8eb19f..d2b3bd440d4700abf2e6b503d3a864af1496026e:/src/am7xxx.c diff --git a/src/am7xxx.c b/src/am7xxx.c index 11c259d..4cfc9a9 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,27 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/* If we're not using GNU C, elide __attribute__ + * taken from: http://unixwiz.net/techtips/gnu-c-attributes.html) + */ +#ifndef __GNUC__ +# define __attribute__(x) /*NOTHING*/ +#endif + +static void log_message(am7xxx_context *ctx, + int level, + const char *function, + int line, + const char *fmt, + ...) __attribute__ ((format (printf, 5, 6))); + +#define fatal(...) log_message(NULL, AM7XXX_LOG_FATAL, __func__, __LINE__, __VA_ARGS__) +#define error(ctx, ...) log_message(ctx, AM7XXX_LOG_ERROR, __func__, __LINE__, __VA_ARGS__) +#define warning(ctx, ...) log_message(ctx, AM7XXX_LOG_WARNING, __func__, 0, __VA_ARGS__) +#define info(ctx, ...) log_message(ctx, AM7XXX_LOG_INFO, __func__, 0, __VA_ARGS__) +#define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) +#define trace(ctx, ...) log_message(ctx, AM7XXX_LOG_TRACE, NULL, 0, __VA_ARGS__) + struct am7xxx_usb_device_descriptor { const char *name; uint16_t vendor_id; @@ -55,11 +77,13 @@ static struct am7xxx_usb_device_descriptor supported_devices[] = { struct _am7xxx_device { libusb_device_handle *usb_device; uint8_t buffer[AM7XXX_HEADER_WIRE_SIZE]; + am7xxx_context *ctx; am7xxx_device *next; }; struct _am7xxx_context { libusb_context *usb_context; + int log_level; am7xxx_device *devices_list; }; @@ -321,10 +345,47 @@ static int send_header(am7xxx_device *dev, struct am7xxx_header *h) return ret; } -static am7xxx_device *add_new_device(am7xxx_device **devices_list) +/* When level == AM7XXX_LOG_FATAL do not check the log_level from the context + * and print the message unconditionally, this makes it possible to print + * fatal messages even early on initialization, before the context has been + * set up */ +static void log_message(am7xxx_context *ctx, + int level, + const char *function, + int line, + const char *fmt, + ...) { + va_list ap; + + if (level == AM7XXX_LOG_FATAL || (ctx && level <= ctx->log_level)) { + if (function) { + fprintf(stderr, "%s", function); + if (line) + fprintf(stderr, "[%d]", line); + fprintf(stderr, ": "); + } + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + } + + return; +} + +static am7xxx_device *add_new_device(am7xxx_context *ctx) +{ + am7xxx_device **devices_list; am7xxx_device *new_device; + if (ctx == NULL) { + fprintf(stderr, "%s: context must not be NULL!\n", __func__); + return NULL; + } + + devices_list = &(ctx->devices_list); + new_device = malloc(sizeof(*new_device)); if (new_device == NULL) { perror("malloc"); @@ -332,6 +393,8 @@ static am7xxx_device *add_new_device(am7xxx_device **devices_list) } memset(new_device, 0, sizeof(*new_device)); + new_device->ctx = ctx; + if (*devices_list == NULL) { *devices_list = new_device; } else { @@ -343,12 +406,18 @@ static am7xxx_device *add_new_device(am7xxx_device **devices_list) return new_device; } -static am7xxx_device *find_device(am7xxx_device *devices_list, +static am7xxx_device *find_device(am7xxx_context *ctx, unsigned int device_index) { unsigned int i = 0; - am7xxx_device *current = devices_list; + am7xxx_device *current; + if (ctx == NULL) { + fprintf(stderr, "%s: context must not be NULL!\n", __func__); + return NULL; + } + + current = ctx->devices_list; while (current && i++ < device_index) current = current->next; @@ -420,7 +489,7 @@ static int scan_devices(am7xxx_context *ctx, scan_op op, printf("am7xxx device found, index: %d, name: %s\n", current_index, supported_devices[j].name); - new_device = add_new_device(&(ctx->devices_list)); + new_device = add_new_device(ctx); if (new_device == NULL) { /* XXX, the caller may want * to call am7xxx_shutdown() if @@ -433,7 +502,7 @@ static int scan_devices(am7xxx_context *ctx, scan_op op, } else if (op == SCAN_OP_OPEN_DEVICE && current_index == open_device_index) { - *dev = find_device(ctx->devices_list, open_device_index); + *dev = find_device(ctx, open_device_index); if (*dev == NULL) { ret = -ENODEV; goto out; @@ -483,6 +552,9 @@ int am7xxx_init(am7xxx_context **ctx) } memset(*ctx, 0, sizeof(**ctx)); + /* Set the highest log level during initialization */ + (*ctx)->log_level = AM7XXX_LOG_TRACE; + ret = libusb_init(&((*ctx)->usb_context)); if (ret < 0) goto out_free_context; @@ -496,6 +568,8 @@ int am7xxx_init(am7xxx_context **ctx) goto out; } + /* Set a quieter log level as default for normal operation */ + (*ctx)->log_level = AM7XXX_LOG_ERROR; return 0; out_free_context: @@ -527,6 +601,11 @@ void am7xxx_shutdown(am7xxx_context *ctx) ctx = NULL; } +void am7xxx_set_log_level(am7xxx_context *ctx, am7xxx_log_level log_level) +{ + ctx->log_level = log_level; +} + int am7xxx_open_device(am7xxx_context *ctx, am7xxx_device **dev, unsigned int device_index) {