diff options
-rw-r--r-- | libusb/core.c | 59 | ||||
-rw-r--r-- | libusb/libusb-1.0.def | 2 | ||||
-rw-r--r-- | libusb/libusb.h | 25 | ||||
-rw-r--r-- | libusb/libusbi.h | 1 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
5 files changed, 87 insertions, 2 deletions
diff --git a/libusb/core.c b/libusb/core.c index 50f92f6..8cb598d 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -51,6 +51,9 @@ static const struct libusb_version libusb_version_internal = static int default_context_refcnt = 0; static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER; static struct timespec timestamp_origin = { 0, 0 }; +#ifndef USE_SYSTEM_LOGGING_FACILITY +static libusb_log_cb log_handler = NULL; +#endif usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER; struct list_head active_contexts_list; @@ -424,6 +427,7 @@ if (cfg != desired) * - libusb_set_auto_detach_kernel_driver() * - libusb_set_configuration() * - libusb_set_debug() + * - libusb_set_log_cb() * - libusb_set_interface_alt_setting() * - libusb_set_iso_packet_lengths() * - libusb_set_option() @@ -2026,6 +2030,49 @@ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) } /** \ingroup libusb_lib + * Set log handler. + * + * libusb will redirect its log messages to the provided callback function. + * libusb supports redirection of per context and global log messages. + * Log messages sent to the context will be sent to the global log handler too. + * + * If libusb is compiled without message logging or USE_SYSTEM_LOGGING_FACILITY + * is defined then global callback function will never be called. + * If ENABLE_DEBUG_LOGGING is defined then per context callback function will + * never be called. + * + * \param ctx context on which to assign log handler, or NULL for the default + * context. Parameter ignored if only LIBUSB_LOG_CB_GLOBAL mode is requested. + * \param cb pointer to the callback function, or NULL to stop log + * messages redirection + * \param mode mode of callback function operation. Several modes can be + * selected for a single callback function, see \ref libusb_log_cb_mode for + * a description. + * \see libusb_log_cb, libusb_log_cb_mode + */ +void API_EXPORTED libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, + int mode) +{ +#if !defined(USE_SYSTEM_LOGGING_FACILITY) + if (mode & LIBUSB_LOG_CB_GLOBAL) { + log_handler = cb; + } +#endif +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) + if (mode & LIBUSB_LOG_CB_CONTEXT) { + USBI_GET_CONTEXT(ctx); + ctx->log_handler = cb; + } +#else + UNUSED(ctx); +#if defined(USE_SYSTEM_LOGGING_FACILITY) + UNUSED(cb); + UNUSED(mode); +#endif +#endif +} + +/** \ingroup libusb_lib * Set an option in the library. * * Use this function to configure a specific option within the library. @@ -2393,7 +2440,11 @@ static void usbi_log_str(enum libusb_log_level level, const char *str) fputs(str, stderr); #endif #else - fputs(str, stderr); + /* Global log handler */ + if (log_handler != NULL) + log_handler(NULL, level, str); + else + fputs(str, stderr); #endif /* USE_SYSTEM_LOGGING_FACILITY */ UNUSED(level); } @@ -2494,6 +2545,12 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, strcpy(buf + header_len + text_len, USBI_LOG_LINE_END); usbi_log_str(level, buf); + + /* Per context log handler */ +#ifndef ENABLE_DEBUG_LOGGING + if (ctx && ctx->log_handler) + ctx->log_handler(ctx, level, buf); +#endif } void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def index 3fd4b6b..6eba4ff 100644 --- a/libusb/libusb-1.0.def +++ b/libusb/libusb-1.0.def @@ -148,6 +148,8 @@ EXPORTS libusb_set_configuration@8 = libusb_set_configuration libusb_set_debug libusb_set_debug@8 = libusb_set_debug + libusb_set_log_cb + libusb_set_log_cb@12 = libusb_set_log_cb libusb_set_interface_alt_setting libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting libusb_set_option diff --git a/libusb/libusb.h b/libusb/libusb.h index 430136b..08d8487 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -1294,10 +1294,35 @@ enum libusb_log_level { LIBUSB_LOG_LEVEL_DEBUG = 4, }; +/** \ingroup libusb_lib + * Log callback mode. + * \see libusb_set_log_cb() + */ +enum libusb_log_cb_mode { + + /** Callback function handling all log mesages. */ + LIBUSB_LOG_CB_GLOBAL = 1 << 0, + + /** Callback function handling context related log mesages. */ + LIBUSB_LOG_CB_CONTEXT = 1 << 1 +}; + +/** \ingroup libusb_lib + * Callback function for handling log messages. + * \param ctx the context which is related to the log message, or NULL if it + * is a global log message + * \param level the log level, see \ref libusb_log_level for a description + * \param str the log message + * \see libusb_set_log_cb() + */ +typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx, + enum libusb_log_level level, const char *str); + int LIBUSB_CALL libusb_init(libusb_context **ctx); void LIBUSB_CALL libusb_exit(libusb_context *ctx); LIBUSB_DEPRECATED_FOR(libusb_set_option) void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode); const struct libusb_version * LIBUSB_CALL libusb_get_version(void); int LIBUSB_CALL libusb_has_capability(uint32_t capability); const char * LIBUSB_CALL libusb_error_name(int errcode); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 31d6ce9..da54ff1 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -293,6 +293,7 @@ struct libusb_context { #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) enum libusb_log_level debug; int debug_fixed; + libusb_log_cb log_handler; #endif /* internal event pipe, used for signalling occurrence of an internal event. */ diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 9f9c55c..328afa9 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11318 +#define LIBUSB_NANO 11319 |