Bug 84 - Adding utf8 support to dlt-daemon, dlt-viewer. Modified patch, originally...
[profile/ivi/dlt-daemon.git] / src / lib / dlt_user.c
old mode 100755 (executable)
new mode 100644 (file)
index c1bcba4..1f43801
@@ -1,39 +1,24 @@
-/*
-* Dlt- Diagnostic Log and Trace user library
-* @licence app begin@
+/**
+ * @licence app begin@
+ * Copyright (C) 2012  BMW AG
+ *
+ * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
- * 
- * This program is free software; you can redistribute it and/or modify it under the terms of the 
- * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 
- * Public License, version 2.1, for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public License, version 2.1, along 
- * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
- * 
- * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may 
- * also be applicable to programs even in cases in which the program is not a library in the technical sense.
- * 
- * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may 
- * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to 
- * license your linked modules under the GNU Lesser General Public License, version 2.1, you 
- * may use the program under the following exception.
- * 
- * As a special exception, the copyright holders of DLT give you permission to combine DLT 
- * with software programs or libraries that are released under any license unless such a combination is not
- * permitted by the license of such a software program or library. You may copy and distribute such a 
- * system following the terms of the GNU Lesser General Public License, version 2.1, including this
- * special exception, for DLT and the licenses of the other code concerned.
- * 
- * Note that people who make modified versions of DLT are not obligated to grant this special exception 
- * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, 
- * version 2.1, gives permission to release a modified version without this exception; this exception 
- * also makes it possible to release a modified version which carries forward this exception.
  *
+ * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
+ *
+ * \file dlt_user.c
+ * For further information see http://www.genivi.org/.
  * @licence end@
-*/
+ */
 
 
 /*******************************************************************************
@@ -78,7 +63,6 @@
  Initials    Date         Comment
  aw          13.01.2010   initial
  */
-
 #include <stdlib.h> /* for getenv(), free(), atexit() */
 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
 #include <pthread.h>    /* POSIX Threads */
 #endif
 
+#include <sys/time.h>
+#include <math.h>
+
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
 
 #include <sys/uio.h> /* writev() */
 
+#include <limits.h>
+
 #include "dlt_user.h"
 #include "dlt_user_shared.h"
 #include "dlt_user_shared_cfg.h"
@@ -104,26 +93,67 @@ static DltUser dlt_user;
 static int dlt_user_initialised = 0;
 
 static char str[DLT_USER_BUFFER_LENGTH];
-static char text[DLT_USER_TEXT_LENGTH];
 
 static sem_t dlt_mutex;
 static pthread_t dlt_receiverthread_handle;
 static pthread_attr_t dlt_receiverthread_attr;
 
+/* Segmented Network Trace */
+#define DLT_MAX_TRACE_SEGMENT_SIZE 1024
+#define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue"
+#define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF
+
+/* Mutex to wait on while message queue is not initialized */
+pthread_mutex_t mq_mutex;
+pthread_cond_t  mq_init_condition;
+
+/* Structure to pass data to segmented thread */
+typedef struct {
+       DltContext                      *handle;
+       uint16_t                        id;
+       DltNetworkTraceType     nw_trace_type;
+       uint16_t                        header_len;
+       void                            *header;
+       uint16_t                        payload_len;
+       void                            *payload;
+} s_segmented_data;
+
 /* Function prototypes for internally used functions */
 static void dlt_user_receiverthread_function(void *ptr);
 static void dlt_user_atexit_handler(void);
 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
-static int dlt_user_log_send_log(DltContextData *log, int mtype);
+static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
 static int dlt_user_log_send_register_application(void);
 static int dlt_user_log_send_unregister_application(void);
 static int dlt_user_log_send_register_context(DltContextData *log);
 static int dlt_user_log_send_unregister_context(DltContextData *log);
 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
+static int dlt_user_log_send_log_mode(DltUserLogMode mode);
 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
 static int dlt_user_log_check_user_message(void);
 static void dlt_user_log_reattach_to_daemon(void);
 static int dlt_user_log_send_overflow(void);
+static void dlt_user_trace_network_segmented_thread(void *unused);
+static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data);
+static int dlt_user_queue_resend(void);
+
+int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
+
+       char str[200];
+       char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
+       char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
+
+       dlt_get_major_version( lib_major_version);
+       dlt_get_minor_version( lib_minor_version);
+
+       if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
+       {
+               sprintf(str,"DLT Library version check failed! Installed DLT library version is %s.%s - Application using DLT library version %s.%s\n",lib_major_version,lib_minor_version,user_major_version,user_minor_version);
+               dlt_log(LOG_WARNING, str);
+               return -1;
+       }
+       return 0;
+}
 
 int dlt_init(void)
 {
@@ -141,10 +171,13 @@ int dlt_init(void)
 
     dlt_user.dlt_is_file = 0;
     dlt_user.overflow = 0;
+#ifdef DLT_SHM_ENABLE
+       memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
+#endif
 
     /* create and open DLT user FIFO */
     sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
-    
+     
     /* Try to delete existing pipe, ignore result of unlink */
     unlink(filename);
     
@@ -156,8 +189,8 @@ int dlt_init(void)
         /* return 0; */ /* removed to prevent error, when FIFO already exists */
     }
 
-    dlt_user.dlt_user_handle = open(filename, O_RDWR);
-    if (dlt_user.dlt_user_handle == -1)
+    dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
+    if (dlt_user.dlt_user_handle == DLT_FD_INIT)
     {
         sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
         dlt_log(LOG_WARNING, str);
@@ -166,13 +199,26 @@ int dlt_init(void)
     }
 
     /* open DLT output FIFO */
-    dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
+    dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
     if (dlt_user.dlt_log_handle==-1)
     {
         sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
         dlt_log(LOG_WARNING, str);
-        return 0;
+        //return 0;
     }
+       else
+       {
+#ifdef DLT_SHM_ENABLE
+               /* init shared memory */
+               if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
+               {
+                       sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
+                       dlt_log(LOG_WARNING, str);
+                       //return 0; 
+               }   
+#endif
+       }
+               
 
     if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
        {
@@ -180,22 +226,9 @@ int dlt_init(void)
         return -1;
     }
 
-    /* Set default thread stack size */
-    if (pthread_attr_init(&dlt_receiverthread_attr)<0)
-    {
-        dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n");
-    }
-    else
-    {
-        if (pthread_attr_setstacksize(&dlt_receiverthread_attr,DLT_USER_RECEIVERTHREAD_STACKSIZE)<0)
-        {
-            dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n");
-        }
-    }
-
     /* Start receiver thread */
     if (pthread_create(&(dlt_receiverthread_handle),
-                       &dlt_receiverthread_attr,
+                       0,
                        (void *) &dlt_user_receiverthread_function,
                        0)!=0)
        {
@@ -214,7 +247,23 @@ int dlt_init(void)
                dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
        }
 
-    return 0;
+    /* These will be lazy initialized only when needed */
+    dlt_user.dlt_segmented_queue_read_handle = -1;
+    dlt_user.dlt_segmented_queue_write_handle = -1;
+
+    /* Wait mutext for segmented thread */
+    pthread_mutex_init(&mq_mutex, NULL);
+    pthread_cond_init(&mq_init_condition, NULL);
+
+    /* Start the segmented thread */
+       if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
+          (void *)dlt_user_trace_network_segmented_thread, NULL))
+       {
+       dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
+       return -1;
+       }
+
+       return 0;
 }
 
 int dlt_init_file(const char *name)
@@ -242,6 +291,77 @@ int dlt_init_file(const char *name)
     return 0;
 }
 
