Index: asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/logging.c
===================================================================
--- asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/logging.c	(revision 337)
+++ asp3_tinet_ecnl_rx/trunk/wolfssl-3.12.2/wolfcrypt/src/logging.c	(revision 372)
@@ -31,13 +31,7 @@
 #include <wolfssl/wolfcrypt/logging.h>
 #include <wolfssl/wolfcrypt/error-crypt.h>
-
-
-#ifdef __cplusplus
-    extern "C" {
-#endif
-    WOLFSSL_API int  wolfSSL_Debugging_ON(void);
-    WOLFSSL_API void wolfSSL_Debugging_OFF(void);
-#ifdef __cplusplus
-    }
+#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+/* avoid adding WANT_READ and WANT_WRITE to error queue */
+#include <wolfssl/error-ssl.h>
 #endif
 
@@ -58,11 +52,67 @@
 };
 volatile struct wc_error_queue* wc_errors;
+static struct wc_error_queue* wc_current_node;
 static struct wc_error_queue* wc_last_node;
 /* pointer to last node in queue to make insertion O(1) */
 #endif
 
-
-
-#if defined(DEBUG_WOLFSSL)
+#ifdef WOLFSSL_FUNC_TIME
+/* WARNING: This code is only to be used for debugging performance.
+ *          The code is not thread-safe.
+ *          Do not use WOLFSSL_FUNC_TIME in production code.
+ */
+static double wc_func_start[WC_FUNC_COUNT];
+static double wc_func_time[WC_FUNC_COUNT] = { 0, };
+static const char* wc_func_name[WC_FUNC_COUNT] = {
+    "SendHelloRequest",
+    "DoHelloRequest",
+    "SendClientHello",
+    "DoClientHello",
+    "SendServerHello",
+    "DoServerHello",
+    "SendEncryptedExtensions",
+    "DoEncryptedExtensions",
+    "SendCertificateRequest",
+    "DoCertificateRequest",
+    "SendCertificate",
+    "DoCertificate",
+    "SendCertificateVerify",
+    "DoCertificateVerify",
+    "SendFinished",
+    "DoFinished",
+    "SendKeyUpdate",
+    "DoKeyUpdate",
+    "SendEarlyData",
+    "DoEarlyData",
+    "SendNewSessionTicket",
+    "DoNewSessionTicket",
+    "SendServerHelloDone",
+    "DoServerHelloDone",
+    "SendTicket",
+    "DoTicket",
+    "SendClientKeyExchange",
+    "DoClientKeyExchange",
+    "SendCertificateStatus",
+    "DoCertificateStatus",
+    "SendServerKeyExchange",
+    "DoServerKeyExchange",
+    "SendEarlyData",
+    "DoEarlyData",
+};
+
+#include <sys/time.h>
+
+/* WARNING: This function is not portable. */
+static WC_INLINE double current_time(int reset)
+{
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    (void)reset;
+
+    return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
+}
+#endif /* WOLFSSL_FUNC_TIME */
+
+#ifdef DEBUG_WOLFSSL
 
 /* Set these to default values initially. */
@@ -70,18 +120,18 @@
 static int loggingEnabled = 0;
 
+#if defined(WOLFSSL_APACHE_MYNEWT)
+#include "log/log.h"
+static struct log mynewt_log;
+#endif /* WOLFSSL_APACHE_MYNEWT */
+
 #endif /* DEBUG_WOLFSSL */
 
 
+/* allow this to be set to NULL, so logs can be redirected to default output */
 int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
 {
 #ifdef DEBUG_WOLFSSL
-    int res = 0;
-
-    if (f)
         log_function = f;
-    else
-        res = BAD_FUNC_ARG;
-
-    return res;
+    return 0;
 #else
     (void)f;
@@ -95,4 +145,7 @@
 #ifdef DEBUG_WOLFSSL
     loggingEnabled = 1;
+#if defined(WOLFSSL_APACHE_MYNEWT)
+    log_register("wolfcrypt", &mynewt_log, &log_console_handler, NULL, LOG_SYSLEVEL);
+#endif /* WOLFSSL_APACHE_MYNEWT */
     return 0;
 #else
@@ -109,4 +162,42 @@
 }
 
