LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_common.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 351 623 56.3 %
Date: 2024-11-20 10:17:27 Functions: 23 32 71.9 %

          Line data    Source code
       1             : /*
       2             :  * SPDX license identifier: MPL-2.0
       3             :  *
       4             :  * Copyright (C) 2011-2015, BMW AG
       5             :  *
       6             :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       7             :  *
       8             :  * This Source Code Form is subject to the terms of the
       9             :  * Mozilla Public License (MPL), v. 2.0.
      10             :  * If a copy of the MPL was not distributed with this file,
      11             :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      12             :  *
      13             :  * For further information see http://www.covesa.org/.
      14             :  */
      15             : 
      16             : /*!
      17             :  * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de>
      18             :  *
      19             :  * \copyright Copyright © 2011-2015 BMW AG. \n
      20             :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      21             :  *
      22             :  * \file dlt_daemon_common.c
      23             :  */
      24             : 
      25             : /*******************************************************************************
      26             : **                                                                            **
      27             : **  SRC-MODULE: dlt_daemon_common.c                                           **
      28             : **                                                                            **
      29             : **  TARGET    : linux                                                         **
      30             : **                                                                            **
      31             : **  PROJECT   : DLT                                                           **
      32             : **                                                                            **
      33             : **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
      34             : **              Markus Klein                                                  **
      35             : **                                                                            **
      36             : **  PURPOSE   :                                                               **
      37             : **                                                                            **
      38             : **  REMARKS   :                                                               **
      39             : **                                                                            **
      40             : **  PLATFORM DEPENDANT [yes/no]: yes                                          **
      41             : **                                                                            **
      42             : **  TO BE CHANGED BY USER [yes/no]: no                                        **
      43             : **                                                                            **
      44             : *******************************************************************************/
      45             : 
      46             : /*******************************************************************************
      47             : **                      Author Identity                                       **
      48             : ********************************************************************************
      49             : **                                                                            **
      50             : ** Initials     Name                       Company                            **
      51             : ** --------     -------------------------  ---------------------------------- **
      52             : **  aw          Alexander Wenzel           BMW                                **
      53             : **  mk          Markus Klein               Fraunhofer ESK                     **
      54             : *******************************************************************************/
      55             : 
      56             : /*******************************************************************************
      57             : **                      Revision Control History                              **
      58             : *******************************************************************************/
      59             : 
      60             : /*
      61             :  * $LastChangedRevision: 1670 $
      62             :  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
      63             :  * $LastChangedBy$
      64             :  * Initials    Date         Comment
      65             :  * aw          13.01.2010   initial
      66             :  */
      67             : 
      68             : #include <stdbool.h>
      69             : #include <stdio.h>
      70             : #include <stdlib.h>
      71             : #include <string.h>
      72             : #include <syslog.h>
      73             : #include <errno.h>
      74             : #include <unistd.h>
      75             : #include <fcntl.h>
      76             : 
      77             : #include <sys/socket.h> /* send() */
      78             : 
      79             : #include "dlt_types.h"
      80             : #include "dlt_log.h"
      81             : #include "dlt_daemon_common.h"
      82             : #include "dlt_daemon_common_cfg.h"
      83             : #include "dlt_user_shared.h"
      84             : #include "dlt_user_shared_cfg.h"
      85             : #include "dlt-daemon.h"
      86             : 
      87             : #include "dlt_daemon_socket.h"
      88             : #include "dlt_daemon_serial.h"
      89             : 
      90             : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
      91             : #   include <systemd/sd-daemon.h>
      92             : #endif
      93             : 
      94             : char *app_recv_buffer = NULL; /* pointer to receiver buffer for application msges */
      95             : 
      96           0 : static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
      97             : {
      98         132 :     if ((m1 == NULL) || (m2 == NULL))
      99             :         return -1;
     100             : 
     101             :     DltDaemonApplication *mi1 = (DltDaemonApplication *)m1;
     102             :     DltDaemonApplication *mi2 = (DltDaemonApplication *)m2;
     103             : 
     104         132 :     return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
     105             : }
     106             : 
     107         471 : static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
     108             : {
     109         471 :     if ((m1 == NULL) || (m2 == NULL))
     110             :         return -1;
     111             : 
     112             :     int ret, cmp;
     113             :     DltDaemonContext *mi1 = (DltDaemonContext *)m1;
     114             :     DltDaemonContext *mi2 = (DltDaemonContext *)m2;
     115             : 
     116         471 :     cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
     117             : 
     118         471 :     if (cmp < 0)
     119             :         ret = -1;
     120         471 :     else if (cmp == 0)
     121         471 :         ret = memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
     122             :     else
     123             :         ret = 1;
     124             : 
     125             :     return ret;
     126             : }
     127             : 
     128         474 : DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon,
     129             :                                                      char *ecu,
     130             :                                                      int verbose)
     131             : {
     132         474 :     PRINT_FUNCTION_VERBOSE(verbose);
     133             : 
     134             :     int i = 0;
     135             : 
     136         474 :     if ((daemon == NULL) || (ecu == NULL)) {
     137           0 :         dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
     138           0 :         return (DltDaemonRegisteredUsers *)NULL;
     139             :     }
     140             : 
     141         476 :     for (i = 0; i < daemon->num_user_lists; i++)
     142         444 :         if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0)
     143         442 :             return &daemon->user_list[i];
     144             : 
     145          32 :     dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %4s\n", ecu);
     146          32 :     return (DltDaemonRegisteredUsers *)NULL;
     147             : }
     148             : 
     149             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     150             : 
     151             : static int dlt_daemon_cmp_log_settings(const void *lhs, const void *rhs) {
     152             :     if ((lhs == NULL) || (rhs == NULL))
     153             :         return -1;
     154             : 
     155             :     DltDaemonContextLogSettings *settings1 = (DltDaemonContextLogSettings *)lhs;
     156             :     DltDaemonContextLogSettings *settings2 = (DltDaemonContextLogSettings *)rhs;
     157             : 
     158             :     int cmp = memcmp(settings1->apid, settings2->apid, DLT_ID_SIZE);
     159             : 
     160             :     if (cmp < 0)
     161             :         return -1;
     162             :     else if (cmp == 0)
     163             :         return memcmp(settings1->ctid, settings2->ctid, DLT_ID_SIZE);
     164             :     else
     165             :         return 1;
     166             : }
     167             : 
     168             : /**
     169             :  * Find configuration for app/ctx id specific log settings configuration
     170             :  * @param daemon pointer to dlt daemon struct
     171             :  * @param apid application id to use
     172             :  * @param ctid context id to use, can be NULL
     173             :  * @return pointer to log settings if found, otherwise NULL
     174             :  */
     175             : DltDaemonContextLogSettings *dlt_daemon_find_configured_app_id_ctx_id_settings(
     176             :     const DltDaemon *daemon, const char *apid, const char *ctid) {
     177             :     DltDaemonContextLogSettings *app_id_settings = NULL;
     178             :     for (int i = 0; i < daemon->num_app_id_log_level_settings; ++i) {
     179             :         DltDaemonContextLogSettings *settings = &daemon->app_id_log_level_settings[i];
     180             : 
     181             :         if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
     182             :             if (app_id_settings != NULL)
     183             :                 return app_id_settings;
     184             :             continue;
     185             :         }
     186             : 
     187             :         if (strlen(settings->ctid) == 0) {
     188             :             app_id_settings = settings;
     189             :         }
     190             : 
     191             :         if (ctid == NULL || strlen(ctid) == 0) {
     192             :             if (app_id_settings != NULL) {
     193             :                 return app_id_settings;
     194             :             }
     195             :         } else {
     196             :             if (strncmp(ctid, settings->ctid, DLT_ID_SIZE) == 0) {
     197             :                 return settings;
     198             :             }
     199             :         }
     200             :     }
     201             : 
     202             :     return app_id_settings;
     203             : }
     204             : 
     205             : /**
     206             :  * Find configured log levels in a given DltDaemonApplication for the passed context id.
     207             :  * @param app The application settings which contain the previously loaded ap id settings
     208             :  * @param ctid The context id to find.
     209             :  * @return Pointer to DltDaemonApplicationLogSettings containing the log level
     210             :  *         for the requested application or NULL if none found.
     211             :  */
     212             : DltDaemonContextLogSettings *dlt_daemon_find_app_log_level_config(
     213             :     const DltDaemonApplication *const app, const char *const ctid) {
     214             : 
     215             :     if (NULL == ctid)
     216             :         return NULL;
     217             : 
     218             :     DltDaemonContextLogSettings settings;
     219             :     memcpy(settings.apid, app->apid, DLT_ID_SIZE);
     220             :     memcpy(settings.ctid, ctid, DLT_ID_SIZE);
     221             : 
     222             :     DltDaemonContextLogSettings* log_settings = NULL;
     223             :     log_settings =
     224             :         (DltDaemonContextLogSettings *)bsearch(
     225             :             &settings, app->context_log_level_settings,
     226             :             (size_t)app->num_context_log_level_settings,
     227             :             sizeof(DltDaemonContextLogSettings),
     228             :             dlt_daemon_cmp_log_settings);
     229             :     return log_settings;
     230             : }
     231             : 
     232             : #endif
     233             : 
     234             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     235             : int dlt_daemon_compare_trace_load_settings(const void *a, const void *b) {
     236             :     const DltTraceLoadSettings *s1 = (const DltTraceLoadSettings *)a;
     237             :     const DltTraceLoadSettings *s2 = (const DltTraceLoadSettings *)b;
     238             : 
     239             :     int cmp = strncmp(s1->apid, s2->apid, DLT_ID_SIZE);
     240             :     if (cmp != 0) {
     241             :         return cmp;
     242             :     }
     243             : 
     244             :     return strncmp(s1->ctid, s2->ctid, DLT_ID_SIZE);
     245             : }
     246             : 
     247             : DltReturnValue dlt_daemon_find_preconfigured_trace_load_settings(
     248             :     DltDaemon *const daemon, const char *apid, const char *ctid, DltTraceLoadSettings **settings, int *num_settings, int verbose)
     249             : {
     250             :     PRINT_FUNCTION_VERBOSE(verbose);
     251             :     int i;
     252             :     *num_settings = 0;
     253             :     *settings = NULL;
     254             : 
     255             :     if ((daemon == NULL) || (apid == NULL)) {
     256             :         dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
     257             :         return DLT_RETURN_WRONG_PARAMETER;
     258             :     }
     259             : 
     260             :     if (NULL == daemon->preconfigured_trace_load_settings || daemon->preconfigured_trace_load_settings_count == 0) {
     261             :         return DLT_RETURN_OK;
     262             :     }
     263             : 
     264             :     for (i = 0; i < daemon->preconfigured_trace_load_settings_count; ++i) {
     265             :         // check if we can exit already, the trace load settings are sorted
     266             :         // and if the apid does not match anymore, but we already have settings
     267             :         // means we collected all settings
     268             :         if (strncmp(apid, daemon->preconfigured_trace_load_settings[i].apid, DLT_ID_SIZE) != 0) {
     269             :             if ((*num_settings) != 0)
     270             :                 break;
     271             :             continue;
     272             :         }
     273             : 
     274             :         // If a ctid is passed, we only want to return entries where both match
     275             :         if (ctid != NULL && strlen(ctid) > 0) {
     276             :             if (strncmp(ctid, daemon->preconfigured_trace_load_settings[i].ctid, DLT_ID_SIZE) != 0) {
     277             :                 continue;
     278             :             }
     279             :         }
     280             : 
     281             :         // Reallocate memory for the settings array with an additional slot for the new setting
     282             :         DltTraceLoadSettings *temp = realloc(*settings, (*num_settings + 1) * sizeof(DltTraceLoadSettings));
     283             :         if (temp == NULL) {
     284             :             dlt_vlog(LOG_ERR, "Failed to allocate memory for trace load settings\n");
     285             :             free(*settings); // Free any previously allocated memory
     286             :             *settings = NULL;
     287             :             *num_settings = 0;
     288             :             return DLT_RETURN_ERROR;
     289             :         }
     290             :         *settings = temp;
     291             :         // Copy preconfigured trace load settings into the app settings
     292             :         (*settings)[*num_settings] = daemon->preconfigured_trace_load_settings[i];
     293             :         (*num_settings)++;
     294             :     }
     295             : 
     296             :     qsort(*settings, (size_t)*num_settings, sizeof(DltTraceLoadSettings),
     297             :           dlt_daemon_compare_trace_load_settings);
     298             :     return DLT_RETURN_OK;
     299             : }
     300             : #endif
     301             : 
     302           9 : int dlt_daemon_init_runtime_configuration(DltDaemon *daemon, const char *runtime_directory, int verbose)
     303             : {
     304           9 :     PRINT_FUNCTION_VERBOSE(verbose);
     305             :     size_t append_length = 0;
     306             : 
     307           9 :     if (daemon == NULL)
     308             :         return DLT_RETURN_ERROR;
     309             : 
     310             :     /* Default */
     311           9 :     daemon->mode = DLT_USER_MODE_EXTERNAL;
     312             : 
     313           9 :     if (runtime_directory == NULL)
     314             :         return DLT_RETURN_ERROR;
     315             : 
     316             :     /* prepare filenames for configuration */
     317             :     append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
     318             : 
     319           9 :     if (runtime_directory[0]) {
     320           0 :         strncpy(daemon->runtime_application_cfg, runtime_directory, append_length);
     321           0 :         daemon->runtime_application_cfg[append_length] = 0;
     322             :     }
     323             :     else {
     324           9 :         strncpy(daemon->runtime_application_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
     325           9 :         daemon->runtime_application_cfg[append_length] = 0;
     326             :     }
     327             : 
     328           9 :     strcat(daemon->runtime_application_cfg, DLT_RUNTIME_APPLICATION_CFG); /* strcat uncritical here, because max length already checked */
     329             : 
     330             :     append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
     331             : 
     332           9 :     if (runtime_directory[0]) {
     333           0 :         strncpy(daemon->runtime_context_cfg, runtime_directory, append_length);
     334           0 :         daemon->runtime_context_cfg[append_length] = 0;
     335             :     }
     336             :     else {
     337           9 :         strncpy(daemon->runtime_context_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
     338           9 :         daemon->runtime_context_cfg[append_length] = 0;
     339             :     }
     340             : 
     341           9 :     strcat(daemon->runtime_context_cfg, DLT_RUNTIME_CONTEXT_CFG); /* strcat uncritical here, because max length already checked */
     342             : 
     343             :     append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
     344             : 
     345           9 :     if (runtime_directory[0]) {
     346           0 :         strncpy(daemon->runtime_configuration, runtime_directory, append_length);
     347           0 :         daemon->runtime_configuration[append_length] = 0;
     348             :     }
     349             :     else {
     350           9 :         strncpy(daemon->runtime_configuration, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
     351           9 :         daemon->runtime_configuration[append_length] = 0;
     352             :     }
     353             : 
     354           9 :     strcat(daemon->runtime_configuration, DLT_RUNTIME_CONFIGURATION); /* strcat uncritical here, because max length already checked */
     355             : 
     356           9 :     return DLT_RETURN_OK;
     357             : }
     358             : 
     359          17 : int dlt_daemon_init(DltDaemon *daemon,
     360             :                     unsigned long RingbufferMinSize,
     361             :                     unsigned long RingbufferMaxSize,
     362             :                     unsigned long RingbufferStepSize,
     363             :                     const char *runtime_directory,
     364             :                     int InitialContextLogLevel,
     365             :                     int InitialContextTraceStatus,
     366             :                     int ForceLLTS,
     367             :                     int verbose)
     368             : {
     369          17 :     PRINT_FUNCTION_VERBOSE(verbose);
     370             : 
     371          17 :     if ((daemon == NULL) || (runtime_directory == NULL))
     372             :         return -1;
     373             : 
     374          17 :     daemon->user_list = NULL;
     375          17 :     daemon->num_user_lists = 0;
     376             : 
     377          17 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
     378          17 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
     379          17 :     daemon->force_ll_ts = (int8_t) ForceLLTS;
     380             : 
     381          17 :     daemon->overflow_counter = 0;
     382             : 
     383          17 :     daemon->runtime_context_cfg_loaded = 0;
     384             : 
     385          17 :     daemon->connectionState = 0; /* no logger connected */
     386             : 
     387          17 :     daemon->state = DLT_DAEMON_STATE_INIT; /* initial logging state */
     388             : 
     389             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     390             :     daemon->preconfigured_trace_load_settings = NULL;
     391             :     daemon->bytes_sent = 0;
     392             :     daemon->bytes_recv = 0;
     393             : #endif
     394             : 
     395          17 :     daemon->sendserialheader = 0;
     396          17 :     daemon->timingpackets = 0;
     397             : 
     398          17 :     dlt_set_id(daemon->ecuid, "");
     399             : 
     400             :     /* initialize ring buffer for client connection */
     401          17 :     dlt_vlog(LOG_INFO, "Ringbuffer configuration: %lu/%lu/%lu\n",
     402             :              RingbufferMinSize, RingbufferMaxSize, RingbufferStepSize);
     403             : 
     404          17 :     if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer),
     405             :                                 (uint32_t) RingbufferMinSize,
     406             :                                 (uint32_t) RingbufferMaxSize,
     407             :                                 (uint32_t) RingbufferStepSize) < DLT_RETURN_OK)
     408             :         return -1;
     409             : 
     410          17 :     daemon->storage_handle = NULL;
     411             : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
     412             :     daemon->received_message_since_last_watchdog_interval = 0;
     413             : #endif
     414          17 :     return 0;
     415             : }
     416             : 
     417           9 : int dlt_daemon_free(DltDaemon *daemon, int verbose)
     418             : {
     419             :     int i = 0;
     420             :     DltDaemonRegisteredUsers *user_list = NULL;
     421             : 
     422           9 :     PRINT_FUNCTION_VERBOSE(verbose);
     423             : 
     424           9 :     if ((daemon == NULL) || (daemon->user_list == NULL))
     425             :         return -1;
     426             : 
     427             :     /* free all registered user information */
     428          19 :     for (i = 0; i < daemon->num_user_lists; i++) {
     429          10 :         user_list = &daemon->user_list[i];
     430             : 
     431          10 :         if (user_list != NULL) {
     432             :             /* ignore return values */
     433          10 :             dlt_daemon_contexts_clear(daemon, user_list->ecu, verbose);
     434          10 :             dlt_daemon_applications_clear(daemon, user_list->ecu, verbose);
     435             :         }
     436             :     }
     437             : 
     438           9 :     free(daemon->user_list);
     439             : 
     440             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     441             :     if (daemon->app_id_log_level_settings != NULL) {
     442             :       free(daemon->app_id_log_level_settings);
     443             :     }
     444             : #endif
     445             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     446             :     if (daemon->preconfigured_trace_load_settings != NULL) {
     447             :         free(daemon->preconfigured_trace_load_settings);
     448             :         daemon->preconfigured_trace_load_settings = NULL;
     449             :     }
     450             :     pthread_rwlock_destroy(&trace_load_rw_lock);
     451             : #endif
     452             : 
     453           9 :     if (app_recv_buffer)
     454           9 :         free(app_recv_buffer);
     455             : 
     456             :     /* free ringbuffer */
     457           9 :     dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
     458             : 
     459           9 :     return 0;
     460             : }
     461             : 
     462          18 : int dlt_daemon_init_user_information(DltDaemon *daemon,
     463             :                                      DltGateway *gateway,
     464             :                                      int gateway_mode,
     465             :                                      int verbose)
     466             : {
     467             :     int nodes = 1;
     468             :     int i = 1;
     469             : 
     470          18 :     PRINT_FUNCTION_VERBOSE(verbose);
     471             : 
     472          18 :     if ((daemon == NULL) || ((gateway_mode == 1) && (gateway == NULL)))
     473             :         return DLT_RETURN_ERROR;
     474             : 
     475          18 :     if (gateway_mode == 0) {
     476             :         /* initialize application list */
     477          17 :         daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
     478             : 
     479          17 :         if (daemon->user_list == NULL) {
     480           0 :             dlt_log(LOG_ERR, "Allocating memory for user information");
     481           0 :             return DLT_RETURN_ERROR;
     482             :         }
     483             : 
     484          17 :         dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
     485          17 :         daemon->num_user_lists = 1;
     486             :     }
     487             :     else { /* gateway is active */
     488           1 :         nodes += gateway->num_connections;
     489             : 
     490             :         /* initialize application list */
     491           1 :         daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
     492             : 
     493           1 :         if (daemon->user_list == NULL) {
     494           0 :             dlt_log(LOG_ERR, "Allocating memory for user information");
     495           0 :             return DLT_RETURN_ERROR;
     496             :         }
     497             : 
     498           1 :         dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
     499           1 :         daemon->num_user_lists = nodes;
     500             : 
     501           2 :         for (i = 1; i < nodes; i++)
     502           1 :             dlt_set_id(daemon->user_list[i].ecu, gateway->connections[i - 1].ecuid);
     503             :     }
     504             : 
     505             :     return DLT_RETURN_OK;
     506             : }
     507             : 
     508          15 : int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,
     509             :                                           char *ecu,
     510             :                                           int fd,
     511             :                                           int verbose)
     512             : {
     513             :     int i;
     514             :     DltDaemonRegisteredUsers *user_list = NULL;
     515             : 
     516          15 :     PRINT_FUNCTION_VERBOSE(verbose);
     517             : 
     518          15 :     if ((daemon == NULL) || (ecu == NULL))
     519             :         return DLT_RETURN_ERROR;
     520             : 
     521          15 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     522             : 
     523          15 :     if (user_list != NULL) {
     524          26 :         for (i = 0; i < user_list->num_applications; i++)
     525          11 :             if (user_list->applications[i].user_handle == fd)
     526           0 :                 user_list->applications[i].user_handle = DLT_FD_INIT;
     527             : 
     528             :         return DLT_RETURN_OK;
     529             :     }
     530             : 
     531             :     return DLT_RETURN_ERROR;
     532             : }
     533             : 
     534          10 : int dlt_daemon_applications_clear(DltDaemon *daemon, char *ecu, int verbose)
     535             : {
     536             :     int i;
     537             :     DltDaemonRegisteredUsers *user_list = NULL;
     538             : 
     539          10 :     PRINT_FUNCTION_VERBOSE(verbose);
     540             : 
     541          10 :     if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
     542             :         return DLT_RETURN_WRONG_PARAMETER;
     543             : 
     544          10 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     545             : 
     546          10 :     if (user_list == NULL)
     547             :         return DLT_RETURN_ERROR;
     548             : 
     549          11 :     for (i = 0; i < user_list->num_applications; i++)
     550           1 :         if (user_list->applications[i].application_description != NULL) {
     551             : 
     552             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     553             :             if (user_list->applications[i].context_log_level_settings)
     554             :                 free(user_list->applications[i].context_log_level_settings);
     555             : #endif
     556             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     557             :             if (user_list->applications[i].trace_load_settings) {
     558             :                 free(user_list->applications[i].trace_load_settings);
     559             :                 user_list->applications[i].trace_load_settings = NULL;
     560             :                 user_list->applications[i].trace_load_settings_count = 0;
     561             :             }
     562             : #endif
     563           1 :             free(user_list->applications[i].application_description);
     564           1 :             user_list->applications[i].application_description = NULL;
     565             :         }
     566             : 
     567          10 :     if (user_list->applications != NULL)
     568           7 :         free(user_list->applications);
     569             : 
     570          10 :     user_list->applications = NULL;
     571          10 :     user_list->num_applications = 0;
     572             : 
     573          10 :     return 0;
     574             : }
     575             : 
     576          15 : static void dlt_daemon_application_reset_user_handle(DltDaemon *daemon,
     577             :                                                      DltDaemonApplication *application,
     578             :                                                      int verbose)
     579             : {
     580             :     DltDaemonRegisteredUsers *user_list;
     581             :     DltDaemonContext *context;
     582             :     int i;
     583             : 
     584          15 :     if (application->user_handle == DLT_FD_INIT)
     585             :         return;
     586             : 
     587           6 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
     588           6 :     if (user_list != NULL) {
     589           6 :         for (i = 0; i < user_list->num_contexts; i++) {
     590           0 :             context = &user_list->contexts[i];
     591           0 :             if (context->user_handle == application->user_handle)
     592           0 :                 context->user_handle = DLT_FD_INIT;
     593             :         }
     594             :     }
     595             : 
     596           6 :     if (application->owns_user_handle)
     597           6 :         close(application->user_handle);
     598             : 
     599           6 :     application->user_handle = DLT_FD_INIT;
     600           6 :     application->owns_user_handle = false;
     601             : }
     602             : 
     603          10 : DltDaemonApplication *dlt_daemon_application_add(DltDaemon *daemon,
     604             :                                                  char *apid,
     605             :                                                  pid_t pid,
     606             :                                                  char *description,
     607             :                                                  int fd,
     608             :                                                  char *ecu,
     609             :                                                  int verbose)
     610             : {
     611             :     DltDaemonApplication *application;
     612             :     DltDaemonApplication *old;
     613             :     int new_application;
     614             :     int dlt_user_handle;
     615             :     bool owns_user_handle;
     616             :     DltDaemonRegisteredUsers *user_list = NULL;
     617             : #ifdef DLT_DAEMON_USE_FIFO_IPC
     618             :     (void)fd;  /* To avoid compiler warning : unused variable */
     619             :     char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
     620             : #endif
     621             : 
     622          10 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
     623             :         return (DltDaemonApplication *)NULL;
     624             : 
     625          10 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     626             : 
     627          10 :     if (user_list == NULL)
     628             :         return (DltDaemonApplication *)NULL;
     629             : 
     630          10 :     if (user_list->applications == NULL) {
     631          10 :         user_list->applications = (DltDaemonApplication *)
     632          10 :             malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
     633             : 
     634          10 :         if (user_list->applications == NULL)
     635             :             return (DltDaemonApplication *)NULL;
     636             :     }
     637             : 
     638             :     new_application = 0;
     639             : 
     640             :     /* Check if application [apid] is already available */
     641          10 :     application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
     642             : 
     643          10 :     if (application == NULL) {
     644          10 :         user_list->num_applications += 1;
     645             : 
     646          10 :         if (user_list->num_applications != 0) {
     647          10 :             if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
     648             :                 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
     649           0 :                 old = user_list->applications;
     650           0 :                 user_list->applications = (DltDaemonApplication *)
     651           0 :                     malloc(sizeof(DltDaemonApplication) *
     652           0 :                            ((user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1) *
     653             :                            DLT_DAEMON_APPL_ALLOC_SIZE);
     654             : 
     655           0 :                 if (user_list->applications == NULL) {
     656           0 :                     user_list->applications = old;
     657           0 :                     user_list->num_applications -= 1;
     658           0 :                     return (DltDaemonApplication *)NULL;
     659             :                 }
     660             : 
     661           0 :                 memcpy(user_list->applications,
     662             :                        old,
     663           0 :                        sizeof(DltDaemonApplication) * user_list->num_applications);
     664           0 :                 free(old);
     665             :             }
     666             :         }
     667             : 
     668          10 :         application = &(user_list->applications[user_list->num_applications - 1]);
     669             : 
     670          10 :         dlt_set_id(application->apid, apid);
     671          10 :         application->pid = 0;
     672          10 :         application->application_description = NULL;
     673          10 :         application->num_contexts = 0;
     674          10 :         application->user_handle = DLT_FD_INIT;
     675          10 :         application->owns_user_handle = false;
     676             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     677             :         application->trace_load_settings = NULL;
     678             :         application->trace_load_settings_count = 0;
     679             : #endif
     680             : 
     681             :         new_application = 1;
     682             : 
     683             :     }
     684           0 :     else if ((pid != application->pid) && (application->pid != 0))
     685             :     {
     686             : 
     687           0 :         dlt_vlog(LOG_WARNING,
     688             :                  "Duplicate registration of ApplicationID: '%.4s'; registering from PID %d, existing from PID %d\n",
     689             :                  apid,
     690             :                  pid,
     691             :                  application->pid);
     692             :     }
     693             : 
     694             :     /* Store application description and pid of application */
     695          10 :     if (application->application_description) {
     696           0 :         free(application->application_description);
     697           0 :         application->application_description = NULL;
     698             :     }
     699             : 
     700          10 :     if (description != NULL) {
     701          10 :         application->application_description = malloc(strlen(description) + 1);
     702             : 
     703          10 :         if (application->application_description) {
     704          10 :             memcpy(application->application_description, description, strlen(description) + 1);
     705             :         } else {
     706           0 :             dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
     707           0 :             free(application);
     708           0 :             return (DltDaemonApplication *)NULL;
     709             :         }
     710             :     }
     711             : 
     712          10 :     if (application->pid != pid) {
     713           9 :         dlt_daemon_application_reset_user_handle(daemon, application, verbose);
     714           9 :         application->pid = 0;
     715             :     }
     716             : 
     717             :     /* open user pipe only if it is not yet opened */
     718          10 :     if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
     719             :         dlt_user_handle = DLT_FD_INIT;
     720             :         owns_user_handle = false;
     721             : 
     722             : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
     723             :         if (fd >= DLT_FD_MINIMUM) {
     724             :             dlt_user_handle = fd;
     725             :             owns_user_handle = false;
     726             :         }
     727             : #endif
     728             : #ifdef DLT_DAEMON_USE_FIFO_IPC
     729             :         if (dlt_user_handle < DLT_FD_MINIMUM) {
     730             :             snprintf(filename,
     731             :                      DLT_DAEMON_COMMON_TEXTBUFSIZE,
     732             :                      "%s/dltpipes/dlt%d",
     733             :                      dltFifoBaseDir,
     734             :                      pid);
     735             : 
     736             :             dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
     737             : 
     738           9 :             if (dlt_user_handle < 0) {
     739           0 :                 int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
     740           0 :                 dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
     741             :             } else {
     742             :                 owns_user_handle = true;
     743             :             }
     744             :         }
     745             : #endif
     746             :         /* check if file descriptor was already used, and make it invalid if it
     747             :         * is reused. This prevents sending messages to wrong file descriptor */
     748           9 :         dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
     749           9 :         dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
     750             : 
     751           9 :         application->user_handle = dlt_user_handle;
     752           9 :         application->owns_user_handle = owns_user_handle;
     753           9 :         application->pid = pid;
     754             :     }
     755             : 
     756             :     /* Sort */
     757          10 :     if (new_application) {
     758          10 :         qsort(user_list->applications,
     759          10 :               (size_t) user_list->num_applications,
     760             :               sizeof(DltDaemonApplication),
     761             :               dlt_daemon_cmp_apid);
     762             : 
     763             :         /* Find new position of application with apid*/
     764          10 :         application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
     765             :     }
     766             : 
     767             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     768             :     application->num_context_log_level_settings = 0;
     769             :     application->context_log_level_settings = NULL;
     770             : #endif
     771             : #if DLT_TRACE_LOAD_CTRL_ENABLE
     772             :     if (application->trace_load_settings == NULL) {
     773             :         DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
     774             :         int num_settings = 0;
     775             :         DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
     776             :             daemon,
     777             :             application->apid,
     778             :             NULL /*load settings for all contexts*/,
     779             :             &pre_configured_trace_load_settings,
     780             :             &num_settings,
     781             :             verbose);
     782             : 
     783             :         DltTraceLoadSettings *app_level = NULL;
     784             :         if ((find_trace_settings_return_value == DLT_RETURN_OK) &&
     785             :             (pre_configured_trace_load_settings != NULL) &&
     786             :             (num_settings != 0)) {
     787             :             application->trace_load_settings = pre_configured_trace_load_settings;
     788             :             application->trace_load_settings_count = num_settings;
     789             :             app_level = dlt_find_runtime_trace_load_settings(
     790             :                 application->trace_load_settings,
     791             :                 application->trace_load_settings_count, application->apid,
     792             :                 NULL);
     793             :         }
     794             : 
     795             :         // app is not configured, set daemon defaults
     796             :         if (app_level == NULL) {
     797             :             DltTraceLoadSettings *temp = realloc(application->trace_load_settings,
     798             :                                                  (application->trace_load_settings_count + 1) *
     799             :                                                      sizeof(DltTraceLoadSettings));
     800             : 
     801             :             if (temp != NULL) {
     802             :                 application->trace_load_settings = temp;
     803             :                 ++application->trace_load_settings_count;
     804             : 
     805             :                 app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
     806             :                 memset(app_level, 0, sizeof(DltTraceLoadSettings));
     807             :                 app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
     808             :                 app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
     809             :                 memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
     810             :                 memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
     811             :             } else {
     812             :                 dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
     813             :             }
     814             : 
     815             :             // We inserted the application id at the end, to make sure
     816             :             // Lookups are working properly later on, we have to sort the list again.
     817             :             qsort(application->trace_load_settings,
     818             :                   (size_t)application->trace_load_settings_count,
     819             :                   sizeof(DltTraceLoadSettings),
     820             :                   dlt_daemon_compare_trace_load_settings);
     821             :         }
     822             :     }
     823             : 
     824             : #endif
     825             : 
     826             :     return application;
     827             : }
     828             : 
     829           6 : int dlt_daemon_application_del(DltDaemon *daemon,
     830             :                                DltDaemonApplication *application,
     831             :                                char *ecu,
     832             :                                int verbose)
     833             : {
     834             :     int pos;
     835             :     DltDaemonRegisteredUsers *user_list = NULL;
     836             : 
     837           6 :     PRINT_FUNCTION_VERBOSE(verbose);
     838             : 
     839           6 :     if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
     840             :         return -1;
     841             : 
     842           6 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     843             : 
     844           6 :     if (user_list == NULL)
     845             :         return -1;
     846             : 
     847           6 :     if (user_list->num_applications > 0) {
     848           6 :         dlt_daemon_application_reset_user_handle(daemon, application, verbose);
     849             : 
     850             :         /* Free description of application to be deleted */
     851           6 :         if (application->application_description) {
     852           6 :             free(application->application_description);
     853           6 :             application->application_description = NULL;
     854             :         }
     855             : 
     856             : #if DLT_TRACE_LOAD_CTRL_ENABLE
     857             :         if (application->trace_load_settings != NULL) {
     858             :             free(application->trace_load_settings);
     859             :             application->trace_load_settings = NULL;
     860             :             application->trace_load_settings_count = 0;
     861             :         }
     862             : #endif
     863           6 :         pos = (int) (application - (user_list->applications));
     864             : 
     865             :         /* move all applications above pos to pos */
     866           6 :         memmove(&(user_list->applications[pos]),
     867           6 :                 &(user_list->applications[pos + 1]),
     868           6 :                 sizeof(DltDaemonApplication) * ((user_list->num_applications - 1) - pos));
     869             : 
     870             :         /* Clear last application */
     871           6 :         memset(&(user_list->applications[user_list->num_applications - 1]),
     872             :                0,
     873             :                sizeof(DltDaemonApplication));
     874             : 
     875           6 :         user_list->num_applications--;
     876             :     }
     877             : 
     878             :     return 0;
     879             : }
     880             : 
     881         149 : DltDaemonApplication *dlt_daemon_application_find(DltDaemon *daemon,
     882             :                                                   char *apid,
     883             :                                                   char *ecu,
     884             :                                                   int verbose)
     885             : {
     886             :     DltDaemonApplication application;
     887             :     DltDaemonRegisteredUsers *user_list = NULL;
     888             : 
     889         149 :     PRINT_FUNCTION_VERBOSE(verbose);
     890             : 
     891         149 :     if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) ||
     892         149 :         (apid[0] == '\0') || (ecu == NULL))
     893             :         return (DltDaemonApplication *)NULL;
     894             : 
     895         149 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     896             : 
     897         149 :     if ((user_list == NULL) || (user_list->num_applications == 0))
     898             :         return (DltDaemonApplication *)NULL;
     899             : 
     900             :     /* Check, if apid is smaller than smallest apid or greater than greatest apid */
     901         132 :     if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) ||
     902         132 :         (memcmp(apid,
     903         132 :                 user_list->applications[user_list->num_applications - 1].apid,
     904             :                 DLT_ID_SIZE) > 0))
     905             :         return (DltDaemonApplication *)NULL;
     906             : 
     907         132 :     dlt_set_id(application.apid, apid);
     908         132 :     return (DltDaemonApplication *)bsearch(&application,
     909         132 :                                            user_list->applications,
     910         132 :                                            (size_t) user_list->num_applications,
     911             :                                            sizeof(DltDaemonApplication),
     912             :                                            dlt_daemon_cmp_apid);
     913             : }
     914             : 
     915           9 : int dlt_daemon_applications_load(DltDaemon *daemon, const char *filename, int verbose)
     916             : {
     917             :     FILE *fd;
     918             :     ID4 apid;
     919             :     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
     920             :     char *ret;
     921             :     char *pb;
     922             : 
     923           9 :     PRINT_FUNCTION_VERBOSE(verbose);
     924             : 
     925           9 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
     926             :         return -1;
     927             : 
     928           9 :     fd = fopen(filename, "r");
     929             : 
     930           9 :     if (fd == NULL) {
     931           9 :         dlt_vlog(LOG_WARNING,
     932             :                  "%s: cannot open file %s: %s\n",
     933             :                  __func__,
     934             :                  filename,
     935           9 :                  strerror(errno));
     936             : 
     937           9 :         return -1;
     938             :     }
     939             : 
     940           0 :     while (!feof(fd)) {
     941             :         /* Clear buf */
     942             :         memset(buf, 0, sizeof(buf));
     943             : 
     944             :         /* Get line */
     945             :         ret = fgets(buf, sizeof(buf), fd);
     946             : 
     947           0 :         if (NULL == ret) {
     948             :             /* fgets always null pointer if the last byte of the file is a new line
     949             :              * We need to check here if there was an error or was it feof.*/
     950           0 :             if (ferror(fd)) {
     951           0 :                 dlt_vlog(LOG_WARNING,
     952             :                          "%s: fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
     953             :                          __func__,
     954           0 :                          strerror(errno));
     955           0 :                 fclose(fd);
     956           0 :                 return -1;
     957             :             }
     958           0 :             else if (feof(fd))
     959             :             {
     960           0 :                 fclose(fd);
     961           0 :                 return 0;
     962             :             }
     963             :             else {
     964           0 :                 dlt_vlog(LOG_WARNING,
     965             :                          "%s: fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
     966             :                          __func__);
     967           0 :                 fclose(fd);
     968           0 :                 return -1;
     969             :             }
     970             :         }
     971             : 
     972           0 :         if (strcmp(buf, "") != 0) {
     973             :             /* Split line */
     974           0 :             pb = strtok(buf, ":");
     975             : 
     976           0 :             if (pb != NULL) {
     977           0 :                 dlt_set_id(apid, pb);
     978           0 :                 pb = strtok(NULL, ":");
     979             : 
     980           0 :                 if (pb != NULL) {
     981             :                     /* pb contains now the description */
     982             :                     /* pid is unknown at loading time */
     983           0 :                     if (dlt_daemon_application_add(daemon,
     984             :                                                    apid,
     985             :                                                    0,
     986             :                                                    pb,
     987             :                                                    -1,
     988           0 :                                                    daemon->ecuid,
     989             :                                                    verbose) == 0) {
     990           0 :                         dlt_vlog(LOG_WARNING,
     991             :                                  "%s: dlt_daemon_application_add failed for %4s\n",
     992             :                                  __func__,
     993             :                                  apid);
     994           0 :                         fclose(fd);
     995           0 :                         return -1;
     996             :                     }
     997             :                 }
     998             :             }
     999             :         }
    1000             :     }
    1001             : 
    1002           0 :     fclose(fd);
    1003             : 
    1004           0 :     return 0;
    1005             : }
    1006             : 
    1007           0 : int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose)
    1008             : {
    1009             :     FILE *fd;
    1010             :     int i;
    1011             : 
    1012             :     char apid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
    1013             :     DltDaemonRegisteredUsers *user_list = NULL;
    1014             : 
    1015           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1016             : 
    1017           0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1018             :         return -1;
    1019             : 
    1020             :     memset(apid, 0, sizeof(apid));
    1021             : 
    1022           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1023             : 
    1024           0 :     if (user_list == NULL)
    1025             :         return -1;
    1026             : 
    1027           0 :     if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
    1028           0 :         fd = fopen(filename, "w");
    1029             : 
    1030           0 :         if (fd != NULL) {
    1031           0 :             for (i = 0; i < user_list->num_applications; i++) {
    1032           0 :                 dlt_set_id(apid, user_list->applications[i].apid);
    1033             : 
    1034           0 :                 if ((user_list->applications[i].application_description) &&
    1035           0 :                     (user_list->applications[i].application_description[0] != '\0'))
    1036             :                     fprintf(fd,
    1037             :                             "%s:%s:\n",
    1038             :                             apid,
    1039             :                             user_list->applications[i].application_description);
    1040             :                 else
    1041             :                     fprintf(fd, "%s::\n", apid);
    1042             :             }
    1043             : 
    1044           0 :             fclose(fd);
    1045             :         }
    1046             :         else {
    1047           0 :             dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n",
    1048             :                      __func__,
    1049             :                      filename);
    1050             :         }
    1051             :     }
    1052             : 
    1053             :     return 0;
    1054             : }
    1055             : 
    1056          41 : DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon,
    1057             :                                          char *apid,
    1058             :                                          char *ctid,
    1059             :                                          int8_t log_level,
    1060             :                                          int8_t trace_status,
    1061             :                                          int log_level_pos,
    1062             :                                          int user_handle,
    1063             :                                          char *description,
    1064             :                                          char *ecu,
    1065             :                                          int verbose)
    1066             : {
    1067             :     DltDaemonApplication *application;
    1068             :     DltDaemonContext *context;
    1069             :     DltDaemonContext *old;
    1070             :     int new_context = 0;
    1071             :     DltDaemonRegisteredUsers *user_list = NULL;
    1072             : 
    1073          41 :     PRINT_FUNCTION_VERBOSE(verbose);
    1074             : 
    1075          41 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
    1076          41 :         (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
    1077             :         return (DltDaemonContext *)NULL;
    1078             : 
    1079          41 :     if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
    1080             :         return (DltDaemonContext *)NULL;
    1081             : 
    1082          41 :     if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
    1083             :         return (DltDaemonContext *)NULL;
    1084             : 
    1085          41 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1086             : 
    1087          41 :     if (user_list == NULL)
    1088             :         return (DltDaemonContext *)NULL;
    1089             : 
    1090          41 :     if (user_list->contexts == NULL) {
    1091          10 :         user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1092             : 
    1093          10 :         if (user_list->contexts == NULL)
    1094             :             return (DltDaemonContext *)NULL;
    1095             :     }
    1096             : 
    1097             :     /* Check if application [apid] is available */
    1098          41 :     application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
    1099             : 
    1100          41 :     if (application == NULL)
    1101             :         return (DltDaemonContext *)NULL;
    1102             : 
    1103             :     /* Check if context [apid, ctid] is already available */
    1104          41 :     context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
    1105             : 
    1106          41 :     if (context == NULL) {
    1107          41 :         user_list->num_contexts += 1;
    1108             : 
    1109          41 :         if (user_list->num_contexts != 0) {
    1110          41 :             if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
    1111             :                 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
    1112           0 :                 old = user_list->contexts;
    1113           0 :                 user_list->contexts = (DltDaemonContext *)calloc(1, (size_t) sizeof(DltDaemonContext) *
    1114           0 :                                                                  ((user_list->num_contexts /
    1115           0 :                                                                    DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1) *
    1116             :                                                                  DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1117             : 
    1118           0 :                 if (user_list->contexts == NULL) {
    1119           0 :                     user_list->contexts = old;
    1120           0 :                     user_list->num_contexts -= 1;
    1121           0 :                     return (DltDaemonContext *)NULL;
    1122             :                 }
    1123             : 
    1124           0 :                 memcpy(user_list->contexts,
    1125             :                        old,
    1126           0 :                        (size_t) sizeof(DltDaemonContext) * user_list->num_contexts);
    1127           0 :                 free(old);
    1128             :             }
    1129             :         }
    1130             : 
    1131          41 :         context = &(user_list->contexts[user_list->num_contexts - 1]);
    1132             :         memset(context, 0, sizeof(DltDaemonContext));
    1133             : 
    1134          41 :         dlt_set_id(context->apid, apid);
    1135          41 :         dlt_set_id(context->ctid, ctid);
    1136             : 
    1137          41 :         application->num_contexts++;
    1138             :         new_context = 1;
    1139             :     }
    1140             : 
    1141             :     /* Set context description */
    1142          41 :     if (context->context_description) {
    1143           0 :         free(context->context_description);
    1144           0 :         context->context_description = NULL;
    1145             :     }
    1146             : 
    1147          41 :     if (description != NULL) {
    1148          41 :         context->context_description = malloc(strlen(description) + 1);
    1149             : 
    1150          41 :         if (context->context_description) {
    1151          41 :             memcpy(context->context_description, description, strlen(description) + 1);
    1152             :         }
    1153             :     }
    1154             : 
    1155             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1156             :     /* configure initial log level */
    1157             :     DltDaemonContextLogSettings *settings = NULL;
    1158             :     settings = dlt_daemon_find_configured_app_id_ctx_id_settings(
    1159             :             daemon, context->apid, ctid);
    1160             : 
    1161             :     if (settings != NULL) {
    1162             :         /* set log level */
    1163             :         log_level = settings->log_level;
    1164             : 
    1165             :         DltDaemonContextLogSettings *ct_settings = NULL;
    1166             :         ct_settings = dlt_daemon_find_app_log_level_config(application, ctid);
    1167             : 
    1168             :         /* ct_settings != null: context and app id combination already exists */
    1169             :         if (ct_settings == NULL) {
    1170             :           /* copy the configuration into the DltDaemonApplication for faster access later */
    1171             :           DltDaemonContextLogSettings *tmp =
    1172             :               realloc(application->context_log_level_settings,
    1173             :                       (++application->num_context_log_level_settings) *
    1174             :                           sizeof(DltDaemonContextLogSettings));
    1175             :           application->context_log_level_settings = tmp;
    1176             : 
    1177             :           ct_settings =
    1178             :               &application->context_log_level_settings[application->num_context_log_level_settings - 1];
    1179             :           memcpy(ct_settings, settings, sizeof(DltDaemonContextLogSettings));
    1180             :           memcpy(ct_settings->ctid, ctid, DLT_ID_SIZE);
    1181             :       }
    1182             :     }
    1183             : #endif
    1184             : 
    1185          41 :     if ((strncmp(daemon->ecuid, ecu, DLT_ID_SIZE) == 0) && (daemon->force_ll_ts)) {
    1186             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1187             :         if (log_level > daemon->default_log_level && settings == NULL)
    1188             : #else
    1189           0 :         if (log_level > daemon->default_log_level)
    1190             : #endif
    1191             :             log_level = daemon->default_log_level;
    1192             : 
    1193           0 :         if (trace_status > daemon->default_trace_status)
    1194             :             trace_status = daemon->default_trace_status;
    1195             : 
    1196           0 :         dlt_vlog(LOG_NOTICE,
    1197             :             "Adapting ll_ts for context: %.4s:%.4s with %i %i\n",
    1198             :             apid,
    1199             :             ctid,
    1200             :             log_level,
    1201             :             trace_status);
    1202             :     }
    1203             : 
    1204             :     /* Store log level and trace status,
    1205             :      * if this is a new context, or
    1206             :      * if this is an old context and the runtime cfg was not loaded */
    1207          41 :     if ((new_context == 1) ||
    1208           0 :         ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
    1209          41 :         context->log_level = log_level;
    1210          41 :         context->trace_status = trace_status;
    1211             :     }
    1212             : 
    1213          41 :     context->log_level_pos = log_level_pos;
    1214          41 :     context->user_handle = user_handle;
    1215             : 
    1216             :     /* In case a context is loaded from runtime config file,
    1217             :      * the user_handle is 0 and we mark that context as predefined.
    1218             :      */
    1219          41 :     if (context->user_handle == 0)
    1220           0 :         context->predefined = true;
    1221             :     else
    1222          41 :         context->predefined = false;
    1223             : 
    1224             :     /* Sort */
    1225          41 :     if (new_context) {
    1226          41 :         qsort(user_list->contexts,
    1227          41 :               (size_t) user_list->num_contexts,
    1228             :               sizeof(DltDaemonContext),
    1229             :               dlt_daemon_cmp_apid_ctid);
    1230             : 
    1231             :         /* Find new position of context with apid, ctid */
    1232          41 :         context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
    1233             :     }
    1234             : 
    1235             :     return context;
    1236             : }
    1237             : 
    1238             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1239             : static void dlt_daemon_free_context_log_settings(
    1240             :     DltDaemonApplication *application,
    1241             :     DltDaemonContext *context)
    1242             : {
    1243             :     DltDaemonContextLogSettings *ct_settings;
    1244             :     int i;
    1245             :     int skipped = 0;
    1246             : 
    1247             :     ct_settings = dlt_daemon_find_app_log_level_config(application, context->ctid);
    1248             :     if (ct_settings == NULL) {
    1249             :         return;
    1250             :     }
    1251             : 
    1252             :     /* move all data forward */
    1253             :     for (i = 0; i < application->num_context_log_level_settings; ++i) {
    1254             :         /* skip given context to delete it */
    1255             :         if (i + skipped < application->num_context_log_level_settings &&
    1256             :             strncmp(application->context_log_level_settings[i+skipped].ctid, context->ctid, DLT_ID_SIZE) == 0) {
    1257             :             ++skipped;
    1258             :             continue;
    1259             :         }
    1260             : 
    1261             :         memcpy(&application->context_log_level_settings[i-skipped],
    1262             :                 &application->context_log_level_settings[i],
    1263             :                 sizeof(DltDaemonContextLogSettings));
    1264             :     }
    1265             : 
    1266             :     application->num_context_log_level_settings -= skipped;
    1267             : 
    1268             :     /* if size is equal to zero, and ptr is not NULL, then realloc is equivalent to free(ptr) */
    1269             :     application->context_log_level_settings = realloc(application->context_log_level_settings,
    1270             :             sizeof(DltDaemonContextLogSettings) * (application->num_context_log_level_settings));
    1271             : 
    1272             : }
    1273             : #endif
    1274             : 
    1275          37 : int dlt_daemon_context_del(DltDaemon *daemon,
    1276             :                            DltDaemonContext *context,
    1277             :                            char *ecu,
    1278             :                            int verbose)
    1279             : {
    1280             :     int pos;
    1281             :     DltDaemonApplication *application;
    1282             :     DltDaemonRegisteredUsers *user_list = NULL;
    1283             : 
    1284          37 :     PRINT_FUNCTION_VERBOSE(verbose);
    1285             : 
    1286          37 :     if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
    1287             :         return -1;
    1288             : 
    1289          37 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1290             : 
    1291          37 :     if (user_list == NULL)
    1292             :         return -1;
    1293             : 
    1294          37 :     if (user_list->num_contexts > 0) {
    1295          37 :         application = dlt_daemon_application_find(daemon, context->apid, ecu, verbose);
    1296             : 
    1297             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1298             :         dlt_daemon_free_context_log_settings(application, context);
    1299             : #endif
    1300             :         /* Free description of context to be deleted */
    1301          37 :         if (context->context_description) {
    1302          37 :             free(context->context_description);
    1303          37 :             context->context_description = NULL;
    1304             :         }
    1305             : 
    1306          37 :         pos = (int) (context - (user_list->contexts));
    1307             : 
    1308             :         /* move all contexts above pos to pos */
    1309          37 :         memmove(&(user_list->contexts[pos]),
    1310          37 :                 &(user_list->contexts[pos + 1]),
    1311          37 :                 sizeof(DltDaemonContext) * ((user_list->num_contexts - 1) - pos));
    1312             : 
    1313             :         /* Clear last context */
    1314          37 :         memset(&(user_list->contexts[user_list->num_contexts - 1]),
    1315             :                0,
    1316             :                sizeof(DltDaemonContext));
    1317             : 
    1318          37 :         user_list->num_contexts--;
    1319             : 
    1320             :         /* Check if application [apid] is available */
    1321          37 :         if (application != NULL)
    1322          37 :             application->num_contexts--;
    1323             :     }
    1324             : 
    1325             :     return 0;
    1326             : }
    1327             : 
    1328         157 : DltDaemonContext *dlt_daemon_context_find(DltDaemon *daemon,
    1329             :                                           char *apid,
    1330             :                                           char *ctid,
    1331             :                                           char *ecu,
    1332             :                                           int verbose)
    1333             : {
    1334             :     DltDaemonContext context;
    1335             :     DltDaemonRegisteredUsers *user_list = NULL;
    1336             : 
    1337         157 :     PRINT_FUNCTION_VERBOSE(verbose);
    1338             : 
    1339         157 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
    1340         157 :         (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
    1341             :         return (DltDaemonContext *)NULL;
    1342             : 
    1343         157 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1344             : 
    1345         157 :     if ((user_list == NULL) || (user_list->num_contexts == 0))
    1346             :         return (DltDaemonContext *)NULL;
    1347             : 
    1348             :     /* Check, if apid is smaller than smallest apid or greater than greatest apid */
    1349         112 :     if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) ||
    1350         112 :         (memcmp(apid,
    1351         112 :                 user_list->contexts[user_list->num_contexts - 1].apid,
    1352             :                 DLT_ID_SIZE) > 0))
    1353             :         return (DltDaemonContext *)NULL;
    1354             : 
    1355         112 :     dlt_set_id(context.apid, apid);
    1356         112 :     dlt_set_id(context.ctid, ctid);
    1357             : 
    1358         112 :     return (DltDaemonContext *)bsearch(&context,
    1359         112 :                                        user_list->contexts,
    1360         112 :                                        (size_t) user_list->num_contexts,
    1361             :                                        sizeof(DltDaemonContext),
    1362             :                                        dlt_daemon_cmp_apid_ctid);
    1363             : }
    1364             : 
    1365          15 : int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,
    1366             :                                       char *ecu,
    1367             :                                       int fd,
    1368             :                                       int verbose)
    1369             : {
    1370             :     int i;
    1371             :     DltDaemonRegisteredUsers *user_list = NULL;
    1372             : 
    1373          15 :     PRINT_FUNCTION_VERBOSE(verbose);
    1374             : 
    1375          15 :     if ((daemon == NULL) || (ecu == NULL))
    1376             :         return -1;
    1377             : 
    1378          15 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1379             : 
    1380          15 :     if (user_list != NULL) {
    1381          39 :         for (i = 0; i < user_list->num_contexts; i++)
    1382          24 :             if (user_list->contexts[i].user_handle == fd)
    1383           0 :                 user_list->contexts[i].user_handle = DLT_FD_INIT;
    1384             : 
    1385             :         return 0;
    1386             :     }
    1387             : 
    1388             :     return -1;
    1389             : }
    1390             : 
    1391          10 : int dlt_daemon_contexts_clear(DltDaemon *daemon, char *ecu, int verbose)
    1392             : {
    1393             :     int i;
    1394             :     DltDaemonRegisteredUsers *users = NULL;
    1395             : 
    1396          10 :     PRINT_FUNCTION_VERBOSE(verbose);
    1397             : 
    1398          10 :     if ((daemon == NULL) || (ecu == NULL))
    1399             :         return DLT_RETURN_WRONG_PARAMETER;
    1400             : 
    1401          10 :     users = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1402             : 
    1403          10 :     if (users == NULL)
    1404             :         return DLT_RETURN_ERROR;
    1405             : 
    1406          11 :     for (i = 0; i < users->num_contexts; i++)
    1407           1 :         if (users->contexts[i].context_description != NULL) {
    1408           1 :             free(users->contexts[i].context_description);
    1409           1 :             users->contexts[i].context_description = NULL;
    1410             :         }
    1411             : 
    1412          10 :     if (users->contexts) {
    1413           7 :         free(users->contexts);
    1414           7 :         users->contexts = NULL;
    1415             :     }
    1416             : 
    1417          11 :     for (i = 0; i < users->num_applications; i++)
    1418           1 :         users->applications[i].num_contexts = 0;
    1419             : 
    1420          10 :     users->num_contexts = 0;
    1421             : 
    1422          10 :     return 0;
    1423             : }
    1424             : 
    1425           0 : int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose)
    1426             : {
    1427             :     FILE *fd;
    1428             :     ID4 apid, ctid;
    1429             :     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
    1430             :     char *ret;
    1431             :     char *pb;
    1432             :     int ll, ts;
    1433             : 
    1434           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1435             : 
    1436           0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1437             :         return -1;
    1438             : 
    1439           0 :     fd = fopen(filename, "r");
    1440             : 
    1441           0 :     if (fd == NULL) {
    1442           0 :         dlt_vlog(LOG_WARNING,
    1443             :                  "DLT runtime-context load, cannot open file %s: %s\n",
    1444             :                  filename,
    1445           0 :                  strerror(errno));
    1446             : 
    1447           0 :         return -1;
    1448             :     }
    1449             : 
    1450           0 :     while (!feof(fd)) {
    1451             :         /* Clear buf */
    1452             :         memset(buf, 0, sizeof(buf));
    1453             : 
    1454             :         /* Get line */
    1455             :         ret = fgets(buf, sizeof(buf), fd);
    1456             : 
    1457           0 :         if (NULL == ret) {
    1458             :             /* fgets always returns null pointer if the last byte of the file is a new line.
    1459             :              * We need to check here if there was an error or was it feof.*/
    1460           0 :             if (ferror(fd)) {
    1461           0 :                 dlt_vlog(LOG_WARNING,
    1462             :                          "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
    1463             :                          __func__,
    1464           0 :                          strerror(errno));
    1465           0 :                 fclose(fd);
    1466           0 :                 return -1;
    1467             :             }
    1468           0 :             else if (feof(fd))
    1469             :             {
    1470           0 :                 fclose(fd);
    1471           0 :                 return 0;
    1472             :             }
    1473             :             else {
    1474           0 :                 dlt_vlog(LOG_WARNING,
    1475             :                          "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
    1476             :                          __func__);
    1477           0 :                 fclose(fd);
    1478           0 :                 return -1;
    1479             :             }
    1480             :         }
    1481             : 
    1482           0 :         if (strcmp(buf, "") != 0) {
    1483             :             /* Split line */
    1484           0 :             pb = strtok(buf, ":");
    1485             : 
    1486           0 :             if (pb != NULL) {
    1487           0 :                 dlt_set_id(apid, pb);
    1488           0 :                 pb = strtok(NULL, ":");
    1489             : 
    1490           0 :                 if (pb != NULL) {
    1491           0 :                     dlt_set_id(ctid, pb);
    1492           0 :                     pb = strtok(NULL, ":");
    1493             : 
    1494           0 :                     if (pb != NULL) {
    1495           0 :                         sscanf(pb, "%d", &ll);
    1496           0 :                         pb = strtok(NULL, ":");
    1497             : 
    1498           0 :                         if (pb != NULL) {
    1499           0 :                             sscanf(pb, "%d", &ts);
    1500           0 :                             pb = strtok(NULL, ":");
    1501             : 
    1502           0 :                             if (pb != NULL) {
    1503             :                                 /* pb contains now the description */
    1504             : 
    1505             :                                 /* log_level_pos, and user_handle are unknown at loading time */
    1506           0 :                                 if (dlt_daemon_context_add(daemon,
    1507             :                                                            apid,
    1508             :                                                            ctid,
    1509           0 :                                                            (int8_t)ll,
    1510           0 :                                                            (int8_t)ts,
    1511             :                                                            0,
    1512             :                                                            0,
    1513             :                                                            pb,
    1514           0 :                                                            daemon->ecuid,
    1515             :                                                            verbose) == NULL) {
    1516           0 :                                     dlt_vlog(LOG_WARNING,
    1517             :                                              "%s dlt_daemon_context_add failed\n",
    1518             :                                              __func__);
    1519           0 :                                     fclose(fd);
    1520           0 :                                     return -1;
    1521             :                                 }
    1522             :                             }
    1523             :                         }
    1524             :                     }
    1525             :                 }
    1526             :             }
    1527             :         }
    1528             :     }
    1529             : 
    1530           0 :     fclose(fd);
    1531             : 
    1532           0 :     return 0;
    1533             : }
    1534             : 
    1535           0 : int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
    1536             : {
    1537             :     FILE *fd;
    1538             :     int i;
    1539             : 
    1540             :     char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
    1541             :     DltDaemonRegisteredUsers *user_list = NULL;
    1542             : 
    1543           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1544             : 
    1545           0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1546             :         return -1;
    1547             : 
    1548           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1549             : 
    1550           0 :     if (user_list == NULL)
    1551             :         return -1;
    1552             : 
    1553             :     memset(apid, 0, sizeof(apid));
    1554             :     memset(ctid, 0, sizeof(ctid));
    1555             : 
    1556           0 :     if ((user_list->contexts) && (user_list->num_contexts > 0)) {
    1557           0 :         fd = fopen(filename, "w");
    1558             : 
    1559           0 :         if (fd != NULL) {
    1560           0 :             for (i = 0; i < user_list->num_contexts; i++) {
    1561           0 :                 dlt_set_id(apid, user_list->contexts[i].apid);
    1562           0 :                 dlt_set_id(ctid, user_list->contexts[i].ctid);
    1563             : 
    1564           0 :                 if ((user_list->contexts[i].context_description) &&
    1565           0 :                     (user_list->contexts[i].context_description[0] != '\0'))
    1566           0 :                     fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
    1567           0 :                             (int)(user_list->contexts[i].log_level),
    1568           0 :                             (int)(user_list->contexts[i].trace_status),
    1569             :                             user_list->contexts[i].context_description);
    1570             :                 else
    1571           0 :                     fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
    1572           0 :                             (int)(user_list->contexts[i].log_level),
    1573           0 :                             (int)(user_list->contexts[i].trace_status));
    1574             :             }
    1575             : 
    1576           0 :             fclose(fd);
    1577             :         }
    1578             :         else {
    1579           0 :             dlt_vlog(LOG_ERR,
    1580             :                      "%s: Cannot open %s. No context information stored\n",
    1581             :                      __func__,
    1582             :                      filename);
    1583             :         }
    1584             :     }
    1585             : 
    1586             :     return 0;
    1587             : }
    1588             : 
    1589           0 : int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
    1590             : {
    1591             :     FILE *fd;
    1592             : 
    1593           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1594             : 
    1595           0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1596             :         return -1;
    1597             : 
    1598           0 :     fd = fopen(filename, "w");
    1599             : 
    1600           0 :     if (fd != NULL) {
    1601             :         fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
    1602           0 :         fprintf(fd, "LoggingMode = %d\n", daemon->mode);
    1603             : 
    1604           0 :         fclose(fd);
    1605             :     }
    1606             : 
    1607             :     return 0;
    1608             : }
    1609             : 
    1610           9 : int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose)
    1611             : {
    1612           9 :     if ((daemon == NULL) || (filename == NULL))
    1613             :         return -1;
    1614             : 
    1615             :     FILE *pFile;
    1616             :     char line[1024];
    1617             :     char token[1024];
    1618             :     char value[1024];
    1619             :     char *pch;
    1620             : 
    1621           9 :     PRINT_FUNCTION_VERBOSE(verbose);
    1622             : 
    1623           9 :     pFile = fopen (filename, "r");
    1624             : 
    1625           9 :     if (pFile != NULL) {
    1626             :         while (1) {
    1627             :             /* fetch line from configuration file */
    1628          18 :             if (fgets (line, 1024, pFile) != NULL) {
    1629           9 :                 pch = strtok (line, " =\r\n");
    1630           9 :                 token[0] = 0;
    1631           9 :                 value[0] = 0;
    1632             : 
    1633          18 :                 while (pch != NULL) {
    1634           9 :                     if (strcmp(pch, "#") == 0)
    1635             :                         break;
    1636             : 
    1637           9 :                     if (token[0] == 0) {
    1638             :                         strncpy(token, pch, sizeof(token) - 1);
    1639           9 :                         token[sizeof(token) - 1] = 0;
    1640             :                     }
    1641             :                     else {
    1642             :                         strncpy(value, pch, sizeof(value) - 1);
    1643           0 :                         value[sizeof(value) - 1] = 0;
    1644           0 :                         break;
    1645             :                     }
    1646             : 
    1647           9 :                     pch = strtok (NULL, " =\r\n");
    1648             :                 }
    1649             : 
    1650           9 :                 if (token[0] && value[0]) {
    1651             :                     /* parse arguments here */
    1652           0 :                     if (strcmp(token, "LoggingMode") == 0) {
    1653           0 :                         daemon->mode = atoi(value);
    1654           0 :                         dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token,
    1655             :                                  daemon->mode);
    1656             :                     }
    1657             :                     else {
    1658           0 :                         dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token,
    1659             :                                  value);
    1660             :                     }
    1661             :                 }
    1662             :             }
    1663             :             else {
    1664             :                 break;
    1665             :             }
    1666             :         }
    1667             : 
    1668           9 :         fclose (pFile);
    1669             :     }
    1670             :     else {
    1671           0 :         dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
    1672             :     }
    1673             : 
    1674             :     return 0;
    1675             : }
    1676             : 
    1677          41 : int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
    1678             : {
    1679             :     DltUserHeader userheader;
    1680             :     DltUserControlMsgLogLevel usercontext;
    1681             :     DltReturnValue ret;
    1682             :     DltDaemonApplication *app;
    1683             : 
    1684          41 :     PRINT_FUNCTION_VERBOSE(verbose);
    1685             : 
    1686          41 :     if ((daemon == NULL) || (context == NULL)) {
    1687           0 :         dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
    1688           0 :         return -1;
    1689             :     }
    1690             : 
    1691          41 :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
    1692           0 :         dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
    1693           0 :         return -1;
    1694             :     }
    1695             : 
    1696          41 :     if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
    1697          34 :         (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
    1698          32 :             usercontext.log_level = (uint8_t) (context->log_level >
    1699             :                 context->storage_log_level ? context->log_level : context->storage_log_level);
    1700             :     else /* Storage log level is not updated (is DEFAULT) then  no device is yet connected so ignore */
    1701           9 :         usercontext.log_level =
    1702           9 :             (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
    1703             : 
    1704          41 :     usercontext.trace_status =
    1705          41 :         (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
    1706             : 
    1707          41 :     usercontext.log_level_pos = context->log_level_pos;
    1708             : 
    1709          41 :     dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n",
    1710          41 :              context->apid,
    1711          41 :              context->ctid,
    1712          41 :              context->log_level,
    1713          41 :              usercontext.log_level,
    1714             :              context->trace_status,
    1715             :              usercontext.trace_status);
    1716             : 
    1717             :     /* log to FIFO */
    1718          41 :     errno = 0;
    1719          41 :     ret = dlt_user_log_out2_with_timeout(context->user_handle,
    1720             :                             &(userheader), sizeof(DltUserHeader),
    1721             :                             &(usercontext), sizeof(DltUserControlMsgLogLevel));
    1722             : 
    1723          41 :     if (ret < DLT_RETURN_OK) {
    1724           0 :         dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
    1725             :                  __func__,
    1726           0 :                  errno != 0 ? strerror(errno) : "Unknown error");
    1727             : 
    1728           0 :         if (errno == EPIPE) {
    1729           0 :             app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
    1730           0 :             if (app != NULL)
    1731           0 :                 dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    1732             :         }
    1733             :     }
    1734             : 
    1735          41 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    1736             : }
    1737             : 
    1738           9 : int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
    1739             : {
    1740             :     DltUserHeader userheader;
    1741             :     DltUserControlMsgLogState logstate;
    1742             :     DltReturnValue ret;
    1743             : 
    1744           9 :     PRINT_FUNCTION_VERBOSE(verbose);
    1745             : 
    1746           9 :     if ((daemon == NULL) || (app == NULL))
    1747             :         return -1;
    1748             : 
    1749           9 :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
    1750             :         return -1;
    1751             : 
    1752           9 :     logstate.log_state = daemon->connectionState;
    1753             : 
    1754             :     /* log to FIFO */
    1755           9 :     ret = dlt_user_log_out2_with_timeout(app->user_handle,
    1756             :                             &(userheader), sizeof(DltUserHeader),
    1757             :                             &(logstate), sizeof(DltUserControlMsgLogState));
    1758             : 
    1759           9 :     if (ret < DLT_RETURN_OK) {
    1760           0 :         if (errno == EPIPE)
    1761           0 :             dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    1762             :     }
    1763             : 
    1764           9 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    1765             : }
    1766             : 
    1767           0 : void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,
    1768             :                                                  const char *filename,
    1769             :                                                  const char *filename1,
    1770             :                                                  int InitialContextLogLevel,
    1771             :                                                  int InitialContextTraceStatus,
    1772             :                                                  int InitialEnforceLlTsStatus,
    1773             :                                                  int verbose)
    1774             : {
    1775             :     FILE *fd;
    1776             : 
    1777           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1778             : 
    1779           0 :     if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
    1780           0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    1781           0 :         return;
    1782             :     }
    1783             : 
    1784           0 :     if ((filename[0] == '\0') || (filename1[0] == '\0')) {
    1785           0 :         dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
    1786           0 :         return;
    1787             :     }
    1788             : 
    1789             :     /* Check for runtime cfg file and delete it, if available */
    1790           0 :     fd = fopen(filename, "r");
    1791             : 
    1792           0 :     if (fd != NULL) {
    1793             :         /* Close and delete file */
    1794           0 :         fclose(fd);
    1795           0 :         if (unlink(filename) != 0) {
    1796           0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    1797           0 :                     __func__, strerror(errno));
    1798             :         }
    1799             :     }
    1800             : 
    1801           0 :     fd = fopen(filename1, "r");
    1802             : 
    1803           0 :     if (fd != NULL) {
    1804             :         /* Close and delete file */
    1805           0 :         fclose(fd);
    1806           0 :         if (unlink(filename1) != 0) {
    1807           0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    1808           0 :                     __func__, strerror(errno));
    1809             :         }
    1810             :     }
    1811             : 
    1812           0 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
    1813           0 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
    1814           0 :     daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
    1815             : 
    1816             :     /* Reset all other things (log level, trace status, etc.
    1817             :      *                         to default values             */
    1818             : 
    1819             :     /* Inform user libraries about changed default log level/trace status */
    1820           0 :     dlt_daemon_user_send_default_update(daemon, verbose);
    1821             : }
    1822             : 
    1823           0 : void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
    1824             : {
    1825             :     int32_t count;
    1826             :     DltDaemonContext *context;
    1827             :     DltDaemonRegisteredUsers *user_list = NULL;
    1828             : 
    1829           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1830             : 
    1831           0 :     if (daemon == NULL) {
    1832           0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    1833           0 :         return;
    1834             :     }
    1835             : 
    1836           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1837             : 
    1838           0 :     if (user_list == NULL)
    1839             :         return;
    1840             : 
    1841           0 :     for (count = 0; count < user_list->num_contexts; count++) {
    1842           0 :         context = &(user_list->contexts[count]);
    1843             : 
    1844           0 :         if (context != NULL) {
    1845           0 :             if ((context->log_level == DLT_LOG_DEFAULT) ||
    1846           0 :                 (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
    1847           0 :                 if (context->user_handle >= DLT_FD_MINIMUM)
    1848           0 :                     if (dlt_daemon_user_send_log_level(daemon,
    1849             :                                                        context,
    1850             :                                                        verbose) == -1)
    1851           0 :                         dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
    1852             :             }
    1853             :         }
    1854             :     }
    1855             : }
    1856             : 
    1857           0 : void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon,
    1858             :                                                int enforce_context_ll_and_ts,
    1859             :                                                int8_t context_log_level,
    1860             :                                                int8_t log_level,
    1861             :                                                int verbose)
    1862             : {
    1863             :     int32_t count = 0;
    1864             :     DltDaemonContext *context = NULL;
    1865             :     DltDaemonRegisteredUsers *user_list = NULL;
    1866             : 
    1867           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1868             : 
    1869           0 :     if (daemon == NULL)
    1870             :         return;
    1871             : 
    1872           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1873             : 
    1874           0 :     if (user_list == NULL)
    1875             :         return;
    1876             : 
    1877           0 :     for (count = 0; count < user_list->num_contexts; count++) {
    1878           0 :         context = &(user_list->contexts[count]);
    1879             : 
    1880           0 :         if (context) {
    1881           0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    1882           0 :                 context->log_level = log_level;
    1883             : 
    1884           0 :                 if (enforce_context_ll_and_ts) {
    1885             : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1886             :                     DltDaemonContextLogSettings *settings =
    1887             :                         dlt_daemon_find_configured_app_id_ctx_id_settings(
    1888             :                             daemon, context->apid, context->ctid);
    1889             :                     if (settings != NULL) {
    1890             :                         if (log_level > settings->log_level) {
    1891             :                           context->log_level = settings->log_level;
    1892             :                         }
    1893             :                     } else
    1894             : #endif
    1895           0 :                     if (log_level > context_log_level) {
    1896           0 :                         context->log_level = (int8_t)context_log_level;
    1897             :                     }
    1898             :                 }
    1899             : 
    1900           0 :                 if (dlt_daemon_user_send_log_level(daemon,
    1901             :                                                    context,
    1902             :                                                    verbose) == -1)
    1903           0 :                     dlt_vlog(LOG_WARNING,
    1904             :                              "Cannot send log level %.4s:%.4s -> %i\n",
    1905           0 :                              context->apid,
    1906           0 :                              context->ctid,
    1907           0 :                              context->log_level);
    1908             :             }
    1909             :         }
    1910             :     }
    1911             : }
    1912             : 
    1913           0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose)
    1914             : {
    1915             :     int32_t count = 0;
    1916             :     DltDaemonContext *context = NULL;
    1917             :     DltDaemonRegisteredUsers *user_list = NULL;
    1918             : 
    1919           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1920             : 
    1921           0 :     if (daemon == NULL)
    1922             :         return;
    1923             : 
    1924           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1925             : 
    1926           0 :     if (user_list == NULL)
    1927             :         return;
    1928             : 
    1929           0 :     dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
    1930             : 
    1931           0 :     for (count = 0; count < user_list->num_contexts; count++) {
    1932           0 :         context = &(user_list->contexts[count]);
    1933             : 
    1934           0 :         if (context) {
    1935           0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    1936           0 :                 context->trace_status = trace_status;
    1937             : 
    1938           0 :                 if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
    1939           0 :                     dlt_vlog(LOG_WARNING,
    1940             :                              "Cannot send trace status %.4s:%.4s -> %i\n",
    1941           0 :                              context->apid,
    1942           0 :                              context->ctid,
    1943           0 :                              context->trace_status);
    1944             :             }
    1945             :         }
    1946             :     }
    1947             : }
    1948             : 
    1949           5 : void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
    1950             : {
    1951             :     int32_t count;
    1952             :     DltDaemonApplication *app;
    1953             :     DltDaemonRegisteredUsers *user_list = NULL;
    1954             : 
    1955           5 :     PRINT_FUNCTION_VERBOSE(verbose);
    1956             : 
    1957           5 :     if (daemon == NULL) {
    1958           0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    1959           0 :         return;
    1960             :     }
    1961             : 
    1962           5 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1963             : 
    1964           5 :     if (user_list == NULL)
    1965             :         return;
    1966             : 
    1967           7 :     for (count = 0; count < user_list->num_applications; count++) {
    1968           2 :         app = &(user_list->applications[count]);
    1969             : 
    1970           2 :         if (app != NULL) {
    1971           2 :             if (app->user_handle >= DLT_FD_MINIMUM)
    1972           2 :                 if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
    1973           0 :                     dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d\n", app->apid, app->pid);
    1974             :         }
    1975             :     }
    1976             : }
    1977             : 
    1978          16 : void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
    1979             : {
    1980          16 :     switch (newState) {
    1981           0 :     case DLT_DAEMON_STATE_INIT:
    1982           0 :         dlt_log(LOG_INFO, "Switched to init state.\n");
    1983           0 :         daemon->state = DLT_DAEMON_STATE_INIT;
    1984           0 :         break;
    1985          12 :     case DLT_DAEMON_STATE_BUFFER:
    1986          12 :         dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
    1987          12 :         daemon->state = DLT_DAEMON_STATE_BUFFER;
    1988          12 :         break;
    1989           0 :     case DLT_DAEMON_STATE_BUFFER_FULL:
    1990           0 :         dlt_log(LOG_INFO, "Switched to buffer full state.\n");
    1991           0 :         daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
    1992           0 :         break;
    1993           2 :     case DLT_DAEMON_STATE_SEND_BUFFER:
    1994           2 :         dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
    1995           2 :         daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
    1996           2 :         break;
    1997           2 :     case DLT_DAEMON_STATE_SEND_DIRECT:
    1998           2 :         dlt_log(LOG_INFO, "Switched to send direct state.\n");
    1999           2 :         daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
    2000           2 :         break;
    2001             :     }
    2002          16 : }
    2003             : 
    2004             : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
    2005             : void dlt_daemon_trigger_systemd_watchdog_if_necessary(unsigned int* last_trigger_time, unsigned int watchdog_trigger_interval) {
    2006             :     unsigned int uptime = dlt_uptime();
    2007             :     if ((uptime - *last_trigger_time) / 10000 >= watchdog_trigger_interval) {
    2008             :         if (sd_notify(0, "WATCHDOG=1") < 0)
    2009             :             dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
    2010             :         *last_trigger_time = uptime;
    2011             :     }
    2012             : }
    2013             : #endif
    2014             : 
    2015             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    2016             : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
    2017             : {
    2018             :     DltUserHeader userheader;
    2019             :     DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
    2020             :     uint32_t trace_load_settings_count;
    2021             :     DltReturnValue ret;
    2022             : 
    2023             : 
    2024             :     PRINT_FUNCTION_VERBOSE(verbose);
    2025             : 
    2026             :     if ((daemon == NULL) || (app == NULL)) return -1;
    2027             : 
    2028             :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
    2029             : 
    2030             :     DltTraceLoadSettings* app_settings = app->trace_load_settings;
    2031             : 
    2032             :     if (app_settings != NULL) {
    2033             :         trace_load_settings_count = app->trace_load_settings_count;
    2034             :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    2035             :         for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
    2036             :             // App id is not transmitted as the user library only
    2037             :             // has one application ID
    2038             :             memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
    2039             :             trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
    2040             :             trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
    2041             : 
    2042             :             if (app_settings[i].ctid[0] == '\0') {
    2043             :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
    2044             :                          app->apid,
    2045             :                          app_settings[i].soft_limit,
    2046             :                          app_settings[i].hard_limit);
    2047             :             } else {
    2048             :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
    2049             :                          app->apid,
    2050             :                          app_settings[i].ctid,
    2051             :                          app_settings[i].soft_limit,
    2052             :                          app_settings[i].hard_limit);
    2053             :             }
    2054             : 
    2055             :         }
    2056             :     }
    2057             :     else {
    2058             :         dlt_vlog(LOG_INFO,
    2059             :                  "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
    2060             : 
    2061             :         trace_load_settings_count = 1;
    2062             :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
    2063             : 
    2064             :         memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
    2065             :         trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
    2066             :         trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
    2067             :     }
    2068             : 
    2069             :     /* log to FIFO */
    2070             :     ret = dlt_user_log_out3_with_timeout(app->user_handle,
    2071             :                                          &(userheader), sizeof(DltUserHeader),
    2072             :                                          &(trace_load_settings_count), sizeof(uint32_t),
    2073             :                                          trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    2074             : 
    2075             :     if (ret < DLT_RETURN_OK && errno == EPIPE) {
    2076             :         dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2077             :     }
    2078             : 
    2079             :     free(trace_load_settings_user_msg);
    2080             : 
    2081             :     return ret;
    2082             : }
    2083             : #endif

Generated by: LCOV version 1.14