+int dlt_init_message_queue(void)
+{
+       pthread_mutex_lock(&mq_mutex);
+       if(dlt_user.dlt_segmented_queue_read_handle >= 0 &&
+          dlt_user.dlt_segmented_queue_write_handle >= 0)
+       {
+               // Already intialized
+               pthread_mutex_unlock(&mq_mutex);
+               return 0;
+       }
+
+    /* Generate per process name for queue */
+    char queue_name[NAME_MAX];
+    sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
+
+    /* Maximum queue size is 10, limit to size of pointers */
+    struct mq_attr mqatr;
+    mqatr.mq_flags             = 0;
+    mqatr.mq_maxmsg            = 10;
+    mqatr.mq_msgsize   = sizeof(s_segmented_data *);
+    mqatr.mq_curmsgs   = 0;
+
+    /**
+     * Create the message queue. It must be newly created
+     * if old one was left by a crashing process.
+     * */
+    dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
+               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
+    if(dlt_user.dlt_segmented_queue_read_handle < 0)
+    {
+       if(errno == EEXIST)
+       {
+               dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
+               if(mq_unlink(queue_name) < 0)
+               {
+                char str[256];
+                snprintf(str,255,"Could not delete existing message queue!: %s \n",strerror(errno));
+                dlt_log(LOG_CRIT, str);
+               }
+               else // Retry
+               {
+                       dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
+                                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
+               }
+       }
+       if(dlt_user.dlt_segmented_queue_read_handle < 0)
+       {
+            char str[256];
+            snprintf(str,255,"Can't create message queue read handle!: %s \n",strerror(errno));
+            dlt_log(LOG_CRIT, str);
+               pthread_mutex_unlock(&mq_mutex);
+               return -1;
+       }
+    }
+
+    dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
+    if(dlt_user.dlt_segmented_queue_write_handle < 0)
+    {
+
+        char str[256];
+        snprintf(str,255,"Can't open message queue write handle!: %s \n",strerror(errno));
+        dlt_log(LOG_CRIT, str);
+       pthread_mutex_unlock(&mq_mutex);
+       return -1;
+    }
+
+    pthread_cond_signal(&mq_init_condition);
+    pthread_mutex_unlock(&mq_mutex);
+    return 0;
+}
+
 int dlt_init_common(void)
 {
     char *env_local_print;
@@ -253,8 +373,11 @@ int dlt_init_common(void)
         return -1;
     }
 
+       /* set to unknown state of connected client */
+       dlt_user.log_state = -1;
+
     dlt_user.dlt_log_handle=-1;
-    dlt_user.dlt_user_handle=-1;
+    dlt_user.dlt_user_handle=DLT_FD_INIT;
 
     dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
     dlt_set_id(dlt_user.appID,"");
@@ -287,25 +410,48 @@ int dlt_init_common(void)
     }
 
     /* Initialize LogLevel/TraceStatus field */
+    DLT_SEM_LOCK();
     dlt_user.dlt_ll_ts = 0;
     dlt_user.dlt_ll_ts_max_num_entries = 0;
     dlt_user.dlt_ll_ts_num_entries = 0;
 
-    if (dlt_ringbuffer_init(&(dlt_user.rbuf), DLT_USER_RINGBUFFER_SIZE)==-1)
+    if (dlt_buffer_init_dynamic(&(dlt_user.startup_buffer), DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)==-1)
     {
                dlt_user_initialised = 0;
+        DLT_SEM_FREE();
         return -1;
     }
+    DLT_SEM_FREE();
 
     signal(SIGPIPE,SIG_IGN);                  /* ignore pipe signals */
 
     atexit(dlt_user_atexit_handler);
 
+#ifdef DLT_TEST_ENABLE
+    dlt_user.corrupt_user_header = 0;
+    dlt_user.corrupt_message_size = 0;
+    dlt_user.corrupt_message_size_size = 0;
+#endif
+
     return 0;
 }
 
 void dlt_user_atexit_handler(void)
 {
+    if (dlt_user_initialised==0)
+    {
+        return;
+    }
+
+       /* Try to resend potential log messages in the user buffer */
+       int count = dlt_user_atexit_blow_out_user_buffer();
+
+       if(count != 0){
+               char tmp[256];
+               sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
+               dlt_log(LOG_ERR, tmp);
+       }
+
     /* Unregister app (this also unregisters all contexts in daemon) */
     /* Ignore return value */
     dlt_unregister_app();
@@ -315,9 +461,34 @@ void dlt_user_atexit_handler(void)
     dlt_free();
 }
 
+int dlt_user_atexit_blow_out_user_buffer(void){
+
+       int count,ret;
+
+       uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
+
+       while(dlt_uptime() < exitTime ){
+
+               ret = dlt_user_log_resend_buffer();
+
+               if(ret == 0)
+               {
+                               return 0;
+               }
+
+               usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
+       }
+
+       DLT_SEM_LOCK();
+       count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
+       DLT_SEM_FREE();
+
+       return count;
+}
+
 int dlt_free(void)
 {
-    int i;
+    uint32_t i;
        char filename[DLT_USER_MAX_FILENAME_LENGTH];
 
     if (dlt_user_initialised==0)
@@ -331,16 +502,21 @@ int dlt_free(void)
         pthread_cancel(dlt_receiverthread_handle);
     }
 
-    if (dlt_user.dlt_user_handle!=-1)
+    if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
     {
-        sprintf(filename,"/tmp/dlt%d",getpid());
+        sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
 
         close(dlt_user.dlt_user_handle);
-        dlt_user.dlt_user_handle=-1;
+        dlt_user.dlt_user_handle=DLT_FD_INIT;
 
         unlink(filename);
     }
 
+#ifdef DLT_SHM_ENABLE
+       /* free shared memory */
+       dlt_shm_free_client(&dlt_user.dlt_shm);
+#endif
+
     if (dlt_user.dlt_log_handle!=-1)
     {
         /* close log file/output fifo to daemon */
@@ -352,8 +528,9 @@ int dlt_free(void)
     dlt_receiver_free(&(dlt_user.receiver));
 
        /* Ignore return value */
-    dlt_ringbuffer_free(&(dlt_user.rbuf));
+    dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
 
+    DLT_SEM_LOCK();
     if (dlt_user.dlt_ll_ts)
     {
         for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
@@ -371,13 +548,33 @@ int dlt_free(void)
         dlt_user.dlt_ll_ts_max_num_entries = 0;
         dlt_user.dlt_ll_ts_num_entries = 0;
     }
+    DLT_SEM_FREE();
+
+    if (dlt_user.dlt_segmented_nwt_handle)
+    {
+       pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
+    }
+
+    char queue_name[NAME_MAX];
+    sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
+
+    /**
+     * Ignore errors from these, to not to spam user if dlt_free
+     * is accidentally called multiple times.
+     */
+    mq_close(dlt_user.dlt_segmented_queue_write_handle);
+    mq_close(dlt_user.dlt_segmented_queue_read_handle);
+    mq_unlink(queue_name);
 
     dlt_user_initialised = 0;
 
     return 0;
 }
 
-
+int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
+{
+       return dlt_user_check_library_version(user_major_version, user_minor_version);
+}
 
 int dlt_register_app(const char *appid, const char * description)
 {
@@ -396,6 +593,35 @@ int dlt_register_app(const char *appid, const char * description)
         return -1;
     }
 