+#ifdef WOLFSSL_FUNC_TIME
+/* WARNING: This code is only to be used for debugging performance.
+ *          The code is not thread-safe.
+ *          Do not use WOLFSSL_FUNC_TIME in production code.
+ */
+void WOLFSSL_START(int funcNum)
+{
+    double now = current_time(0) * 1000.0;
+#ifdef WOLFSSL_FUNC_TIME_LOG
+    fprintf(stderr, "%17.3f: START - %s\n", now, wc_func_name[funcNum]);
+#endif
+    wc_func_start[funcNum] = now;
+}
+
+void WOLFSSL_END(int funcNum)
+{
+    double now = current_time(0) * 1000.0;
+    wc_func_time[funcNum] += now - wc_func_start[funcNum];
+#ifdef WOLFSSL_FUNC_TIME_LOG
+    fprintf(stderr, "%17.3f: END   - %s\n", now, wc_func_name[funcNum]);
+#endif
+}
+
+void WOLFSSL_TIME(int count)
+{
+    int i;
+    double avg, total = 0;
+
+    for (i = 0; i < WC_FUNC_COUNT; i++) {
+        if (wc_func_time[i] > 0) {
+            avg = wc_func_time[i] / count;
+            fprintf(stderr, "%8.3f ms: %s\n", avg, wc_func_name[i]);
+            total += avg;
+        }
+    }
+    fprintf(stderr, "%8.3f ms\n", total);
+}
+#endif
 
 #ifdef DEBUG_WOLFSSL
@@ -122,5 +213,12 @@
     int sprintf(char* buf, const char *fmt, ...);
 #elif defined(MICRIUM)
+    #if (BSP_SER_COMM_EN  == DEF_ENABLED)
     #include <bsp_ser.h>
+    #endif
+#elif defined(WOLFSSL_USER_LOG)
+    /* user includes their own headers */
+#elif defined(WOLFSSL_ESPIDF)
+    #include "esp_types.h"
+    #include "esp_log.h"
 #else
     #include <stdio.h>   /* for default printf stuff */
@@ -136,6 +234,10 @@
         log_function(logLevel, logMessage);
     else {
-        if (loggingEnabled) {
-#if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
+#if defined(WOLFSSL_USER_LOG)
+        WOLFSSL_USER_LOG(logMessage);
+#elif defined(WOLFSSL_LOG_PRINTF)
+        printf("%s\n", logMessage);
+
+#elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
             dc_log_printf("%s\n", logMessage);
 #elif defined(MICRIUM)
@@ -145,6 +247,4 @@
             printf("%s\n", logMessage);
             fflush(stdout) ;
-#elif defined(WOLFSSL_LOG_PRINTF)
-            printf("%s\n", logMessage);
 #elif defined(WOLFSSL_UTASKER)
             fnDebugMsg((char*)logMessage);
@@ -152,4 +252,10 @@
 #elif defined(MQX_USE_IO_OLD)
             fprintf(_mqxio_stderr, "%s\n", logMessage);
+
+#elif defined(WOLFSSL_APACHE_MYNEWT)
+        LOG_DEBUG(&mynewt_log, LOG_MODULE_DEFAULT, "%s\n", logMessage);
+#elif defined(WOLFSSL_ESPIDF)
+        extern char* TAG;
+        ESP_LOGI(TAG, "%s", logMessage);
 #else
             fprintf(stderr, "%s\n", logMessage);
@@ -157,7 +263,6 @@
         }
     }
