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 <christopher.a.dickens@gmail.com>
This commit is contained in:
Chris Dickens 2017-07-10 22:37:13 -07:00
parent 34987d005e
commit 539f22e2fd
7 changed files with 118 additions and 54 deletions

View File

@ -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)) {

View File

@ -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)

View File

@ -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.
* 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_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.
* 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.

View File

@ -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

View File

@ -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

View File

@ -1 +1 @@
#define LIBUSB_NANO 11210
#define LIBUSB_NANO 11211

View File

@ -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);