core: Introduce libusb_set_option() API function
authorChris Dickens <christopher.a.dickens@gmail.com>
Tue, 11 Jul 2017 05:37:13 +0000 (22:37 -0700)
committerChris Dickens <christopher.a.dickens@gmail.com>
Sun, 16 Jul 2017 21:02:05 +0000 (14:02 -0700)
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>
examples/fxload.c
examples/xusb.c
libusb/core.c
libusb/libusb-1.0.def
libusb/libusb.h
libusb/version_nano.h
tests/stress.c

index 5aa5226..1cea9c3 100644 (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)) {
index 352a5d7..b2e2424 100644 (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)
index 5b47194..f21a74f 100644 (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.
- *
- * 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.
index 2443d9b..92c26d4 100644 (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
index 70ee2ca..480a5ad 100644 (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
index f8a1bfb..2971829 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11210
+#define LIBUSB_NANO 11211
index 0f50003..0e2dbe5 100644 (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);