-}
-
-
+
+#ifndef WOLFSSL_DEBUG_ERRORS_ONLY
 void WOLFSSL_MSG(const char* msg)
 {
@@ -208,6 +313,6 @@
 {
     if (loggingEnabled) {
-        char buffer[80];
-        sprintf(buffer, "wolfSSL Entering %s", msg);
+        char buffer[WOLFSSL_MAX_ERROR_SZ];
+        XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Entering %s", msg);
         wolfssl_log(ENTER_LOG , buffer);
     }
@@ -218,9 +323,11 @@
 {
     if (loggingEnabled) {
-        char buffer[80];
-        sprintf(buffer, "wolfSSL Leaving %s, return %d", msg, ret);
+        char buffer[WOLFSSL_MAX_ERROR_SZ];
+        XSNPRINTF(buffer, sizeof(buffer), "wolfSSL Leaving %s, return %d",
+                msg, ret);
         wolfssl_log(LEAVE_LOG , buffer);
     }
 }
+#endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */
 #endif  /* DEBUG_WOLFSSL */
 
@@ -230,6 +337,8 @@
  * name where WOLFSSL_ERROR is called at.
  */
-#if (defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX)) || defined(WOLFSSL_HAPROXY)
-    #if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
+#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || \
+    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
+
+#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
 void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,
             const char* file, void* usrCtx)
@@ -238,9 +347,10 @@
     #endif
 {
-    #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_NGINX)
-    if (loggingEnabled && error != WC_PENDING_E)
+#ifdef WOLFSSL_ASYNC_CRYPT
+    if (error != WC_PENDING_E)
     #endif
     {
-        char buffer[80];
+        char buffer[WOLFSSL_MAX_ERROR_SZ];
+
         #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
             (void)usrCtx; /* a user ctx for future flexibility */
@@ -249,9 +359,17 @@
             if (wc_LockMutex(&debug_mutex) != 0) {
                 WOLFSSL_MSG("Lock debug mutex failed");
-                sprintf(buffer, "wolfSSL error occurred, error = %d", error);
+            XSNPRINTF(buffer, sizeof(buffer),
+                    "wolfSSL error occurred, error = %d", error);
             }
             else {
-                if (error < 0) error = error - (2*error); /*get absolute value*/
-                sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s",
+            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+            /* If running in compatibility mode do not add want read and
+               want right to error queue */
+            if (error != WANT_READ && error != WANT_WRITE) {
+            #endif
+            if (error < 0)
+                error = error - (2 * error); /* get absolute value */
+            XSNPRINTF(buffer, sizeof(buffer),
+                    "wolfSSL error occurred, error = %d line:%d file:%s",
                     error, line, file);
                 if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) {
@@ -260,14 +378,35 @@
                      * to unlock mutex and log what buffer was created. */
                 }
+            #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
+            }
+            else {
+                XSNPRINTF(buffer, sizeof(buffer),
+                    "wolfSSL error occurred, error = %d", error);
+
+            }
+            #endif
 
                 wc_UnLockMutex(&debug_mutex);
             }
         #else
-            sprintf(buffer, "wolfSSL error occurred, error = %d", error);
+        XSNPRINTF(buffer, sizeof(buffer),
+                "wolfSSL error occurred, error = %d", error);
         #endif
+
         #ifdef DEBUG_WOLFSSL
+        if (loggingEnabled)
         wolfssl_log(ERROR_LOG , buffer);
         #endif
     }
+}
+
+void WOLFSSL_ERROR_MSG(const char* msg)
+{
+#ifdef DEBUG_WOLFSSL
+    if (loggingEnabled)
+        wolfssl_log(ERROR_LOG , msg);
+#else
+    (void)msg;
+#endif
 }
 
@@ -283,4 +422,5 @@
     }
     wc_errors          = NULL;
+    wc_current_node    = NULL;
     wc_last_node       = NULL;
 