+    /* check if application already registered */
+    /* if yes do not register again */
+    if(appid[1]==0)
+    {
+       if(appid[0]==dlt_user.appID[0])
+             return 0;
+    }
+    else if(appid[2]==0)
+    {
+       if(appid[0]==dlt_user.appID[0] &&
+          appid[1]==dlt_user.appID[1])
+             return 0;
+    }
+    else if(appid[3]==0)
+    {
+       if(appid[0]==dlt_user.appID[0] &&
+          appid[1]==dlt_user.appID[1] &&
+          appid[2]==dlt_user.appID[2])
+             return 0;
+    }
+    else
+    {
+       if(appid[0]==dlt_user.appID[0] &&
+          appid[1]==dlt_user.appID[1] &&
+          appid[2]==dlt_user.appID[2] &&
+          appid[3]==dlt_user.appID[3])
+             return 0;
+    }
+
     DLT_SEM_LOCK();
 
     /* Store locally application id and application description */
@@ -410,11 +636,19 @@ int dlt_register_app(const char *appid, const char * description)
 
     if (description!=0)
     {
-        dlt_user.application_description= malloc(strlen(description)+1);
-        strncpy(dlt_user.application_description, description, strlen(description));
+        size_t desc_len = strlen(description);
+        dlt_user.application_description= malloc(desc_len+1);
+        if (dlt_user.application_description){
+            strncpy(dlt_user.application_description, description, desc_len);
 
-        /* Terminate transmitted string with 0 */
-        dlt_user.application_description[strlen(description)]='\0';
+            /* Terminate transmitted string with 0 */
+            dlt_user.application_description[desc_len]='\0';
+        }
+        else
+        {
+               DLT_SEM_FREE();
+               return -1;
+        }
     }
 
     DLT_SEM_FREE();
