diff --git a/c/BUILD b/c/BUILD index 26ef9f1..c5c5821 100644 --- a/c/BUILD +++ b/c/BUILD @@ -2,6 +2,23 @@ package(default_visibility = ["//visibility:public"]) load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") +# Option to disable _all_ print messages: +# --//:polaris_enable_print [enabled; default] +# --//:polaris_enable_print=True [enabled; default] +# --//:polaris_enable_print=False [disabled] +# --no//:polaris_enable_print [disabled] +bool_flag( + name = "polaris_enable_print", + build_setting_default = True, +) + +config_setting( + name = "print_enabled", + flag_values = { + ":polaris_enable_print": "True", + }, +) + # Option to enable/disable TLS support (enabled by default): # --//:polaris_enable_tls [enabled; default] # --//:polaris_enable_tls=True [enabled; default] @@ -38,7 +55,11 @@ cc_library( name = "polaris_client_tls", srcs = glob(["src/**/*.c"]), hdrs = glob(["src/**/*.h"]), - copts = ["-DPOLARIS_USE_TLS=1"], + copts = ["-DPOLARIS_USE_TLS=1"] + + select({ + ":print_enabled": [], + "//conditions:default": ["-DPOLARIS_NO_PRINT"], + }), includes = ["src"], deps = ["@boringssl//:ssl"], ) @@ -49,5 +70,9 @@ cc_library( name = "polaris_client_no_tls", srcs = glob(["src/**/*.c"]), hdrs = glob(["src/**/*.h"]), + copts = select({ + ":print_enabled": [], + "//conditions:default": ["-DPOLARIS_NO_PRINT"], + }), includes = ["src"], ) diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index 6009efa..cd40483 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -9,9 +9,8 @@ option(BUILD_SHARED_LIBS "Build shared libraries instead of static libraries." option(BUILD_EXAMPLES "Build example applications." ON) -set(POLARIS_DEBUG "OFF" CACHE STRING - "Enable Polaris debug/trace print messages.") -set_property(CACHE POLARIS_DEBUG PROPERTY STRINGS OFF ON DEBUG TRACE) +option(POLARIS_ENABLE_PRINT + "Enable Polaris debug/trace print messages." ON) option(POLARIS_ENABLE_TLS "Enable TLS support when connecting to Polaris." ON) @@ -22,10 +21,8 @@ else() add_compile_options(-Wall -Werror) endif() -if(POLARIS_DEBUG STREQUAL "TRACE") - add_compile_definitions(POLARIS_TRACE) -elseif(POLARIS_DEBUG) - add_compile_definitions(POLARIS_DEBUG) +if(NOT POLARIS_ENABLE_PRINT) + add_compile_definitions(POLARIS_NO_PRINT) endif() ################################################################################ diff --git a/c/examples/connection_retry.c b/c/examples/connection_retry.c index c826113..5465453 100644 --- a/c/examples/connection_retry.c +++ b/c/examples/connection_retry.c @@ -5,6 +5,7 @@ ******************************************************************************/ #include +#include // For atoi() #include "point_one/polaris/polaris.h" #include "point_one/polaris/portability.h" @@ -26,13 +27,16 @@ void HandleSignal(int sig) { int main(int argc, const char* argv[]) { if (argc < 2 || argc > 3) { - P1_fprintf(stderr, "Usage: %s API_KEY [UNIQUE_ID]\n", argv[0]); + P1_fprintf(stderr, "Usage: %s API_KEY [UNIQUE_ID] [LOG_LEVEL]\n", argv[0]); return 1; } const char* api_key = argv[1]; const char* unique_id = argc > 2 ? argv[2] : "device12345"; + int log_level = argc > 3 ? atoi(argv[3]) : POLARIS_LOG_LEVEL_INFO; + Polaris_SetLogLevel(log_level); + const int MAX_RECONNECTS = 2; int auth_valid = 0; int reconnect_count = 0; diff --git a/c/examples/simple_polaris_client.c b/c/examples/simple_polaris_client.c index 6505880..22d9ebd 100644 --- a/c/examples/simple_polaris_client.c +++ b/c/examples/simple_polaris_client.c @@ -5,6 +5,7 @@ ******************************************************************************/ #include +#include // For atoi() #include "point_one/polaris/polaris.h" #include "point_one/polaris/portability.h" @@ -26,13 +27,16 @@ void HandleSignal(int sig) { int main(int argc, const char* argv[]) { if (argc < 2 || argc > 3) { - P1_fprintf(stderr, "Usage: %s API_KEY [UNIQUE_ID]\n", argv[0]); + P1_fprintf(stderr, "Usage: %s API_KEY [UNIQUE_ID] [LOG_LEVEL]\n", argv[0]); return 1; } const char* api_key = argv[1]; const char* unique_id = argc > 2 ? argv[2] : "device12345"; + int log_level = argc > 3 ? atoi(argv[3]) : POLARIS_LOG_LEVEL_INFO; + Polaris_SetLogLevel(log_level); + // Retrieve an access token using the specified API key. if (Polaris_Init(&context) != POLARIS_SUCCESS) { return 2; diff --git a/c/src/point_one/polaris/polaris.c b/c/src/point_one/polaris/polaris.c index 093bc21..7b8902a 100644 --- a/c/src/point_one/polaris/polaris.c +++ b/c/src/point_one/polaris/polaris.c @@ -22,12 +22,39 @@ #define MAKE_STR(x) #x #define STR(x) MAKE_STR(x) -#define P1_Print(x, ...) \ +#if defined(P1_NO_PRINT) +# define P1_Print(x, ...) do {} while(0) +# define P1_PrintError(x, ...) do {} while(0) +# define P1_DebugPrint(x, ...) do {} while(0) +# define PrintData(buffer, length) do {} while(0) +# if defined(POLARIS_USE_TLS) +# define ShowCerts(ssl) do {} while(0) +# endif +#else +static int __log_level = POLARIS_LOG_LEVEL_INFO; + +# define P1_Print(x, ...) \ P1_fprintf(stderr, "polaris.c:" STR(__LINE__) "] " x, ##__VA_ARGS__) -#define P1_PrintError(x, ...) \ +# define P1_PrintError(x, ...) \ P1_perror("polaris.c:" STR(__LINE__) "] " x, ##__VA_ARGS__) +# define P1_DebugPrint(x, ...) \ + if (__log_level >= POLARIS_LOG_LEVEL_DEBUG) { \ + P1_Print(x, ##__VA_ARGS__); \ + } +# define P1_TracePrint(x, ...) \ + if (__log_level >= POLARIS_LOG_LEVEL_TRACE) { \ + P1_Print(x, ##__VA_ARGS__); \ + } + +static void P1_PrintData(const uint8_t* buffer, size_t length); +# if defined(POLARIS_USE_TLS) +static void ShowCerts(SSL* ssl); +# endif +#endif -#if defined(POLARIS_USE_TLS) +#if defined(POLARIS_NO_PRINT) +# define P1_PrintWriteError(context, x, ret) do {} while(0) +#elif defined(POLARIS_USE_TLS) static void __P1_PrintWriteError(int line, PolarisContext_t* context, const char* message, int ret) { SSL_load_error_strings(); @@ -80,40 +107,10 @@ static void __P1_PrintWriteError(int line, PolarisContext_t* context, } } -#define P1_PrintWriteError(context, x, ret) \ +# define P1_PrintWriteError(context, x, ret) \ __P1_PrintWriteError(__LINE__, context, x, ret) #else -#define P1_PrintWriteError(context, x, ret) P1_PrintError(x, ret) -#endif - - -#if defined(POLARIS_TRACE) && !defined(POLARIS_DEBUG) -# define POLARIS_DEBUG 1 -#endif - -#if defined(POLARIS_DEBUG) || defined(POLARIS_TRACE) -# define P1_DebugPrint(x, ...) P1_Print(x, ##__VA_ARGS__) -#else -# define P1_DebugPrint(x, ...) do {} while(0) -#endif - -#if defined(POLARIS_TRACE) -void PrintData(const uint8_t* buffer, size_t length) { - for (size_t i = 0; i < length; ++i) { - if (i % 16 != 0) { - P1_fprintf(stderr, " "); - } - - P1_fprintf(stderr, "%02x", buffer[i]); - - if (i % 16 == 15) { - P1_fprintf(stderr, "\n"); - } - } - P1_fprintf(stderr, "\n"); -} -#else -# define PrintData(buffer, length) do {} while(0) +# define P1_PrintWriteError(context, x, ret) P1_PrintError(x, ret) #endif static int OpenSocket(PolarisContext_t* context, const char* endpoint_url, @@ -127,10 +124,6 @@ static int GetHTTPResponse(PolarisContext_t* context); static void CloseSocket(PolarisContext_t* context, int destroy_context); -#ifdef POLARIS_USE_TLS -static void ShowCerts(SSL* ssl); -#endif - /******************************************************************************/ int Polaris_Init(PolarisContext_t* context) { if (POLARIS_RECV_BUFFER_SIZE < POLARIS_MAX_HTTP_MESSAGE_SIZE) { @@ -167,6 +160,13 @@ void Polaris_Free(PolarisContext_t* context) { CloseSocket(context, 1); } +/******************************************************************************/ +void Polaris_SetLogLevel(int log_level) { +#if !defined(POLARIS_NO_PRINT) + __log_level = log_level; +#endif +} + /******************************************************************************/ int Polaris_Authenticate(PolarisContext_t* context, const char* api_key, const char* unique_id) { @@ -380,7 +380,7 @@ int Polaris_SendECEFPosition(PolarisContext_t* context, double x_m, double y_m, "Sending ECEF position. [size=%u B, position=[%.2f, %.2f, %.2f]]\n", (unsigned)message_size, x_m, y_m, z_m); #endif - PrintData(context->send_buffer, message_size); + P1_PrintData(context->send_buffer, message_size); #ifdef POLARIS_USE_TLS int ret = SSL_write(context->ssl, context->send_buffer, message_size); @@ -423,7 +423,7 @@ int Polaris_SendLLAPosition(PolarisContext_t* context, double latitude_deg, "Sending LLA position. [size=%u B, position=[%.6f, %.6f, %.2f]]\n", (unsigned)message_size, latitude_deg, longitude_deg, altitude_m); #endif - PrintData(context->send_buffer, message_size); + P1_PrintData(context->send_buffer, message_size); #ifdef POLARIS_USE_TLS int ret = SSL_write(context->ssl, context->send_buffer, message_size); @@ -454,7 +454,7 @@ int Polaris_RequestBeacon(PolarisContext_t* context, const char* beacon_id) { P1_DebugPrint("Sending beacon request. [size=%u B, beacon='%s']\n", (unsigned)message_size, beacon_id); - PrintData(context->send_buffer, message_size); + P1_PrintData(context->send_buffer, message_size); #ifdef POLARIS_USE_TLS int ret = SSL_write(context->ssl, context->send_buffer, message_size); @@ -860,9 +860,34 @@ static int GetHTTPResponse(PolarisContext_t* context) { } /******************************************************************************/ -#ifdef POLARIS_USE_TLS +#if !defined(P1_NO_PRINT) +void P1_PrintData(const uint8_t* buffer, size_t length) { + if (__log_level < POLARIS_LOG_LEVEL_TRACE) { + return; + } + + for (size_t i = 0; i < length; ++i) { + if (i % 16 != 0) { + P1_fprintf(stderr, " "); + } + + P1_fprintf(stderr, "%02x", buffer[i]); + + if (i % 16 == 15) { + P1_fprintf(stderr, "\n"); + } + } + P1_fprintf(stderr, "\n"); +} +#endif + +/******************************************************************************/ +#if !defined(P1_NO_PRINT) && defined(POLARIS_USE_TLS) void ShowCerts(SSL* ssl) { - #if defined(POLARIS_DEBUG) || defined(POLARIS_TRACE) + if (__log_level >= POLARIS_LOG_LEVEL_DEBUG) { + return; + } + X509* cert = SSL_get_peer_certificate(ssl); if (cert != NULL) { char* line; @@ -874,6 +899,5 @@ void ShowCerts(SSL* ssl) { } else { P1_DebugPrint("No client certificates configured.\n"); } - #endif } #endif diff --git a/c/src/point_one/polaris/polaris.h b/c/src/point_one/polaris/polaris.h index 9555a19..3ccf3e8 100644 --- a/c/src/point_one/polaris/polaris.h +++ b/c/src/point_one/polaris/polaris.h @@ -69,6 +69,10 @@ # define POLARIS_SEND_TIMEOUT_MS 1000 #endif +/** + * @name Polaris Return Codes + * @{ + */ #define POLARIS_SUCCESS 0 #define POLARIS_ERROR -1 #define POLARIS_NOT_ENOUGH_SPACE -2 @@ -78,6 +82,16 @@ #define POLARIS_FORBIDDEN -6 #define POLARIS_CONNECTION_CLOSED -7 #define POLARIS_TIMED_OUT -8 +/** @} */ + +/** + * @name Polaris Logging Verbosity Levels + * @{ + */ +#define POLARIS_LOG_LEVEL_INFO 0 +#define POLARIS_LOG_LEVEL_DEBUG 1 +#define POLARIS_LOG_LEVEL_TRACE 2 +/** @} */ struct PolarisContext_s; typedef struct PolarisContext_s PolarisContext_t; @@ -131,6 +145,13 @@ int Polaris_Init(PolarisContext_t* context); */ void Polaris_Free(PolarisContext_t* context); +/** + * @brief Set the Polaris library print verbosity level. + * + * @param log_level The desired verbosity level. + */ +void Polaris_SetLogLevel(int log_level); + /** * @brief Authenticate with Polaris. * diff --git a/src/point_one/polaris/polaris_client.cc b/src/point_one/polaris/polaris_client.cc index b406ace..e80f537 100644 --- a/src/point_one/polaris/polaris_client.cc +++ b/src/point_one/polaris/polaris_client.cc @@ -60,6 +60,14 @@ PolarisClient::PolarisClient(const std::string& api_key, : max_reconnect_attempts_(max_reconnect_attempts), api_key_(api_key), unique_id_(unique_id) { + // Note that the C library print level will not change if the VLOG level is + // changed dynamically via SetVLOGLevel() at runtime. + if (VLOG_IS_ON(1)) { + Polaris_SetLogLevel(POLARIS_LOG_LEVEL_DEBUG); + } else if (VLOG_IS_ON(2)) { + Polaris_SetLogLevel(POLARIS_LOG_LEVEL_TRACE); + } + SetPolarisEndpoint(); polaris_.SetRTCMCallback([&](const uint8_t* buffer, size_t size_bytes) {