summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libusb/core.c59
-rw-r--r--libusb/libusb-1.0.def2
-rw-r--r--libusb/libusb.h25
-rw-r--r--libusb/libusbi.h1
-rw-r--r--libusb/version_nano.h2
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