@@ -457,7 +691,7 @@ int dlt_register_context(DltContext *handle, const char *contextid, const char *
 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
 {
     DltContextData log;
-    int i;
+    uint32_t i;
     int registered,ret;
     char ctid[DLT_ID_SIZE+1];
 
@@ -501,6 +735,9 @@ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const
        return -1;
     }
 
+    /* Reset message counter */
+    handle->mcnt = 0;
+
     /* Store context id in log level/trace status field */
 
     /* Check if already registered, else register context */
@@ -561,19 +798,25 @@ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const
             if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
             {
                 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
-                dlt_ll_ts_type *old;
-                old = dlt_user.dlt_ll_ts;
+                dlt_ll_ts_type *old_ll_ts;
+                uint32_t old_max_entries;
+
+                old_ll_ts = dlt_user.dlt_ll_ts;
+                old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
+
                 dlt_user.dlt_ll_ts_max_num_entries = ((dlt_user.dlt_ll_ts_num_entries/DLT_USER_CONTEXT_ALLOC_SIZE)+1)*DLT_USER_CONTEXT_ALLOC_SIZE;
                 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
                                      dlt_user.dlt_ll_ts_max_num_entries);
                 if (dlt_user.dlt_ll_ts==0)
                 {
+                       dlt_user.dlt_ll_ts = old_ll_ts;
+                       dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
                     DLT_SEM_FREE();
                     return -1;
                 }
 
-                memcpy(dlt_user.dlt_ll_ts,old,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
-                free(old);
+                memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
+                free(old_ll_ts);
 
                 /* Initialize new entries */
                 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
@@ -605,11 +848,18 @@ int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const
 
         if (description!=0)
         {
-            dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(strlen(description)+1);
-            strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, strlen(description));
+               size_t desc_len = strlen(description);
+            dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
+            if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
+            {
+               DLT_SEM_FREE();
+               return -1;
+            }
+
+            strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
 
             /* Terminate transmitted string with 0 */
-            dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[strlen(description)]='\0';
+            dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
         }
 
         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
@@ -743,7 +993,7 @@ int dlt_unregister_context(DltContext *handle)
 
 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
 {
-    int i;
+    uint32_t i;
     int ret;
 
     if (dlt_user_initialised==0)
@@ -790,6 +1040,24 @@ int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType
     return ret;
 }
 
+int dlt_get_log_state()
+{
+       return dlt_user.log_state;
+}
+
+int dlt_set_log_mode(DltUserLogMode mode)
+{
+    if (dlt_user_initialised==0)
+    {
+        if (dlt_init()<0)
+        {
+            return -1;
+        }
+    }
+
+       return dlt_user_log_send_log_mode(mode);
+}
+
 int dlt_forward_msg(void *msgdata,size_t size)
 {
     DltUserHeader userheader;
@@ -835,14 +1103,19 @@ int dlt_forward_msg(void *msgdata,size_t size)
         {
             DLT_SEM_LOCK();
 
-            if (dlt_ringbuffer_put3(&(dlt_user.rbuf),
-                                &(userheader), sizeof(DltUserHeader),
+            if (dlt_buffer_push3(&(dlt_user.startup_buffer),
+                                (unsigned char *)&(userheader), sizeof(DltUserHeader),
                                  msgdata, size, 0, 0)==-1)
                        {
                                dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
                        }
 
             DLT_SEM_FREE();
+
+            if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
+            {
+                dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n");
+            }
         }
 
         switch (ret)
@@ -883,48 +1156,30 @@ int dlt_forward_msg(void *msgdata,size_t size)
 
 /* ********************************************************************************************* */
 
-int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
+inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
 {
     return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
 }
 
 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
 {
-    uint32_t mid;
-
-    if (dlt_user_initialised==0)
-    {
-        if (dlt_init()<0)
-        {
-            return -1;
-        }
-    }
-
-    if (dlt_user_log_init(handle, log)==-1)
-    {
-               return -1;
-    }
-
+       if(dlt_user_initialised==0)
+       {
+               if (dlt_init()<0)
+               {
+                       return -1;
+               }
+       }
     if (log==0)
     {
         return -1;
     }
 
-    /* Removed because of DltLogLevelType
-
-    if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
+    if (dlt_user_log_init(handle, log)==-1)
     {
-        return -1;
+               return -1;
     }
 
-    */
-
-    mid = messageid;
-
-    log->args_num = 0;
-    log->log_level = loglevel;
-    log->size = 0;
-
     if (dlt_user.dlt_ll_ts==0)
     {
         return -1;
@@ -932,9 +1187,11 @@ int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLe
 
     DLT_SEM_LOCK();
 
-    if ((log->log_level<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (log->log_level!=0))
+    if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
     {
         DLT_SEM_FREE();
+               log->args_num = 0;
+       log->log_level = loglevel;
 
         /* In non-verbose mode, insert message id */
         if (dlt_user.verbose_mode==0)
@@ -944,12 +1201,13 @@ int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLe
                 return -1;
             }
             /* Write message id */
-            memcpy(log->buffer,&(mid),sizeof(uint32_t));
+            memcpy(log->buffer,&(messageid),sizeof(uint32_t));
             log->size = sizeof(uint32_t);
 
             /* as the message id is part of each message in non-verbose mode,
                it doesn't increment the argument counter in extended header (if used) */
         }
+        else log->size=0;
         return 1;
     }
     else
@@ -968,7 +1226,7 @@ int dlt_user_log_write_finish(DltContextData *log)
         return -1;
     }
 
-    return dlt_user_log_send_log(log, DLT_TYPE_LOG);
+    return dlt_user_log_send_log(log, DLT_TYPE_LOG) < 0 ? -1 : 0;
 }
 
 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
@@ -1510,7 +1768,50 @@ int dlt_user_log_write_string(DltContextData *log, const char *text)
             return -1;
         }
 
-        type_info = DLT_TYPE_INFO_STRG;
+        type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII;
+
+        memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
+        log->size += sizeof(uint32_t);
+    }
+
+    arg_size = strlen(text) + 1;
+
+    memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
+    log->size += sizeof(uint16_t);
+
+    memcpy((log->buffer)+log->size,text,arg_size);
+    log->size += arg_size;
+
+    log->args_num ++;
+
+    return 0;
+}
+
+int dlt_user_log_write_utf8_string(DltContextData *log, const char *text)
+{
+    uint16_t arg_size;
+    uint32_t type_info;
+
+    if ((log==0) || (text==0))
+    {
+        return -1;
+    }
+
+    arg_size = strlen(text)+1;
+
+    if ((log->size+arg_size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
+    {
+        return -1;
+    }
+
+    if (dlt_user.verbose_mode)
+    {
+        if ((log->size+arg_size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
+        {
+            return -1;
+        }
+
+        type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8;
 
         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
         log->size += sizeof(uint32_t);
@@ -1533,7 +1834,7 @@ int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
                                     int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
 {
     DltContextData log;
-    int i,j,k;
+    uint32_t i,j,k;
     int found = 0;
 
        DltUserInjectionCallback *old;
@@ -1593,11 +1894,22 @@ int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
         if (dlt_user.dlt_ll_ts[i].injection_table == 0)
         {
             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
+            if(dlt_user.dlt_ll_ts[i].injection_table == 0)
+            {
+               DLT_SEM_FREE();
+               return -1;
+            }
         }
         else
         {
             old = dlt_user.dlt_ll_ts[i].injection_table;
             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
+            if(dlt_user.dlt_ll_ts[i].injection_table == 0)
+            {
+               dlt_user.dlt_ll_ts[i].injection_table = old;
+               DLT_SEM_FREE();
+               return -1;
+            }
             memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
             free(old);
         }
@@ -1613,36 +1925,42 @@ int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
     return 0;
 }
 
-int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
-{
-    DltContextData log;
+/**
+ * NW Trace related
+ */
 
-    if (dlt_user_initialised==0)
-    {
-        if (dlt_init()<0)
-        {
-            return -1;
-        }
-    }
 
-    if (dlt_user_log_init(handle, &log)==-1)
-    {
+int check_buffer()
+{
+       int total_size, used_size;
+       dlt_user_check_buffer(&total_size, &used_size);
+
+       if((total_size - used_size) < (total_size/2))
+       {
                return -1;
-    }
+       }
+       return 1;
+}
 
-    if (handle==0)
-    {
-        return -1;
-    }
+/**
+ * Send the start of a segment chain.
+ * Returns -1 on failure
+ */
+int dlt_user_trace_network_segmented_start(uint16_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len)
+{
 
-    /* Commented out because of DltNetworkTraceType:
+    DltContextData log;
+       struct timeval tv;
 
-    if ((nw_trace_type<=0) || (nw_trace_type>0x15))
+    if (handle==NULL)
     {
         return -1;
     }
 
-    */
+    if (dlt_user_log_init(handle, &log)==-1)
+    {
+               return -1;
+    }
 
     DLT_SEM_LOCK();
 
@@ -1660,26 +1978,51 @@ int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type
         log.trace_status = nw_trace_type;
         log.size = 0;
 
-        if (header==0)
+       gettimeofday(&tv, NULL);
+       *id = tv.tv_usec;
+
+       /* Write identifier */
+        if(dlt_user_log_write_string(&log, "NWST") < 0)
         {
-            header_len=0;
+               return -1;
         }
 
-        /* Write header and its length */
-        if (dlt_user_log_write_raw(&log, header, header_len)==-1)
+        /* Write stream handle */
+        if(dlt_user_log_write_uint16(&log, *id) < 0)
         {
                return -1;
         }
 
-        if (payload==0)
+        /* Write header */
+        if(dlt_user_log_write_raw(&log, header, header_len) < 0)
         {
-            payload_len=0;
+               return -1;
         }
 
-        /* Write payload and its length */
-        if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
+        /* Write size of payload */
+        if(dlt_user_log_write_uint16(&log, payload_len) < 0)
         {
-                       return -1;
+               return -1;
+        }
+
+        /* Write expected segment count */
+        uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
+
+        /* If segments align perfectly with segment size, avoid sending empty segment */
+        if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
+        {
+               segment_count--;
+        }
+
+        if(dlt_user_log_write_uint16(&log, segment_count) < 0)
+        {
+               return -1;
+        }
+
+        /* Write length of one segment */
+        if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
+        {
+               return -1;
         }
 
         /* Send log */
@@ -1689,15 +2032,441 @@ int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type
     {
         DLT_SEM_FREE();
     }
-
     return 0;
 }
 
-int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
+int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
 {
-    DltContextData log;
+       while(check_buffer() < 0)
+       {
+               usleep(1000*50); // Wait 50ms
+               dlt_user_log_resend_buffer();
+       }
 
-    if (dlt_user.verbose_mode==0)
+    if (handle==NULL)
+    {
+        return -1;
+    }
+
+    DltContextData log;
+
+    if (dlt_user_log_init(handle, &log)==-1)
+    {
+               return -1;
+    }
+
+    DLT_SEM_LOCK();
+
+    if (dlt_user.dlt_ll_ts==0)
+    {
+        DLT_SEM_FREE();
+        return -1;
+    }
+
+    if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
+    {
+        DLT_SEM_FREE();
+
+        log.args_num = 0;
+        log.trace_status = nw_trace_type;
+        log.size = 0;
+
+        /* Write identifier */
+        if(dlt_user_log_write_string(&log, "NWCH") < 0)
+        {
+               return -1;
+        }
+
+        /* Write stream handle */
+        if(dlt_user_log_write_uint16(&log, id) < 0)
+        {
+               return -1;
+        }
+
+        /* Write segment sequence number */
+        if(dlt_user_log_write_uint16(&log, sequence) < 0)
+        {
+               return -1;
+        }
+
+        /* Write data */
+        if(dlt_user_log_write_raw(&log, payload, payload_len) < 0)
+        {
+               return -1;
+        }
+
+        /* Send log */
+        return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
+    }
+    else
+    {
+        DLT_SEM_FREE();
+    }
+
+    /* Allow other threads to log between chunks */
+       pthread_yield();
+    return 0;
+}
+
+int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
+{
+    DltContextData log;
+
+    if (handle==0)
+    {
+        return -1;
+    }
+
+    if (dlt_user_log_init(handle, &log)==-1)
+    {
+               return -1;
+    }
+
+
+
+    DLT_SEM_LOCK();
+
+    if (dlt_user.dlt_ll_ts==0)
+    {
+        DLT_SEM_FREE();
+        return -1;
+    }
+
+    if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
+    {
+        DLT_SEM_FREE();
+
+        log.args_num = 0;
+        log.trace_status = nw_trace_type;
+        log.size = 0;
+
+        /* Write identifier */
+        if(dlt_user_log_write_string(&log, "NWEN") < 0)
+        {
+               return -1;
+        }
+
+        /* Write stream handle */
+        if(dlt_user_log_write_uint(&log, id) < 0)
+        {
+               return -1;
+        }
+
+        /* Send log */
+        return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
+    }
+    else
+    {
+        DLT_SEM_FREE();
+    }
+    return 0;
+}
+
+
+void dlt_user_trace_network_segmented_thread(void *unused)
+{
+       /* Unused on purpose. */
+       (void) unused;
+
+       s_segmented_data *data;
+
+        while(1)
+        {
+                // Wait until message queue is initialized
+                pthread_mutex_lock(&mq_mutex);
+                if(dlt_user.dlt_segmented_queue_read_handle < 0)
+                {
+                        pthread_cond_wait(&mq_init_condition, &mq_mutex);
+                }
+                pthread_mutex_unlock(&mq_mutex);
+
+                ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
+                                        sizeof(s_segmented_data * ), NULL);
+
+                if(read != sizeof(s_segmented_data *))
+                {
+
+                        char str[255];
+                        snprintf(str,254,"NWTSegmented: Error while reading queue: %s \n",strerror(errno));
+                        dlt_log(LOG_CRIT, str);
+                        continue;
+                }
+
+                /* Indicator just to try to flush the buffer */
+                if(data->payload_len == DLT_DELAYED_RESEND_INDICATOR_PATTERN)
+                {
+                        // Sleep 100ms, to allow other process to read FIFO
+                        usleep(100*1000);
+                        if(dlt_user_log_resend_buffer() < 0)
+                        {
+                                // Requeue if still not empty
+                                if ( dlt_user_queue_resend() < 0 )
+                                    dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n");
+                        }
+                        free(data);
+                        continue;
+                }
+
+                dlt_user_trace_network_segmented_thread_segmenter(data);
+
+                /* Send the end message */
+                DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type);
+                if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
+                {
+                        dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n");
+                }
+
+                /* Free resources */
+                free(data->header);
+                free(data->payload);
+                free(data);
+        }
+}
+
+void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data)
+{
+        /* Segment the data and send the chunks */
+        void *ptr                      = NULL;
+        uint16_t offset                = 0;
+        uint16_t sequence      = 0;
+        do
+        {
+                uint16_t len = 0;
+                if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
+                {
+                        len = data->payload_len - offset;
+                }
+                else
+                {
+                        len = DLT_MAX_TRACE_SEGMENT_SIZE;
+                }
+                /* If payload size aligns perfectly with segment size, avoid sending empty segment */
+                if(len == 0)
+                {
+                        break;
+                }
+
+                ptr = data->payload + offset;
+                DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
+                if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
+                {
+                        dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
+                        break; // loop
+                }
+                offset += len;
+        }while(ptr < data->payload + data->payload_len);
+}
+
+
+int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
+{
+       /* Send as normal trace if possible */
+       if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
+               return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
+       }
+
+       /* Allocate Memory */
+       s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
+       if(thread_data == NULL)
+       {
+               return -1;
+       }
+       thread_data->header = malloc(header_len);
+       if(thread_data->header == NULL)
+       {
+               free(thread_data);
+               return -1;
+       }
+       thread_data->payload = malloc(payload_len);
+       if(thread_data->payload == NULL)
+       {
+               free(thread_data->header);
+               free(thread_data);
+               return -1;
+       }
+
+       /* Copy data */
+       thread_data->handle = handle;
+       thread_data->nw_trace_type = nw_trace_type;
+       thread_data->header_len = header_len;
+       memcpy(thread_data->header, header, header_len);
+       thread_data->payload_len = payload_len;
+       memcpy(thread_data->payload, payload, payload_len);
+
+       /* Send start message */
+       DltReturnValue err =    dlt_user_trace_network_segmented_start(&(thread_data->id),
+                                                       thread_data->handle, thread_data->nw_trace_type,
+                                                       thread_data->header_len, thread_data->header,
+                                                       thread_data->payload_len);
+       if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
+       {
+               dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
+               free(thread_data->header);
+               free(thread_data->payload);
+               free(thread_data);
+               return -1;
+       }
+
+       /* Open queue if it is not open */
+       if(dlt_init_message_queue() < 0)
+       {
+                dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
+                free(thread_data->header);
+                free(thread_data->payload);
+                free(thread_data);
+
+               return -1;
+       }
+
+       /* Add to queue */
+       if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
+                       (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
+       {
+               if(errno == EAGAIN)
+               {
+                       dlt_log(LOG_ERR, "NWTSegmented: Queue full. Message discarded.\n");
+               }
+               free(thread_data->header);
+               free(thread_data->payload);
+               free(thread_data);              
+        char str[256];
+        snprintf(str,255,"NWTSegmented: Could not write into queue: %s \n",strerror(errno));
+        dlt_log(LOG_CRIT, str);
+               return -1;
+       }
+
+        //thread_data will be freed by the receiver function
+        //coverity[leaked_storage]
+       return 0;
+}
+
+int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
+{
+       return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
+}
+
+int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate)
+{
+    DltContextData log;
+
+    if (dlt_user_initialised==0)
+    {
+        if (dlt_init()<0)
+        {
+            return -1;
+        }
+    }
+
+    if (dlt_user_log_init(handle, &log)==-1)
+    {
+               return -1;
+    }
+
+    if (handle==0)
+    {
+        return -1;
+    }
+
+    /* Commented out because of DltNetworkTraceType:
+
+    if ((nw_trace_type<=0) || (nw_trace_type>0x15))
+    {
+        return -1;
+    }
+
+    */
+
+    DLT_SEM_LOCK();
+
+    if (dlt_user.dlt_ll_ts==0)
+    {
+        DLT_SEM_FREE();
+        return -1;
+    }
+
+    if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
+    {
+        DLT_SEM_FREE();
+
+        log.args_num = 0;
+        log.trace_status = nw_trace_type;
+        log.size = 0;
+
+        if (header==0)
+        {
+            header_len=0;
+        }
+
+        /* If truncation is allowed, check if we must do it */
+        if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
+        {
+               /* Identify as truncated */
+               if(dlt_user_log_write_string(&log, "NWTR") < 0)
+               {
+                       return -1;
+               }
+
+            /* Write header and its length */
+            if (dlt_user_log_write_raw(&log, header, header_len) < 0)
+            {
+               return -1;
+            }
+
+               /* Write original size of payload */
+            if(dlt_user_log_write_uint16(&log, payload_len) < 0)
+            {
+               return -1;
+            }
+
+               /**
+                *  Calculate maximum avaialble space in sending buffer after headers.
+                */
+
+               int truncated_payload_len = DLT_USER_BUF_MAX_SIZE -
+                               log.size - sizeof(uint16_t) - sizeof(uint32_t);
+
+            /* Write truncated payload */
+            if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < 0)
+            {
+                       return -1;
+            }
+        }
+        else /* Truncation not allowed or data short enough */
+        {
+            /* Write header and its length */
+            if (dlt_user_log_write_raw(&log, header, header_len)==-1)
+            {
+               return -1;
+            }
+
+            if (payload==0)
+            {
+                payload_len=0;
+            }
+
+            /* Write payload and its length */
+            if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
+            {
+                       return -1;
+            }
+        }
+
+        /* Send log */
+        return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
+    }
+    else
+    {
+        DLT_SEM_FREE();
+    }
+
+    return 0;
+}
+
+int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
+{
+    DltContextData log;
+
+    if (dlt_user.verbose_mode==0)
     {
         return -1;
     }
@@ -1707,7 +2476,7 @@ int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text
         return -1;
     }
 
-    if (dlt_user_log_write_start(handle,&log,loglevel))
+    if (dlt_user_log_write_start(handle,&log,loglevel)>0)
     {
         if (dlt_user_log_write_string(&log,text)==-1)
         {
@@ -1736,7 +2505,7 @@ int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *
         return -1;
     }
 
-    if (dlt_user_log_write_start(handle,&log,loglevel))
+    if (dlt_user_log_write_start(handle,&log,loglevel)>0)
     {
         if (dlt_user_log_write_string(&log,text)==-1)
         {
@@ -1769,7 +2538,7 @@ int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char
         return -1;
     }
 
-    if (dlt_user_log_write_start(handle,&log,loglevel))
+    if (dlt_user_log_write_start(handle,&log,loglevel)>0)
     {
         if (dlt_user_log_write_string(&log,text)==-1)
         {
@@ -1802,7 +2571,7 @@ int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
         return -1;
     }
 
-    if (dlt_user_log_write_start(handle,&log,loglevel))
+    if (dlt_user_log_write_start(handle,&log,loglevel)>0)
     {
         if (dlt_user_log_write_int(&log,data)==-1)
         {
@@ -1831,7 +2600,7 @@ int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
         return -1;
     }
 
-    if (dlt_user_log_write_start(handle,&log,loglevel))
+    if (dlt_user_log_write_start(handle,&log,loglevel)>0)
     {
         if (dlt_user_log_write_uint(&log,data)==-1)
         {
@@ -1860,7 +2629,7 @@ int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t
         return -1;
     }
 
-    if (dlt_user_log_write_start(handle,&log,loglevel))
+    if (dlt_user_log_write_start(handle,&log,loglevel)>0)
     {
         if (dlt_user_log_write_raw(&log,data,length)==-1)
         {
@@ -1937,7 +2706,7 @@ int dlt_disable_local_print(void)
     return 0;
 }
 
-void dlt_user_receiverthread_function(void *ptr)
+void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
 {
     while (1)
     {
@@ -1965,60 +2734,106 @@ int dlt_user_log_init(DltContext *handle, DltContextData *log)
     }
 
     log->handle = handle;
-    log->mcnt = 0;
 
     return 0;
 }
 
-int dlt_user_log_send_log(DltContextData *log, int mtype)
+int dlt_user_queue_resend(void)
+{
+       if(dlt_user.dlt_log_handle < 0)
+       {
+               // Fail silenty. FIFO is not open yet
+               return -1;
+       }
+    /**
+     * Ask segmented thread to try emptying the buffer soon.
+     * This will be freed in dlt_user_trace_network_segmented_thread
+     * */
+    s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
+
+    if (NULL == resend_data)
+    {
+        return -1;
+    }
+
+    resend_data->payload_len = DLT_DELAYED_RESEND_INDICATOR_PATTERN;
+
+
+
+    /* Open queue if it is not open */
+       if(dlt_init_message_queue() < 0)
+       {
+               dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
+                free(resend_data);
+               return -1;
+       }
+
+    if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
+    {
+        char str[255];
+        snprintf(str,254,"Could not request resending.: %s \n",strerror(errno));
+        dlt_log(LOG_CRIT, str);
+       free(resend_data);
+       return -1;
+    }
+    //thread_data will be freed by the receiver function
+    //coverity[leaked_storage]
+    return 0;
+}
+
+DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
 {
     DltMessage msg;
     DltUserHeader userheader;
     int32_t len;
 
-    DltReturnValue ret;
+    DltReturnValue ret = DLT_RETURN_OK;
 
     if (log==0)
     {
-        return -1;
+        return DLT_RETURN_ERROR;
     }
 
     if (log->handle==0)
     {
-        return -1;
+        return DLT_RETURN_ERROR;
     }
 
     if (dlt_user.appID[0]=='\0')
     {
-        return -1;
+        return DLT_RETURN_ERROR;
     }
 
     if (log->handle->contextID[0]=='\0')
     {
-        return -1;
+        return DLT_RETURN_ERROR;
     }
 
     if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
     {
-        return -1;
+        return DLT_RETURN_ERROR;
     }
 
     /* also for Trace messages */
+#ifdef DLT_SHM_ENABLE
+    if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
+#else
     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
+#endif
     {
-               return -1;
+               return DLT_RETURN_ERROR;
     }
 
     if (dlt_message_init(&msg,0)==-1)
     {
-       return -1;
+       return DLT_RETURN_ERROR;
     }
 
     msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
 
     if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
     {
-               return -1;
+               return DLT_RETURN_ERROR;
     }
 
     msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
@@ -2041,7 +2856,7 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
     msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
 #endif
 
-    msg.standardheader->mcnt = log->mcnt++;
+    msg.standardheader->mcnt = log->handle->mcnt++;
 
     /* Set header extra parameters */
     dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
@@ -2050,7 +2865,7 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
 
     if (dlt_message_set_extraparameters(&msg,0)==-1)
     {
-       return -1;
+       return DLT_RETURN_ERROR;
     }
 
     /* Fill out extended header, if extended header should be provided */
@@ -2074,7 +2889,7 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
         default:
         {
                    /* This case should not occur */
-            return -1;
+            return DLT_RETURN_ERROR;
             break;
         }
         }
@@ -2101,7 +2916,7 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
     if (len>UINT16_MAX)
     {
         dlt_log(LOG_CRIT,"Huge message discarded!\n");
-        return -1;
+        return DLT_RETURN_ERROR;
     }
 
     msg.standardheader->len = DLT_HTOBE_16(len);
@@ -2114,7 +2929,7 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
         {
             if (dlt_user_print_msg(&msg, log)==-1)
             {
-                               return -1;
+                               return DLT_RETURN_ERROR;
             }
         }
     }
@@ -2123,7 +2938,7 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
     {
         /* log to file */
         ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
-        return ((ret==DLT_RETURN_OK)?0:-1);
+        return ret;
     }
     else
     {
@@ -2138,35 +2953,78 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
             }
         }
 
-        /* log to FIFO */
-        ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
-                                &(userheader), sizeof(DltUserHeader),
-                                msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
-                                log->buffer, log->size);
-
+               /* try to resent old data first */
+               ret = DLT_RETURN_OK;
+               if(dlt_user.dlt_log_handle!=-1)
+                       ret = dlt_user_log_resend_buffer();
+               if(ret==DLT_RETURN_OK)
+               {
+                       /* resend ok or nothing to resent */
+#ifdef DLT_SHM_ENABLE
+                       if(dlt_user.dlt_log_handle!=-1)
+                               dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
+                                                                                       log->buffer, log->size,0,0);                   
+
+                       /* log to FIFO */
+                       ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
+                                                                       &(userheader), sizeof(DltUserHeader),
+                                                                       0, 0,
+                                                                       0, 0);
+#else
+                       /* log to FIFO */
+#ifdef DLT_TEST_ENABLE
+                       if(dlt_user.corrupt_user_header) {
+                               userheader.pattern[0]=0xff;
+                               userheader.pattern[1]=0xff;
+                               userheader.pattern[2]=0xff;
+                               userheader.pattern[3]=0xff;
+                       }
+                       if(dlt_user.corrupt_message_size) {
+                               msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
+                       }
+#endif
+                       ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
+                                                                       &(userheader), sizeof(DltUserHeader),
+                                                                       msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
+                                                                       log->buffer, log->size);                
+#endif                 
+               }
+               
         /* store message in ringbuffer, if an error has occured */
         if (ret!=DLT_RETURN_OK)
         {
             DLT_SEM_LOCK();
 
-            if (dlt_ringbuffer_put3(&(dlt_user.rbuf),
-                                &(userheader), sizeof(DltUserHeader),
+            if (dlt_buffer_push3(&(dlt_user.startup_buffer),
+                                (unsigned char *)&(userheader), sizeof(DltUserHeader),
                                 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
                                 log->buffer, log->size)==-1)
                        {
                                dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
+                               ret = DLT_RETURN_BUFFER_FULL;
                        }
 
             DLT_SEM_FREE();
+
+               // Fail silenty if FIFO is not open
+            if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
+            {
+                dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
+            }
         }
 
         switch (ret)
         {
+        case DLT_RETURN_BUFFER_FULL:
+        {
+               /* Buffer full */
+               return DLT_RETURN_BUFFER_FULL;
+        }
         case DLT_RETURN_PIPE_FULL:
         {
             /* data could not be written */
             dlt_user.overflow = 1;
-            return -1;
+            return DLT_RETURN_PIPE_FULL;
         }
         case DLT_RETURN_PIPE_ERROR:
         {
@@ -2174,31 +3032,36 @@ int dlt_user_log_send_log(DltContextData *log, int mtype)
             close(dlt_user.dlt_log_handle);
             dlt_user.dlt_log_handle = -1;
 
+#ifdef DLT_SHM_ENABLE
+                       /* free shared memory */
+                       dlt_shm_free_client(&dlt_user.dlt_shm);
+#endif
+
             if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
             {
                 dlt_user_print_msg(&msg, log);
             }
 
-            return -1;
+            return DLT_RETURN_PIPE_ERROR;
         }
         case DLT_RETURN_ERROR:
         {
             /* other error condition */
-            return -1;
+            return DLT_RETURN_ERROR;
         }
                case DLT_RETURN_OK:
         {
-               return 0;
+               return DLT_RETURN_OK;
         }
                default:
                {
                        /* This case should never occur. */
-                       return -1;
+                       return DLT_RETURN_ERROR;
                }
         }
     }
 
-    return 0;
+    return DLT_RETURN_OK;
 }
 
 int dlt_user_log_send_register_application(void)
@@ -2239,7 +3102,31 @@ int dlt_user_log_send_register_application(void)
 
     /* log to FIFO */
     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
-       return ((ret==DLT_RETURN_OK)?0:-1);
+
+    /* store message in ringbuffer, if an error has occured */
+    if (ret!=DLT_RETURN_OK)
+    {
+        DLT_SEM_LOCK();
+
+        if (dlt_buffer_push3(&(dlt_user.startup_buffer),
+                            (unsigned char *)&(userheader), sizeof(DltUserHeader),
+                            (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
+                            (const unsigned char*)dlt_user.application_description, usercontext.description_length)==-1)
+             {
+                    dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
+                    DLT_SEM_FREE();
+                    return -1;
+             }
+
+        DLT_SEM_FREE();
+
+        if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
+        {
+            dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n");
+        }
+    }
+
+    return 0;
 }
 
 int dlt_user_log_send_unregister_application(void)
@@ -2326,7 +3213,32 @@ int dlt_user_log_send_register_context(DltContextData *log)
 
     /* log to FIFO */
     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
-    return ((ret==DLT_RETURN_OK)?0:-1);
+
+    /* store message in ringbuffer, if an error has occured */
+    if (ret!=DLT_RETURN_OK)
+    {
+        DLT_SEM_LOCK();
+
+        if (dlt_buffer_push3(&(dlt_user.startup_buffer),
+                            (unsigned char *)&(userheader), sizeof(DltUserHeader),
+                            (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
+                            (const unsigned char*)log->context_description, usercontext.description_length)==-1)
+             {
+                    dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
+                    DLT_SEM_FREE();
+                    return -1;
+             }
+
+        DLT_SEM_FREE();
+
+        if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
+        {
+            dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n");
+        }
+    }
+
+    return 0;
+
 }
 
 int dlt_user_log_send_unregister_context(DltContextData *log)
@@ -2417,10 +3329,38 @@ int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTra
     return ((ret==DLT_RETURN_OK)?0:-1);
 }
 
+int dlt_user_log_send_log_mode(DltUserLogMode mode)
+{
+    DltUserHeader userheader;
+    DltUserControlMsgLogMode logmode;
+
+    DltReturnValue ret;
+
+    /* set userheader */
+    if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
+    {
+       return -1;
+    }
+
+    /* set data */
+    logmode.log_mode = (unsigned char) mode;
+
+    if (dlt_user.dlt_is_file)
+    {
+        return 0;
+    }
+
+    /* log to FIFO */
+    ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
+    return ((ret==DLT_RETURN_OK)?0:-1);
+}
+
 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
 {
     uint8_t *databuffer_tmp;
     int32_t datasize_tmp;
+    int32_t databuffersize_tmp;
+    static char text[DLT_USER_TEXT_LENGTH];
 
     if ((msg==0) || (log==0))
     {
@@ -2430,6 +3370,7 @@ int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
     /* Save variables before print */
     databuffer_tmp = msg->databuffer;
     datasize_tmp = msg->datasize;
+    databuffersize_tmp = msg->databuffersize;
 
     /* Act like a receiver, convert header back to host format */
     msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
@@ -2437,6 +3378,7 @@ int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
 
     msg->databuffer = log->buffer;
     msg->datasize = log->size;
+    msg->databuffersize = log->size;
 
     /* Print message as ASCII */
     if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
@@ -2446,6 +3388,7 @@ int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
 
     /* Restore variables and set len to BE*/
     msg->databuffer = databuffer_tmp;
+    msg->databuffersize = databuffersize_tmp;
     msg->datasize =  datasize_tmp;
 
     msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
@@ -2458,18 +3401,26 @@ int dlt_user_log_check_user_message(void)
     int offset=0;
     int leave_while=0;
 
-    int i;
+    uint32_t i;
 
     DltUserHeader *userheader;
     DltReceiver *receiver = &(dlt_user.receiver);
 
     DltUserControlMsgLogLevel *usercontextll;
-
     DltUserControlMsgInjection *usercontextinj;
+    DltUserControlMsgLogState *userlogstate;
     unsigned char *userbuffer;
-    unsigned char *inject_buffer;
 
-    if (dlt_user.dlt_user_handle!=-1)
+    /* For delayed calling of injection callback, to avoid deadlock */
+    DltUserInjectionCallback   delayed_injection_callback;
+    unsigned char                              *delayed_inject_buffer = 0;
+    uint32_t                                   delayed_inject_data_length = 0;
+
+    /* Ensure that callback is null before searching for it */
+    delayed_injection_callback.injection_callback = 0;
+    delayed_injection_callback.service_id = 0;
+
+    if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
     {
         while (1)
         {
@@ -2482,7 +3433,7 @@ int dlt_user_log_check_user_message(void)
             /* look through buffer as long as data is in there */
             while (1)
             {
-                if (receiver->bytesRcvd < sizeof(DltUserHeader))
+                if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
                 {
                     break;
                 }
@@ -2501,10 +3452,11 @@ int dlt_user_log_check_user_message(void)
                     offset++;
 
                 }
-                while ((sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
+                while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
 
                 /* Check for user header pattern */
-                if (dlt_user_check_userheader(userheader)==0)
+                if (dlt_user_check_userheader(userheader)<0 ||
+                    dlt_user_check_userheader(userheader)==0)
                 {
                     break;
                 }
@@ -2520,7 +3472,7 @@ int dlt_user_log_check_user_message(void)
                 {
                 case DLT_USER_MESSAGE_LOG_LEVEL:
                 {
-                    if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
+                    if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
                     {
                         leave_while=1;
                         break;
@@ -2533,7 +3485,7 @@ int dlt_user_log_check_user_message(void)
                     {
                         DLT_SEM_LOCK();
 
-                        if ((usercontextll->log_level_pos>=0) && (usercontextll->log_level_pos<dlt_user.dlt_ll_ts_num_entries))
+                        if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
                         {
                             // printf("Store ll, ts\n");
                             if (dlt_user.dlt_ll_ts)
@@ -2556,7 +3508,7 @@ int dlt_user_log_check_user_message(void)
                 case DLT_USER_MESSAGE_INJECTION:
                 {
                     /* At least, user header, user context, and service id and data_length of injected message is available */
-                    if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
+                    if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
                     {
                         leave_while = 1;
                         break;
@@ -2564,12 +3516,11 @@ int dlt_user_log_check_user_message(void)
 
                     usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
                     userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
-                    inject_buffer = 0;
 
                     if (userbuffer!=0)
                     {
 
-                        if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
+                        if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
                         {
                             leave_while = 1;
                             break;
@@ -2585,28 +3536,18 @@ int dlt_user_log_check_user_message(void)
                                 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
                                         (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
                                 {
-                                    /* callback available, so prepare data, then call it */
-                                    inject_buffer = malloc(usercontextinj->data_length_inject);
-                                    if (inject_buffer!=0)
-                                    {
-                                        /* copy from receiver to inject_buffer */
-                                        memcpy(inject_buffer, userbuffer, usercontextinj->data_length_inject);
-
-                                        /* call callback */
-                                        if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
-                                        {
-                                            // printf("Got injection(%d), length=%d, '%s' \n", usercontext->service_id, usercontext->data_length_inject, inject_buffer);
-                                            dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback(
-                                                usercontextinj->service_id, inject_buffer, usercontextinj->data_length_inject);
-                                        }
-
-                                        if (inject_buffer!=0)
-                                        {
-                                            free(inject_buffer);
-                                            inject_buffer = 0;
-                                        }
-                                    }
-
+                                       /* Prepare delayed injection callback call */
+                                                                       if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
+                                                                       {
+                                                                               delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
+                                                                               delayed_injection_callback.service_id = usercontextinj->service_id;
+                                                                               delayed_inject_data_length = usercontextinj->data_length_inject;
+                                                                               delayed_inject_buffer = malloc(delayed_inject_data_length);
+                                                                               if(delayed_inject_buffer != 0) {
+                                                                                       memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
+                                                                               }
+
+                                                                       }
                                     break;
                                 }
                             }
@@ -2614,6 +3555,15 @@ int dlt_user_log_check_user_message(void)
 
                         DLT_SEM_FREE();
 
+                        /* Delayed injection callback call */
+                        if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
+                               delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
+                                delayed_injection_callback.injection_callback = 0;
+                                free(delayed_inject_buffer);
+                                delayed_inject_buffer = NULL;
+
+                        }
+
                         /* keep not read data in buffer */
                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
                                                {
@@ -2622,6 +3572,25 @@ int dlt_user_log_check_user_message(void)
                     }
                 }
                 break;
+                case DLT_USER_MESSAGE_LOG_STATE:
+                {
+                    /* At least, user header, user context, and service id and data_length of injected message is available */
+                    if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
+                    {
+                        leave_while = 1;
+                        break;
+                    }
+
+                    userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
+                                       dlt_user.log_state = userlogstate->log_state;
+
+                                       /* keep not read data in buffer */
+                                       if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
+                                       {
+                                               return -1;
+                                       }
+                }
+                break;
                 default:
                 {
                     dlt_log(LOG_ERR,"Invalid user message type received!\n");
@@ -2647,19 +3616,62 @@ int dlt_user_log_check_user_message(void)
         } /* while receive */
     } /* if */
 
-    return 0;
+    return DLT_RETURN_OK;
 }
 
-void dlt_user_log_reattach_to_daemon(void)
+int dlt_user_log_resend_buffer(void)
 {
-    int num, count, reregistered=0;
+       int num,count;
+    int size;
+       DltReturnValue ret;
+       
+       /* Send content of ringbuffer */
+       DLT_SEM_LOCK();
+       count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
+       DLT_SEM_FREE();
+
+       for (num=0;num<count;num++)
+       {
+
+               DLT_SEM_LOCK();
+               size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer));
+
+               if (size>0)
+               {
+#ifdef DLT_SHM_ENABLE                                          
+                       dlt_shm_push(&dlt_user.dlt_shm,dlt_user.resend_buffer+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
+
+                       /* log to FIFO */
+                       ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader),0,0,0,0);
+#else
+                       /* log to FIFO */
+                       ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size,0,0,0,0);
+#endif
+
+                       /* in case of error, keep message in ringbuffer */                        
+                       if (ret==DLT_RETURN_OK)
+                       {
+                               dlt_buffer_remove(&(dlt_user.startup_buffer));
+                       }
+                       else
+                       {
+                               /* keep message in ringbuffer */   
+                               DLT_SEM_FREE();
+                               return -1;
+                       }
+               }
+               DLT_SEM_FREE();
+       }
+       
+       return 0;
+}
 
-    uint8_t buf[DLT_USER_RINGBUFFER_SIZE];
-    size_t size;
+void dlt_user_log_reattach_to_daemon(void)
+{
+       uint32_t num,reregistered=0;
 
        DltContext handle;
        DltContextData log_new;
-       DltReturnValue ret;
 
     if (dlt_user.dlt_log_handle<0)
     {
@@ -2674,6 +3686,16 @@ void dlt_user_log_reattach_to_daemon(void)
                return;
             }
 
+#ifdef DLT_SHM_ENABLE
+                       /* init shared memory */
+                       if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
+                       {
+                               sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
+                               dlt_log(LOG_WARNING, str);
+                               //return 0; 
+                       }   
+#endif
+
             dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
 
             /* Re-register application */
@@ -2688,7 +3710,7 @@ void dlt_user_log_reattach_to_daemon(void)
             for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
             {
                 /* Re-register stored context */
-                if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
+                if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0'))
                 {
                     //dlt_set_id(log_new.appID, dlt_user.appID);
                     dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
@@ -2712,42 +3734,7 @@ void dlt_user_log_reattach_to_daemon(void)
 
             if (reregistered==1)
             {
-                /* Send content of ringbuffer */
-                DLT_SEM_LOCK();
-                count = dlt_user.rbuf.count;
-                DLT_SEM_FREE();
-
-                for (num=0;num<count;num++)
-                {
-
-                    DLT_SEM_LOCK();
-                    dlt_ringbuffer_get(&(dlt_user.rbuf),buf,&size);
-                    DLT_SEM_FREE();
-
-                    if (size>0)
-                    {
-                        /* log to FIFO */
-                        ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0);
-
-                        /* in case of error, push message back to ringbuffer */
-                        if (ret!=DLT_RETURN_OK)
-                        {
-                            DLT_SEM_LOCK();
-                            if (dlt_ringbuffer_put(&(dlt_user.rbuf), buf, size)==-1)
-                            {
-                                                               dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n");
-                            }
-                            DLT_SEM_FREE();
-
-                            /* In case of: data could not be written, set overflow flag */
-                            if (ret==DLT_RETURN_PIPE_FULL)
-                            {
-                                dlt_user.overflow = 1;
-                            }
-                        }
-                    }
-
-                }
+                               dlt_user_log_resend_buffer();
             }
         }
     }
@@ -2774,3 +3761,29 @@ int dlt_user_log_send_overflow(void)
     return ((ret==DLT_RETURN_OK)?0:-1);
 }
 
+int dlt_user_check_buffer(int *total_size, int *used_size)
+{
+#ifdef DLT_SHM_ENABLE
+       *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
+       *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
+#else
+       *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
+       *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
+#endif
+       
+       return 0; /* ok */
+}
+
+#ifdef DLT_TEST_ENABLE
+void dlt_user_test_corrupt_user_header(int enable)
+{
+    dlt_user.corrupt_user_header = enable;
+}
+void dlt_user_test_corrupt_message_size(int enable,int16_t size)
+{
+    dlt_user.corrupt_message_size = enable;
+    dlt_user.corrupt_message_size_size = size;
+}
+#endif
+
+