From 539f22e2fd916558d11ab9a66f10f461c5593168 Mon Sep 17 00:00:00 2001 From: Chris Dickens Date: Mon, 10 Jul 2017 22:37:13 -0700 Subject: [PATCH] core: Introduce libusb_set_option() API function This new function allows more flexibility in extending the library to support more user-configurable options. It is intended to provide a single API that can support a wide variety of needs and eliminates the need for new API functions to set future options. The function is introduced with a single option (LIBUSB_OPTION_LOG_LEVEL) that replaces the libusb_set_debug() function. Documentation relating to libusb_set_debug() and the uses of this function in the examples and tests have been updated accordingly. Signed-off-by: Chris Dickens --- examples/fxload.c | 2 +- examples/xusb.c | 4 +- libusb/core.c | 111 ++++++++++++++++++++++++++++++++------------------ libusb/libusb-1.0.def | 2 + libusb/libusb.h | 49 +++++++++++++++++----- libusb/version_nano.h | 2 +- tests/stress.c | 4 +- 7 files changed, 119 insertions(+), 55 deletions(-) diff --git a/examples/fxload.c b/examples/fxload.c index 5aa5226..1cea9c3 100644 --- a/examples/fxload.c +++ b/examples/fxload.c @@ -178,7 +178,7 @@ int main(int argc, char*argv[]) logerror("libusb_init() failed: %s\n", libusb_error_name(status)); return -1; } - libusb_set_debug(NULL, verbose); + libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, verbose); /* try to pick up missing parameters from known devices */ if ((type == NULL) || (device_id == NULL) || (device_path != NULL)) { diff --git a/examples/xusb.c b/examples/xusb.c index 352a5d7..b2e2424 100644 --- a/examples/xusb.c +++ b/examples/xusb.c @@ -1095,7 +1095,7 @@ int main(int argc, char** argv) } // xusb is commonly used as a debug tool, so it's convenient to have debug output during libusb_init(), - // but since we can't call on libusb_set_debug() before libusb_init(), we use the env variable method + // but since we can't call on libusb_set_option() before libusb_init(), we use the env variable method old_dbg_str = getenv("LIBUSB_DEBUG"); if (debug_mode) { if (putenv("LIBUSB_DEBUG=4") != 0) // LIBUSB_LOG_LEVEL_DEBUG @@ -1110,7 +1110,7 @@ int main(int argc, char** argv) // If not set externally, and no debug option was given, use info log level if ((old_dbg_str == NULL) && (!debug_mode)) - libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_INFO); + libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO); if (error_lang != NULL) { r = libusb_setlocale(error_lang); if (r < 0) diff --git a/libusb/core.c b/libusb/core.c index 5b47194..f21a74f 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -116,15 +116,17 @@ struct list_head active_contexts_list; * libusb uses stderr for all logging. By default, logging is set to NONE, * which means that no output will be produced. However, unless the library * has been compiled with logging disabled, then any application calls to - * libusb_set_debug(), or the setting of the environmental variable - * LIBUSB_DEBUG outside of the application, can result in logging being - * produced. Your application should therefore not close stderr, but instead - * direct it to the null device if its output is undesirable. - * - * The libusb_set_debug() function can be used to enable logging of certain - * messages. Under standard configuration, libusb doesn't really log much - * so you are advised to use this function to enable all error/warning/ - * informational messages. It will help debug problems with your software. + * libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level), or the setting of the + * environmental variable LIBUSB_DEBUG outside of the application, can result + * in logging being produced. Your application should therefore not close + * stderr, but instead direct it to the null device if its output is + * undesirable. + * + * The libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) function can be + * used to enable logging of certain messages. Under standard configuration, + * libusb doesn't really log much so you are advised to use this function + * to enable all error/warning/ informational messages. It will help debug + * problems with your software. * * The logged messages are unstructured. There is no one-to-one correspondence * between messages being logged and success or failure return codes from @@ -139,18 +141,20 @@ struct list_head active_contexts_list; * * The LIBUSB_DEBUG environment variable can be used to enable message logging * at run-time. This environment variable should be set to a log level number, - * which is interpreted the same as the libusb_set_debug() parameter. When this + * which is interpreted the same as the + * libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) parameter. When this * environment variable is set, the message logging verbosity level is fixed - * and libusb_set_debug() effectively does nothing. + * and libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) effectively does + * nothing. * * libusb can be compiled without any logging functions, useful for embedded - * systems. In this case, libusb_set_debug() and the LIBUSB_DEBUG environment - * variable have no effects. + * systems. In this case, libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) + * and the LIBUSB_DEBUG environment variable have no effects. * * libusb can also be compiled with verbose debugging messages always. When * the library is compiled in this way, all messages of all verbosities are - * always logged. libusb_set_debug() and the LIBUSB_DEBUG environment variable - * have no effects. + * always logged. libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, level) and + * the LIBUSB_DEBUG environment variable have no effects. * * \section remarks Other remarks * @@ -297,7 +301,7 @@ if (cfg != desired) * developed modules may both use libusb. * * libusb is written to allow for these multiple user scenarios. The two - * "instances" of libusb will not interfere: libusb_set_debug() calls + * "instances" of libusb will not interfere: libusb_set_option() calls * from one user will not affect the same settings for other users, other * users can continue using libusb after one of them calls libusb_exit(), etc. * @@ -422,6 +426,7 @@ if (cfg != desired) * - libusb_set_debug() * - libusb_set_interface_alt_setting() * - libusb_set_iso_packet_lengths() + * - libusb_set_option() * - libusb_setlocale() * - libusb_set_pollfd_notifiers() * - libusb_strerror() @@ -465,6 +470,7 @@ if (cfg != desired) * - \ref libusb_iso_sync_type * - \ref libusb_iso_usage_type * - \ref libusb_log_level + * - \ref libusb_option * - \ref libusb_request_recipient * - \ref libusb_request_type * - \ref libusb_speed @@ -2002,29 +2008,8 @@ int API_EXPORTED libusb_set_auto_detach_kernel_driver( } /** \ingroup libusb_lib - * Set log message verbosity. - * - * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever - * printed. If you choose to increase the message verbosity level, ensure - * that your application does not close the stdout/stderr file descriptors. - * - * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative - * with its message logging and most of the time, will only log messages that - * explain error conditions and other oddities. This will help you debug - * your software. - * - * If the LIBUSB_DEBUG environment variable was set when libusb was - * initialized, this function does nothing: the message verbosity is fixed - * to the value in the environment variable. - * - * If libusb was compiled without any message logging, this function does - * nothing: you'll never get any messages. - * - * If libusb was compiled with verbose debug message logging, this function - * does nothing: you'll always get messages from all levels. - * - * \param ctx the context to operate on, or NULL for the default context - * \param level debug level to set + * \deprecated Use libusb_set_option() instead using the + * \ref LIBUSB_OPTION_LOG_LEVEL option. */ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) { @@ -2040,6 +2025,54 @@ void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) #endif } +/** \ingroup libusb_lib + * Set an option in the library. + * + * Use this function to configure a specific option within the library. + * + * Some options require one or more arguments to be provided. Consult each + * option's documentation for specific requirements. + * + * Since version 1.0.22, \ref LIBUSB_API_VERSION >= 0x01000106 + * + * \param ctx context on which to operate + * \param option which option to set + * \param ... any required arguments for the specified option + * + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_INVALID_PARAM if the option or arguments are invalid + * \returns LIBUSB_ERROR_NOT_SUPPORTED if the option is valid but not supported + * on this platform + */ +int API_EXPORTED libusb_set_option(libusb_context *ctx, + enum libusb_option option, ...) +{ + int arg, r = LIBUSB_SUCCESS; + va_list ap; + + USBI_GET_CONTEXT(ctx); + + va_start(ap, option); + switch (option) { + case LIBUSB_OPTION_LOG_LEVEL: + arg = va_arg(ap, int); + if (arg < LIBUSB_LOG_LEVEL_NONE || arg > LIBUSB_LOG_LEVEL_DEBUG) { + r = LIBUSB_ERROR_INVALID_PARAM; + break; + } +#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) + if (!ctx->debug_fixed) + ctx->debug = (enum libusb_log_level)arg; +#endif + break; + default: + r = LIBUSB_ERROR_INVALID_PARAM; + } + va_end(ap); + + return r; +} + #if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING) /* returns the log level as defined in the LIBUSB_DEBUG environment variable. * if LIBUSB_DEBUG is not present or not a number, returns LIBUSB_LOG_LEVEL_NONE. diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def index 2443d9b..92c26d4 100644 --- a/libusb/libusb-1.0.def +++ b/libusb/libusb-1.0.def @@ -152,6 +152,8 @@ EXPORTS libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting libusb_setlocale libusb_setlocale@4 = libusb_setlocale + libusb_set_option + libusb_set_option@8 = libusb_set_option libusb_set_pollfd_notifiers libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers libusb_strerror diff --git a/libusb/libusb.h b/libusb/libusb.h index 70ee2ca..480a5ad 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -147,7 +147,7 @@ typedef unsigned __int32 uint32_t; * Internally, LIBUSB_API_VERSION is defined as follows: * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) */ -#define LIBUSB_API_VERSION 0x01000105 +#define LIBUSB_API_VERSION 0x01000106 /* The following is kept for compatibility, but will be deprecated in the future */ #define LIBUSBX_API_VERSION LIBUSB_API_VERSION @@ -921,7 +921,7 @@ struct libusb_version { * sessions allows for your program to use two libraries (or dynamically * load two modules) which both independently use libusb. This will prevent * interference between the individual libusb users - for example - * libusb_set_debug() will not affect the other user of the library, and + * libusb_set_option() will not affect the other user of the library, and * libusb_exit() will not destroy resources that the other user is still * using. * @@ -1278,21 +1278,20 @@ enum libusb_capability { * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stdout, warning - * and error messages are printed to stderr - * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stdout, - * warnings and errors to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stderr */ enum libusb_log_level { LIBUSB_LOG_LEVEL_NONE = 0, - LIBUSB_LOG_LEVEL_ERROR, - LIBUSB_LOG_LEVEL_WARNING, - LIBUSB_LOG_LEVEL_INFO, - LIBUSB_LOG_LEVEL_DEBUG, + LIBUSB_LOG_LEVEL_ERROR = 1, + LIBUSB_LOG_LEVEL_WARNING = 2, + LIBUSB_LOG_LEVEL_INFO = 3, + LIBUSB_LOG_LEVEL_DEBUG = 4, }; 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); const struct libusb_version * LIBUSB_CALL libusb_get_version(void); int LIBUSB_CALL libusb_has_capability(uint32_t capability); @@ -1989,6 +1988,36 @@ int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle callback_handle); +/** \ingroup libusb_lib + * Available option values for libusb_set_option(). + */ +enum libusb_option { + /** Set the log message verbosity. + * + * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever + * printed. If you choose to increase the message verbosity level, ensure + * that your application does not close the stderr file descriptor. + * + * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative + * with its message logging and most of the time, will only log messages that + * explain error conditions and other oddities. This will help you debug + * your software. + * + * If the LIBUSB_DEBUG environment variable was set when libusb was + * initialized, this function does nothing: the message verbosity is fixed + * to the value in the environment variable. + * + * If libusb was compiled without any message logging, this function does + * nothing: you'll never get any messages. + * + * If libusb was compiled with verbose debug message logging, this function + * does nothing: you'll always get messages from all levels. + */ + LIBUSB_OPTION_LOG_LEVEL, +}; + +int LIBUSB_CALL libusb_set_option(libusb_context *ctx, enum libusb_option option, ...); + #ifdef __cplusplus } #endif diff --git a/libusb/version_nano.h b/libusb/version_nano.h index f8a1bfb..2971829 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11210 +#define LIBUSB_NANO 11211 diff --git a/tests/stress.c b/tests/stress.c index 0f50003..0e2dbe5 100644 --- a/tests/stress.c +++ b/tests/stress.c @@ -126,8 +126,8 @@ static libusb_testlib_result test_default_context_change(libusb_testlib_ctx * tc } /* Enable debug output, to be sure to use the context */ - libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_DEBUG); - libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_DEBUG); + libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); + libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); /* Now create a reference to the default context */ r = libusb_init(NULL); -- 2.7.4