@@ -304,6 +444,4 @@
 
 
-#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
-    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE)
 /* peek at an error node
  *
@@ -367,4 +505,51 @@
 
 
+/* Pulls the current node from error queue and increments current state.
+ * Note: this does not delete nodes because input arguments are pointing to
+ *       node buffers.
+ *
+ * file   pointer to file that error was in. Can be NULL to return no file.
+ * reason error string giving reason for error. Can be NULL to return no reason.
+ * line   return line number of where error happened.
+ *
+ * returns the error value on success and BAD_MUTEX_E or BAD_STATE_E on failure
+ */
+int wc_PullErrorNode(const char **file, const char **reason, int *line)
+{
+    struct wc_error_queue* err;
+    int value;
+
+    if (wc_LockMutex(&debug_mutex) != 0) {
+        WOLFSSL_MSG("Lock debug mutex failed");
+        return BAD_MUTEX_E;
+    }
+
+    err = wc_current_node;
+    if (err == NULL) {
+        WOLFSSL_MSG("No Errors in queue");
+        wc_UnLockMutex(&debug_mutex);
+        return BAD_STATE_E;
+    }
+
+    if (file != NULL) {
+        *file = err->file;
+    }
+
+    if (reason != NULL) {
+        *reason = err->error;
+    }
+
+    if (line != NULL) {
+        *line = err->line;
+    }
+
+    value = err->value;
+    wc_current_node = err->next;
+    wc_UnLockMutex(&debug_mutex);
+
+    return value;
+}
+
+
 /* create new error node and add it to the queue
  * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal
@@ -416,8 +601,14 @@
                 /* check for unexpected case before over writing wc_errors */
                 WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n");
+                /* In the event both wc_last_node and wc_errors are NULL, err
+                 * goes unassigned to external wc_errors, wc_last_node. Free
+                 * err in this instance since wc_ClearErrorNodes will not
+                 */
+                XFREE(err, wc_error_heap, DYNAMIC_TYPE_LOG);
             }
             else {
                 wc_errors    = err;
                 wc_last_node = err;
+                wc_current_node = err;
             }
         }
@@ -426,4 +617,10 @@
             err->prev = wc_last_node;
             wc_last_node = err;
+
+            /* check the case where have read to the end of the queue and the
+             * current node to read needs updated */
+            if (wc_current_node == NULL) {
+                wc_current_node = err;
+            }
         }
     }
@@ -465,5 +662,4 @@
 }
 
-#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
 
 /* Clears out the list of error nodes.
@@ -471,4 +667,7 @@
 void wc_ClearErrorNodes(void)
 {
+#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
+    defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
+
     if (wc_LockMutex(&debug_mutex) != 0) {
         WOLFSSL_MSG("Lock debug mutex failed");
@@ -491,5 +690,7 @@
     wc_errors    = NULL;
     wc_last_node = NULL;
+    wc_current_node = NULL;
     wc_UnLockMutex(&debug_mutex);
+#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
 }
 
@@ -505,14 +706,48 @@
 }
 
+
+/* frees all nodes in the queue
+ *
+ * id  this is the thread id
+ */
+int wc_ERR_remove_state(void)
+{
+    struct wc_error_queue* current;
+    struct wc_error_queue* next;
+
+    if (wc_LockMutex(&debug_mutex) != 0) {
+        WOLFSSL_MSG("Lock debug mutex failed");
+        return BAD_MUTEX_E;
+    }
+
+    /* free all nodes from error queue */
+    current = (struct wc_error_queue*)wc_errors;
+    while (current != NULL) {
+        next = current->next;
+        XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
+        current = next;
+    }
+
+    wc_errors          = NULL;
+    wc_last_node       = NULL;
+
+    wc_UnLockMutex(&debug_mutex);
+
+    return 0;
+}
+
+
 #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
 /* empties out the error queue into the file */
-void wc_ERR_print_errors_fp(FILE* fp)
+void wc_ERR_print_errors_fp(XFILE fp)
 {
     WOLFSSL_ENTER("wc_ERR_print_errors_fp");
 
-    if (wc_LockMutex(&debug_mutex) != 0) {
+        if (wc_LockMutex(&debug_mutex) != 0)
+        {
         WOLFSSL_MSG("Lock debug mutex failed");
     }
-    else {
+        else
+        {
         /* free all nodes from error queue and print them to file */
         {
@@ -521,5 +756,6 @@
 
             current = (struct wc_error_queue*)wc_errors;
-            while (current != NULL) {
+                while (current != NULL)
+                {
                 next = current->next;
                 fprintf(fp, "%s\n", current->error);
