Bug 84 - Adding utf8 support to dlt-daemon, dlt-viewer. Modified patch, originally...
[profile/ivi/dlt-daemon.git] / src / lib / dlt_user.c
index 199b943..1f43801 100644 (file)
@@ -134,6 +134,7 @@ 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){
@@ -325,8 +326,9 @@ int dlt_init_message_queue(void)
                dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
                if(mq_unlink(queue_name) < 0)
                {
-                       dlt_log(LOG_CRIT, "Could not delete existing message queue!\n");
-                       dlt_log(LOG_CRIT, strerror(errno));
+                char str[256];
+                snprintf(str,255,"Could not delete existing message queue!: %s \n",strerror(errno));
+                dlt_log(LOG_CRIT, str);
                }
                else // Retry
                {
@@ -336,8 +338,9 @@ int dlt_init_message_queue(void)
        }
        if(dlt_user.dlt_segmented_queue_read_handle < 0)
        {
-               dlt_log(LOG_CRIT, "Can't create message queue read handle!\n");
-               dlt_log(LOG_CRIT, strerror(errno));
+            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;
        }
@@ -346,8 +349,10 @@ int dlt_init_message_queue(void)
     dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
     if(dlt_user.dlt_segmented_queue_write_handle < 0)
     {
-       dlt_log(LOG_CRIT, "Can't open message queue write handle!\n");
-       dlt_log(LOG_CRIT, strerror(errno));
+
+        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;
     }
@@ -405,6 +410,7 @@ 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;
@@ -412,8 +418,10 @@ int dlt_init_common(void)
     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 */
 
@@ -430,6 +438,10 @@ int dlt_init_common(void)
 
 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();
@@ -518,6 +530,7 @@ int dlt_free(void)
        /* Ignore return value */
     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++)
@@ -535,6 +548,7 @@ 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)
     {
@@ -1100,7 +1114,7 @@ int dlt_forward_msg(void *msgdata,size_t size)
 
             if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
             {
-               dlt_log(LOG_WARNING, "Failed to queue resending.\n");
+                dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n");
             }
         }
 
@@ -1754,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);
@@ -2105,6 +2162,7 @@ int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNet
     return 0;
 }
 
+
 void dlt_user_trace_network_segmented_thread(void *unused)
 {
        /* Unused on purpose. */
@@ -2112,85 +2170,94 @@ void dlt_user_trace_network_segmented_thread(void *unused)
 
        s_segmented_data *data;
 
-       while(1)
-       {
-               // Wait untill 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);
+        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);
+                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 *))
-               {
-                       dlt_log(LOG_ERR, "NWTSegmented: Error while reading queue.\n");
-                       dlt_log(LOG_ERR, strerror(errno));
-                       continue;
-               }
+                if(read != sizeof(s_segmented_data *))
+                {
 
-               /* 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
-                               dlt_user_queue_resend();
-                       }
-                       free(data);
-                       continue;
-               }
+                        char str[255];
+                        snprintf(str,254,"NWTSegmented: Error while reading queue: %s \n",strerror(errno));
+                        dlt_log(LOG_CRIT, str);
+                        continue;
+                }
 
-               /* 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 sendind empty segment */
-                       if(len == 0)
-                       {
-                               break;
-                       }
+                /* 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;
+                }
 
-                       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; // Inner loop
-                       }
-                       offset += len;
-               }while(ptr < data->payload + data->payload_len);
+                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");
-               }
+                /* 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);
-       }
+                /* 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 */
@@ -2243,7 +2310,11 @@ int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_
        /* Open queue if it is not open */
        if(dlt_init_message_queue() < 0)
        {
-               dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
+                dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
+                free(thread_data->header);
+                free(thread_data->payload);
+                free(thread_data);
+
                return -1;
        }
 
@@ -2257,11 +2328,15 @@ int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_
                }
                free(thread_data->header);
                free(thread_data->payload);
-               free(thread_data);
-               dlt_log(LOG_ERR, "NWTSegmented: Could not write into queue.\n");
-               dlt_log(LOG_ERR, strerror(errno));
+               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;
 }
 
@@ -2689,17 +2764,20 @@ int dlt_user_queue_resend(void)
        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)
     {
-       dlt_log(LOG_ERR,"Could not request resending.\n");
-       dlt_log(LOG_ERR, strerror(errno));
+        char str[255];
+        snprintf(str,254,"Could not request resending.: %s \n",strerror(errno));
+        dlt_log(LOG_CRIT, str);
        free(resend_data);
-       DLT_SEM_FREE();
        return -1;
     }
+    //thread_data will be freed by the receiver function
+    //coverity[leaked_storage]
     return 0;
 }
 
@@ -2931,7 +3009,7 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
                // Fail silenty if FIFO is not open
             if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
             {
-               dlt_log(LOG_WARNING, "Failed to queue resending.\n");
+                dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
             }
         }
 
@@ -3044,7 +3122,7 @@ int dlt_user_log_send_register_application(void)
 
         if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
         {
-               dlt_log(LOG_WARNING, "Failed to queue resending.\n");
+            dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n");
         }
     }
 
@@ -3155,7 +3233,7 @@ int dlt_user_log_send_register_context(DltContextData *log)
 
         if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
         {
-               dlt_log(LOG_WARNING, "Failed to queue resending.\n");
+            dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n");
         }
     }
 
@@ -3377,7 +3455,8 @@ int dlt_user_log_check_user_message(void)
                 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;
                 }
@@ -3479,7 +3558,10 @@ int dlt_user_log_check_user_message(void)
                         /* 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);
-                               free(delayed_inject_buffer);
+                                delayed_injection_callback.injection_callback = 0;
+                                free(delayed_inject_buffer);
+                                delayed_inject_buffer = NULL;
+
                         }
 
                         /* keep not read data in buffer */