LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_common.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 56.3 % 623 351
Test Date: 2025-03-25 20:53:42 Functions: 71.9 % 32 23

            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              : bool dlt_daemon_trigger_systemd_watchdog_if_necessary(DltDaemon *daemon) {
    2006              :     if (daemon->watchdog_trigger_interval == 0) {
    2007              :         return false;
    2008              :     }
    2009              : 
    2010              :     const unsigned int uptime_seconds = dlt_uptime() / 10000;
    2011              :     const unsigned int seconds_since_last_trigger = uptime_seconds - daemon->watchdog_last_trigger_time;
    2012              :     if (seconds_since_last_trigger < daemon->watchdog_trigger_interval) {
    2013              :         return false;
    2014              :     }
    2015              :     if (sd_notify(0, "WATCHDOG=1") < 0) {
    2016              :         dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
    2017              :         return false;
    2018              :     }
    2019              :     else
    2020              :         daemon->watchdog_last_trigger_time = uptime_seconds;
    2021              : 
    2022              :     return true;
    2023              : }
    2024              : 
    2025              : #endif
    2026              : 
    2027              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    2028              : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
    2029              : {
    2030              :     DltUserHeader userheader;
    2031              :     DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
    2032              :     uint32_t trace_load_settings_count;
    2033              :     DltReturnValue ret;
    2034              : 
    2035              : 
    2036              :     PRINT_FUNCTION_VERBOSE(verbose);
    2037              : 
    2038              :     if ((daemon == NULL) || (app == NULL)) return -1;
    2039              : 
    2040              :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
    2041              : 
    2042              :     DltTraceLoadSettings* app_settings = app->trace_load_settings;
    2043              : 
    2044              :     if (app_settings != NULL) {
    2045              :         trace_load_settings_count = app->trace_load_settings_count;
    2046              :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    2047              :         for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
    2048              :             // App id is not transmitted as the user library only
    2049              :             // has one application ID
    2050              :             memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
    2051              :             trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
    2052              :             trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
    2053              : 
    2054              :             if (app_settings[i].ctid[0] == '\0') {
    2055              :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
    2056              :                          app->apid,
    2057              :                          app_settings[i].soft_limit,
    2058              :                          app_settings[i].hard_limit);
    2059              :             } else {
    2060              :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
    2061              :                          app->apid,
    2062              :                          app_settings[i].ctid,
    2063              :                          app_settings[i].soft_limit,
    2064              :                          app_settings[i].hard_limit);
    2065              :             }
    2066              : 
    2067              :         }
    2068              :     }
    2069              :     else {
    2070              :         dlt_vlog(LOG_INFO,
    2071              :                  "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
    2072              : 
    2073              :         trace_load_settings_count = 1;
    2074              :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
    2075              : 
    2076              :         memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
    2077              :         trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
    2078              :         trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
    2079              :     }
    2080              : 
    2081              :     /* log to FIFO */
    2082              :     ret = dlt_user_log_out3_with_timeout(app->user_handle,
    2083              :                                          &(userheader), sizeof(DltUserHeader),
    2084              :                                          &(trace_load_settings_count), sizeof(uint32_t),
    2085              :                                          trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    2086              : 
    2087              :     if (ret < DLT_RETURN_OK && errno == EPIPE) {
    2088              :         dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2089              :     }
    2090              : 
    2091              :     free(trace_load_settings_user_msg);
    2092              : 
    2093              :     return ret;
    2094              : }
    2095              : #endif
        

Generated by: LCOV version 2.0-1