LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_common.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 28.1 % 1073 302
Test Date: 2026-03-27 13:51:01 Functions: 38.9 % 54 21

            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           31 :     if ((m1 == NULL) || (m2 == NULL))
      99              :         return -1;
     100              : 
     101              :     const DltDaemonApplication *mi1 = (const DltDaemonApplication *)m1;
     102              :     const DltDaemonApplication *mi2 = (const DltDaemonApplication *)m2;
     103              : 
     104           31 :     return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
     105              : }
     106              : 
     107            0 : static int dlt_daemon_cmp_apid_v2(const void *m1, const void *m2)
     108              : {
     109            0 :     if ((m1 == NULL) || (m2 == NULL))
     110              :         return -1;
     111              : 
     112              :     const DltDaemonApplication *mi1 = (const DltDaemonApplication *)m1;
     113              :     const DltDaemonApplication *mi2 = (const DltDaemonApplication *)m2;
     114              : 
     115            0 :     if (mi1->apid2len < mi2->apid2len){
     116              :         return -1;
     117            0 :     }else if (mi1->apid2len > mi2->apid2len){
     118              :         return 1;
     119              :     }
     120              : 
     121            0 :     return memcmp(mi1->apid2, mi2->apid2, mi1->apid2len);
     122              : }
     123              : 
     124          164 : static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
     125              : {
     126          164 :     if ((m1 == NULL) || (m2 == NULL))
     127              :         return -1;
     128              : 
     129              :     int ret, cmp;
     130              :     const DltDaemonContext *mi1 = (const DltDaemonContext *)m1;
     131              :     const DltDaemonContext *mi2 = (const DltDaemonContext *)m2;
     132              : 
     133          164 :     cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
     134              : 
     135          164 :     if (cmp < 0)
     136              :         ret = -1;
     137          164 :     else if (cmp == 0)
     138          164 :         ret = memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
     139              :     else
     140              :         ret = 1;
     141              : 
     142              :     return ret;
     143              : }
     144              : 
     145            0 : static int dlt_daemon_cmp_apid_ctid_v2(const void *m1, const void *m2)
     146              : {
     147            0 :     if ((m1 == NULL) || (m2 == NULL))
     148              :         return -1;
     149              : 
     150              :     int cmp;
     151              :     const DltDaemonContext *mi1 = (const DltDaemonContext *)m1;
     152              :     const DltDaemonContext *mi2 = (const DltDaemonContext *)m2;
     153              : 
     154            0 :     if (mi1->apid2len < mi2->apid2len){
     155              :         return -1;
     156            0 :     }else if (mi1->apid2len > mi2->apid2len){
     157              :         return 1;
     158              :     }
     159              : 
     160            0 :     cmp = memcmp(mi1->apid2, mi2->apid2, mi1->apid2len);
     161              : 
     162            0 :     if (cmp < 0){
     163              :         return -1;
     164            0 :     }else if (cmp > 0){
     165              :         return 1;
     166              :     }else {
     167            0 :         if (mi1->ctid2len < mi2->ctid2len){
     168              :             return -1;
     169            0 :         }else if (mi1->ctid2len > mi2->ctid2len){
     170              :             return 1;
     171              :         }else{
     172            0 :             return memcmp(mi1->ctid2, mi2->ctid2, mi1->ctid2len);
     173              :         }
     174              :     }
     175              : }
     176              : 
     177          118 : DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon,
     178              :                                                      char *ecu,
     179              :                                                      int verbose)
     180              : {
     181          118 :     PRINT_FUNCTION_VERBOSE(verbose);
     182              : 
     183              :     int i = 0;
     184              : 
     185          118 :     if ((daemon == NULL) || (ecu == NULL)) {
     186            0 :         dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
     187            0 :         return (DltDaemonRegisteredUsers *)NULL;
     188              :     }
     189              : 
     190          118 :     for (i = 0; i < daemon->num_user_lists; i++)
     191          106 :         if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0)
     192          106 :             return &daemon->user_list[i];
     193              : 
     194           12 :     dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %4s\n", ecu);
     195           12 :     return (DltDaemonRegisteredUsers *)NULL;
     196              : }
     197              : 
     198            0 : DltDaemonRegisteredUsers *dlt_daemon_find_users_list_v2(DltDaemon *daemon,
     199              :                                                         uint8_t eculen,
     200              :                                                         char *ecu,
     201              :                                                         int verbose)
     202              : {
     203            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     204              : 
     205              :     int i = 0;
     206              : 
     207            0 :     if ((daemon == NULL) || (ecu == NULL) || (eculen == 0)) {
     208            0 :         dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
     209            0 :         return (DltDaemonRegisteredUsers *)NULL;
     210              :     }
     211              : 
     212            0 :     for (i = 0; i < daemon->num_user_lists; i++)
     213            0 :         if (strncmp(ecu, daemon->user_list[i].ecuid2, daemon->user_list[i].ecuid2len) == 0)
     214            0 :             return &daemon->user_list[i];
     215              : 
     216            0 :     dlt_vlog(LOG_ERR, "Cannot find user list for ECU: %s\n", ecu);
     217            0 :     return (DltDaemonRegisteredUsers *)NULL;
     218              : }
     219              : 
     220              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     221              : 
     222              : static int dlt_daemon_cmp_log_settings(const void *lhs, const void *rhs) {
     223              :     if ((lhs == NULL) || (rhs == NULL))
     224              :         return -1;
     225              : 
     226              :     DltDaemonContextLogSettings *settings1 = (DltDaemonContextLogSettings *)lhs;
     227              :     DltDaemonContextLogSettings *settings2 = (DltDaemonContextLogSettings *)rhs;
     228              : 
     229              :     int cmp = memcmp(settings1->apid, settings2->apid, DLT_ID_SIZE);
     230              : 
     231              :     if (cmp < 0)
     232              :         return -1;
     233              :     else if (cmp == 0)
     234              :         return memcmp(settings1->ctid, settings2->ctid, DLT_ID_SIZE);
     235              :     else
     236              :         return 1;
     237              : }
     238              : 
     239              : /**
     240              :  * Find configuration for app/ctx id specific log settings configuration
     241              :  * @param daemon pointer to dlt daemon struct
     242              :  * @param apid application id to use
     243              :  * @param ctid context id to use, can be NULL
     244              :  * @return pointer to log settings if found, otherwise NULL
     245              :  */
     246              : DltDaemonContextLogSettings *dlt_daemon_find_configured_app_id_ctx_id_settings(
     247              :     const DltDaemon *daemon, const char *apid, const char *ctid) {
     248              :     DltDaemonContextLogSettings *app_id_settings = NULL;
     249              :     for (int i = 0; i < daemon->num_app_id_log_level_settings; ++i) {
     250              :         DltDaemonContextLogSettings *settings = &daemon->app_id_log_level_settings[i];
     251              : 
     252              :         if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
     253              :             if (app_id_settings != NULL)
     254              :                 return app_id_settings;
     255              :             continue;
     256              :         }
     257              : 
     258              :         if (strlen(settings->ctid) == 0) {
     259              :             app_id_settings = settings;
     260              :         }
     261              : 
     262              :         if (ctid == NULL || strlen(ctid) == 0) {
     263              :             if (app_id_settings != NULL) {
     264              :                 return app_id_settings;
     265              :             }
     266              :         } else {
     267              :             if (strncmp(ctid, settings->ctid, DLT_ID_SIZE) == 0) {
     268              :                 return settings;
     269              :             }
     270              :         }
     271              :     }
     272              : 
     273              :     return app_id_settings;
     274              : }
     275              : 
     276              : /**
     277              :  * Find configuration for app/ctx id specific log settings configuration
     278              :  * for DLT V2
     279              :  * @param daemon pointer to dlt daemon struct
     280              :  * @param apid application id to use
     281              :  * @param ctid context id to use, can be NULL
     282              :  * @return pointer to log settings if found, otherwise NULL
     283              :  */
     284              : DltDaemonContextLogSettingsV2 *dlt_daemon_find_configured_app_id_ctx_id_settings_v2(
     285              :     const DltDaemon *daemon, const char *apid, const char *ctid) {
     286              :     DltDaemonContextLogSettingsV2 *app_id_settings = NULL;
     287              :     for (int i = 0; i < daemon->num_app_id_log_level_settings; ++i) {
     288              :         DltDaemonContextLogSettingsV2 *settings = &daemon->app_id_log_level_settings[i];
     289              :         //TBD: Check settings->apid, settings->apid2len in runtime
     290              :         if (strncmp(apid, settings->apid, settings->apidlen) != 0) {
     291              :             if (app_id_settings != NULL)
     292              :                 return app_id_settings;
     293              :             continue;
     294              :         }
     295              : 
     296              :         if (strlen(settings->ctid) == 0) {
     297              :             app_id_settings = settings;
     298              :         }
     299              : 
     300              :         if (ctid == NULL || strlen(ctid) == 0) {
     301              :             if (app_id_settings != NULL) {
     302              :                 return app_id_settings;
     303              :             }
     304              :         } else {
     305              :             if (strncmp(ctid, settings->ctid, settings->ctidlen) == 0) {
     306              :                 return settings;
     307              :             }
     308              :         }
     309              :     }
     310              : 
     311              :     return app_id_settings;
     312              : }
     313              : 
     314              : /**
     315              :  * Find configured log levels in a given DltDaemonApplication for the passed context id.
     316              :  * @param app The application settings which contain the previously loaded ap id settings
     317              :  * @param ctid The context id to find.
     318              :  * @return Pointer to DltDaemonApplicationLogSettings containing the log level
     319              :  *         for the requested application or NULL if none found.
     320              :  */
     321              : DltDaemonContextLogSettings *dlt_daemon_find_app_log_level_config(
     322              :     const DltDaemonApplication *const app, const char *const ctid) {
     323              : 
     324              :     if (NULL == ctid)
     325              :         return NULL;
     326              : 
     327              :     DltDaemonContextLogSettings settings;
     328              :     memcpy(settings.apid, app->apid, DLT_ID_SIZE);
     329              :     memcpy(settings.ctid, ctid, DLT_ID_SIZE);
     330              : 
     331              :     DltDaemonContextLogSettings* log_settings = NULL;
     332              :     log_settings =
     333              :         (DltDaemonContextLogSettings *)bsearch(
     334              :             &settings, app->context_log_level_settings,
     335              :             (size_t)app->num_context_log_level_settings,
     336              :             sizeof(DltDaemonContextLogSettings),
     337              :             dlt_daemon_cmp_log_settings);
     338              :     return log_settings;
     339              : }
     340              : 
     341              : /* TODO: Add function dlt_daemon_find_app_log_level_config_v2 for DLTv2 */
     342              : 
     343              : #endif
     344              : 
     345              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     346              : int dlt_daemon_compare_trace_load_settings(const void *a, const void *b) {
     347              :     const DltTraceLoadSettings *s1 = (const DltTraceLoadSettings *)a;
     348              :     const DltTraceLoadSettings *s2 = (const DltTraceLoadSettings *)b;
     349              : 
     350              :     int cmp = strncmp(s1->apid, s2->apid, DLT_ID_SIZE);
     351              :     if (cmp != 0) {
     352              :         return cmp;
     353              :     }
     354              : 
     355              :     return strncmp(s1->ctid, s2->ctid, DLT_ID_SIZE);
     356              : }
     357              : 
     358              : DltReturnValue dlt_daemon_find_preconfigured_trace_load_settings(
     359              :     DltDaemon *const daemon, const char *apid, const char *ctid, DltTraceLoadSettings **settings, int *num_settings, int verbose)
     360              : {
     361              :     PRINT_FUNCTION_VERBOSE(verbose);
     362              :     int i;
     363              :     *num_settings = 0;
     364              :     *settings = NULL;
     365              : 
     366              :     if ((daemon == NULL) || (apid == NULL)) {
     367              :         dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
     368              :         return DLT_RETURN_WRONG_PARAMETER;
     369              :     }
     370              : 
     371              :     if (NULL == daemon->preconfigured_trace_load_settings || daemon->preconfigured_trace_load_settings_count == 0) {
     372              :         return DLT_RETURN_OK;
     373              :     }
     374              : 
     375              :     for (i = 0; i < daemon->preconfigured_trace_load_settings_count; ++i) {
     376              :         // check if we can exit already, the trace load settings are sorted
     377              :         // and if the apid does not match anymore, but we already have settings
     378              :         // means we collected all settings
     379              :         if (strncmp(apid, daemon->preconfigured_trace_load_settings[i].apid, DLT_ID_SIZE) != 0) {
     380              :             if ((*num_settings) != 0)
     381              :                 break;
     382              :             continue;
     383              :         }
     384              : 
     385              :         // If a ctid is passed, we only want to return entries where both match
     386              :         if (ctid != NULL && strlen(ctid) > 0) {
     387              :             if (strncmp(ctid, daemon->preconfigured_trace_load_settings[i].ctid, DLT_ID_SIZE) != 0) {
     388              :                 continue;
     389              :             }
     390              :         }
     391              : 
     392              :         // Reallocate memory for the settings array with an additional slot for the new setting
     393              :         DltTraceLoadSettings *temp = realloc(*settings, (*num_settings + 1) * sizeof(DltTraceLoadSettings));
     394              :         if (temp == NULL) {
     395              :             dlt_vlog(LOG_ERR, "Failed to allocate memory for trace load settings\n");
     396              :             free(*settings); // Free any previously allocated memory
     397              :             *settings = NULL;
     398              :             *num_settings = 0;
     399              :             return DLT_RETURN_ERROR;
     400              :         }
     401              :         *settings = temp;
     402              :         // Copy preconfigured trace load settings into the app settings
     403              :         (*settings)[*num_settings] = daemon->preconfigured_trace_load_settings[i];
     404              :         (*num_settings)++;
     405              :     }
     406              : 
     407              :     qsort(*settings, (size_t)*num_settings, sizeof(DltTraceLoadSettings),
     408              :           dlt_daemon_compare_trace_load_settings);
     409              :     return DLT_RETURN_OK;
     410              : }
     411              : #endif
     412              : 
     413            1 : int dlt_daemon_init_runtime_configuration(DltDaemon *daemon, const char *runtime_directory, int verbose)
     414              : {
     415            1 :     PRINT_FUNCTION_VERBOSE(verbose);
     416              :     size_t append_length = 0;
     417              : 
     418            1 :     if (daemon == NULL)
     419              :         return DLT_RETURN_ERROR;
     420              : 
     421              :     /* Default */
     422            1 :     daemon->mode = DLT_USER_MODE_EXTERNAL;
     423              : 
     424            1 :     if (runtime_directory == NULL)
     425              :         return DLT_RETURN_ERROR;
     426              : 
     427              :     /* prepare filenames for configuration */
     428              :     append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
     429              : 
     430            1 :     if (runtime_directory[0]) {
     431            0 :         strncpy(daemon->runtime_application_cfg, runtime_directory, append_length);
     432            0 :         daemon->runtime_application_cfg[append_length] = 0;
     433              :     }
     434              :     else {
     435            1 :         strncpy(daemon->runtime_application_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
     436            1 :         daemon->runtime_application_cfg[append_length] = 0;
     437              :     }
     438              : 
     439            1 :     strcat(daemon->runtime_application_cfg, DLT_RUNTIME_APPLICATION_CFG); /* strcat uncritical here, because max length already checked */
     440              : 
     441              :     append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
     442              : 
     443            1 :     if (runtime_directory[0]) {
     444            0 :         strncpy(daemon->runtime_context_cfg, runtime_directory, append_length);
     445            0 :         daemon->runtime_context_cfg[append_length] = 0;
     446              :     }
     447              :     else {
     448            1 :         strncpy(daemon->runtime_context_cfg, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
     449            1 :         daemon->runtime_context_cfg[append_length] = 0;
     450              :     }
     451              : 
     452            1 :     strcat(daemon->runtime_context_cfg, DLT_RUNTIME_CONTEXT_CFG); /* strcat uncritical here, because max length already checked */
     453              : 
     454              :     append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
     455              : 
     456            1 :     if (runtime_directory[0]) {
     457            0 :         strncpy(daemon->runtime_configuration, runtime_directory, append_length);
     458            0 :         daemon->runtime_configuration[append_length] = 0;
     459              :     }
     460              :     else {
     461            1 :         strncpy(daemon->runtime_configuration, DLT_RUNTIME_DEFAULT_DIRECTORY, append_length);
     462            1 :         daemon->runtime_configuration[append_length] = 0;
     463              :     }
     464              : 
     465            1 :     strcat(daemon->runtime_configuration, DLT_RUNTIME_CONFIGURATION); /* strcat uncritical here, because max length already checked */
     466              : 
     467            1 :     return DLT_RETURN_OK;
     468              : }
     469              : 
     470           10 : int dlt_daemon_init(DltDaemon *daemon,
     471              :                     unsigned long RingbufferMinSize,
     472              :                     unsigned long RingbufferMaxSize,
     473              :                     unsigned long RingbufferStepSize,
     474              :                     const char *runtime_directory,
     475              :                     int InitialContextLogLevel,
     476              :                     int InitialContextTraceStatus,
     477              :                     int ForceLLTS,
     478              :                     int verbose)
     479              : {
     480           10 :     PRINT_FUNCTION_VERBOSE(verbose);
     481              : 
     482           10 :     if ((daemon == NULL) || (runtime_directory == NULL))
     483              :         return -1;
     484              : 
     485           10 :     daemon->user_list = NULL;
     486           10 :     daemon->num_user_lists = 0;
     487              : 
     488           10 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
     489           10 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
     490           10 :     daemon->force_ll_ts = (int8_t) ForceLLTS;
     491              : 
     492           10 :     daemon->overflow_counter = 0;
     493              : 
     494           10 :     daemon->runtime_context_cfg_loaded = 0;
     495              : 
     496           10 :     daemon->connectionState = 0; /* no logger connected */
     497              : 
     498           10 :     daemon->state = DLT_DAEMON_STATE_INIT; /* initial logging state */
     499              : 
     500              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     501              :     daemon->preconfigured_trace_load_settings = NULL;
     502              :     daemon->bytes_sent = 0;
     503              :     daemon->bytes_recv = 0;
     504              : #endif
     505              : 
     506           10 :     daemon->sendserialheader = 0;
     507           10 :     daemon->timingpackets = 0;
     508              : 
     509           10 :     dlt_set_id(daemon->ecuid, "");
     510           10 :     daemon->ecuid2len = 0;
     511           10 :     memset(daemon->ecuid2, 0, DLT_V2_ID_SIZE);
     512              : 
     513              :     /* initialize ring buffer for client connection */
     514           10 :     dlt_vlog(LOG_INFO, "Ringbuffer configuration: %lu/%lu/%lu\n",
     515              :              RingbufferMinSize, RingbufferMaxSize, RingbufferStepSize);
     516              : 
     517           10 :     if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer),
     518              :                                 (uint32_t) RingbufferMinSize,
     519              :                                 (uint32_t) RingbufferMaxSize,
     520              :                                 (uint32_t) RingbufferStepSize) < DLT_RETURN_OK)
     521              :         return -1;
     522              : 
     523           10 :     daemon->storage_handle = NULL;
     524              : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
     525              :     daemon->received_message_since_last_watchdog_interval = 0;
     526              : #endif
     527           10 :     return 0;
     528              : }
     529              : 
     530            1 : int dlt_daemon_free(DltDaemon *daemon, int verbose)
     531              : {
     532              :     int i = 0;
     533              :     DltDaemonRegisteredUsers *user_list = NULL;
     534              : 
     535            1 :     PRINT_FUNCTION_VERBOSE(verbose);
     536              : 
     537            1 :     if ((daemon == NULL) || (daemon->user_list == NULL))
     538              :         return -1;
     539              : 
     540              :     /* free all registered user information */
     541            2 :     for (i = 0; i < daemon->num_user_lists; i++) {
     542            1 :         user_list = &daemon->user_list[i];
     543              : 
     544            1 :         if (user_list != NULL) {
     545              :             /* ignore return values */
     546            1 :             dlt_daemon_contexts_clear(daemon, user_list->ecu, verbose);
     547            1 :             dlt_daemon_applications_clear(daemon, user_list->ecu, verbose);
     548              :         }
     549              :     }
     550              : 
     551            1 :     free(daemon->user_list);
     552              : 
     553              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     554              :     if (daemon->app_id_log_level_settings != NULL) {
     555              :       free(daemon->app_id_log_level_settings);
     556              :     }
     557              : #endif
     558              : 
     559            1 :     if (app_recv_buffer)
     560            1 :         free(app_recv_buffer);
     561              : 
     562              :     /* free ringbuffer */
     563            1 :     dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
     564              : 
     565            1 :     return 0;
     566              : }
     567              : 
     568           11 : int dlt_daemon_init_user_information(DltDaemon *daemon,
     569              :                                      DltGateway *gateway,
     570              :                                      int gateway_mode,
     571              :                                      int verbose)
     572              : {
     573              :     int nodes = 1;
     574              :     int i = 1;
     575              : 
     576           11 :     PRINT_FUNCTION_VERBOSE(verbose);
     577              : 
     578           11 :     if ((daemon == NULL) || ((gateway_mode == 1) && (gateway == NULL)))
     579              :         return DLT_RETURN_ERROR;
     580              : 
     581           11 :     if (gateway_mode == 0) {
     582              :         /* initialize application list */
     583           11 :         daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
     584              : 
     585           11 :         if (daemon->user_list == NULL) {
     586            0 :             dlt_log(LOG_ERR, "Allocating memory for user information");
     587            0 :             return DLT_RETURN_ERROR;
     588              :         }
     589              : 
     590           11 :         dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
     591           11 :         daemon->user_list[0].ecuid2len = daemon->ecuid2len;
     592           11 :         dlt_set_id_v2(daemon->user_list[0].ecuid2, daemon->ecuid2, daemon->ecuid2len);
     593           11 :         daemon->num_user_lists = 1;
     594              :     }
     595              :     else { /* gateway is active */
     596            0 :         nodes += gateway->num_connections;
     597              : 
     598              :         /* initialize application list */
     599            0 :         daemon->user_list = calloc((size_t) nodes, sizeof(DltDaemonRegisteredUsers));
     600              : 
     601            0 :         if (daemon->user_list == NULL) {
     602            0 :             dlt_log(LOG_ERR, "Allocating memory for user information");
     603            0 :             return DLT_RETURN_ERROR;
     604              :         }
     605              : 
     606            0 :         dlt_set_id(daemon->user_list[0].ecu, daemon->ecuid);
     607            0 :         daemon->user_list[0].ecuid2len = daemon->ecuid2len;
     608            0 :         dlt_set_id_v2(daemon->user_list[0].ecuid2, daemon->ecuid2, daemon->ecuid2len);
     609            0 :         daemon->num_user_lists = nodes;
     610              : 
     611            0 :         for (i = 1; i < nodes; i++) {
     612            0 :             dlt_set_id(daemon->user_list[i].ecu, gateway->connections[i - 1].ecuid);
     613            0 :             daemon->user_list[i].ecuid2len = gateway->connections[i - 1].ecuid2len;
     614            0 :             dlt_set_id_v2(daemon->user_list[i].ecuid2, gateway->connections[i - 1].ecuid2, gateway->connections[i - 1].ecuid2len);
     615              :         }
     616              :     }
     617              : 
     618              :     return DLT_RETURN_OK;
     619              : }
     620              : 
     621            5 : int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,
     622              :                                           char *ecu,
     623              :                                           int fd,
     624              :                                           int verbose)
     625              : {
     626              :     int i;
     627              :     DltDaemonRegisteredUsers *user_list = NULL;
     628              : 
     629            5 :     PRINT_FUNCTION_VERBOSE(verbose);
     630              : 
     631            5 :     if ((daemon == NULL) || (ecu == NULL))
     632              :         return DLT_RETURN_ERROR;
     633              : 
     634            5 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     635              : 
     636            5 :     if (user_list != NULL) {
     637           10 :         for (i = 0; i < user_list->num_applications; i++)
     638            5 :             if (user_list->applications[i].user_handle == fd)
     639            0 :                 user_list->applications[i].user_handle = DLT_FD_INIT;
     640              : 
     641              :         return DLT_RETURN_OK;
     642              :     }
     643              : 
     644              :     return DLT_RETURN_ERROR;
     645              : }
     646              : 
     647            0 : int dlt_daemon_applications_invalidate_fd_v2(DltDaemon *daemon,
     648              :                                              char *ecu,
     649              :                                              int fd,
     650              :                                              int verbose)
     651              : {
     652              :     int i;
     653              :     DltDaemonRegisteredUsers *user_list = NULL;
     654              : 
     655            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     656              : 
     657            0 :     if ((daemon == NULL) || (ecu == NULL))
     658              :         return DLT_RETURN_ERROR;
     659            0 :     uint8_t eculen = (uint8_t)strlen(ecu);
     660            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
     661              : 
     662            0 :     if (user_list != NULL) {
     663            0 :         for (i = 0; i < user_list->num_applications; i++)
     664            0 :             if (user_list->applications[i].user_handle == fd)
     665            0 :                 user_list->applications[i].user_handle = DLT_FD_INIT;
     666              : 
     667              :         return DLT_RETURN_OK;
     668              :     }
     669              : 
     670              :     return DLT_RETURN_ERROR;
     671              : }
     672              : 
     673            1 : int dlt_daemon_applications_clear(DltDaemon *daemon, char *ecu, int verbose)
     674              : {
     675              :     int i;
     676              :     DltDaemonRegisteredUsers *user_list = NULL;
     677              : 
     678            1 :     PRINT_FUNCTION_VERBOSE(verbose);
     679              : 
     680            1 :     if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
     681              :         return DLT_RETURN_WRONG_PARAMETER;
     682              : 
     683            1 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     684              : 
     685            1 :     if (user_list == NULL)
     686              :         return DLT_RETURN_ERROR;
     687              : 
     688            2 :     for (i = 0; i < user_list->num_applications; i++)
     689            1 :         if (user_list->applications[i].application_description != NULL) {
     690              : 
     691              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     692              :             if (user_list->applications[i].context_log_level_settings)
     693              :                 free(user_list->applications[i].context_log_level_settings);
     694              : #endif
     695              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     696              :             if (user_list->applications[i].trace_load_settings) {
     697              :                 free(user_list->applications[i].trace_load_settings);
     698              :                 user_list->applications[i].trace_load_settings = NULL;
     699              :                 user_list->applications[i].trace_load_settings_count = 0;
     700              :             }
     701              : #endif
     702            1 :             free(user_list->applications[i].application_description);
     703            1 :             user_list->applications[i].application_description = NULL;
     704              :         }
     705              : 
     706            1 :     if (user_list->applications != NULL)
     707            1 :         free(user_list->applications);
     708              : 
     709            1 :     user_list->applications = NULL;
     710            1 :     user_list->num_applications = 0;
     711              : 
     712            1 :     return 0;
     713              : }
     714              : 
     715            0 : int dlt_daemon_applications_clear_v2(DltDaemon *daemon, char *ecu, int verbose)
     716              : {
     717              :     int i;
     718              :     DltDaemonRegisteredUsers *user_list = NULL;
     719              : 
     720            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     721              : 
     722            0 :     if ((daemon == NULL) || (daemon->user_list == NULL) || (ecu == NULL))
     723              :         return DLT_RETURN_WRONG_PARAMETER;
     724              : 
     725            0 :     uint8_t eculen = (uint8_t)strlen(ecu);
     726              : 
     727            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
     728              : 
     729            0 :     if (user_list == NULL)
     730              :         return DLT_RETURN_ERROR;
     731              : 
     732            0 :     for (i = 0; i < user_list->num_applications; i++)
     733            0 :         if (user_list->applications[i].application_description != NULL) {
     734              : 
     735              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     736              :             if (user_list->applications[i].context_log_level_settings)
     737              :                 free(user_list->applications[i].context_log_level_settings);
     738              : #endif
     739              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     740              :             if (user_list->applications[i].trace_load_settings) {
     741              :                 free(user_list->applications[i].trace_load_settings);
     742              :                 user_list->applications[i].trace_load_settings = NULL;
     743              :                 user_list->applications[i].trace_load_settings_count = 0;
     744              :             }
     745              : #endif
     746            0 :             free(user_list->applications[i].application_description);
     747            0 :             user_list->applications[i].application_description = NULL;
     748              :         }
     749              : 
     750            0 :     if (user_list->applications != NULL)
     751            0 :         free(user_list->applications);
     752              : 
     753            0 :     user_list->applications = NULL;
     754            0 :     user_list->num_applications = 0;
     755              : 
     756            0 :     return 0;
     757              : }
     758              : 
     759            3 : static void dlt_daemon_application_reset_user_handle(DltDaemon *daemon,
     760              :                                                      DltDaemonApplication *application,
     761              :                                                      int verbose)
     762              : {
     763              :     DltDaemonRegisteredUsers *user_list;
     764              :     DltDaemonContext *context;
     765              :     int i;
     766              : 
     767            3 :     if (application->user_handle == DLT_FD_INIT)
     768              :         return;
     769              : 
     770            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
     771            0 :     if (user_list != NULL) {
     772            0 :         for (i = 0; i < user_list->num_contexts; i++) {
     773            0 :             context = &user_list->contexts[i];
     774            0 :             if (context->user_handle == application->user_handle)
     775            0 :                 context->user_handle = DLT_FD_INIT;
     776              :         }
     777              :     }
     778              : 
     779            0 :     if (application->owns_user_handle)
     780            0 :         close(application->user_handle);
     781              : 
     782            0 :     application->user_handle = DLT_FD_INIT;
     783            0 :     application->owns_user_handle = false;
     784              : }
     785              : 
     786            0 : static void dlt_daemon_application_reset_user_handle_v2(DltDaemon *daemon,
     787              :                                                      DltDaemonApplication *application,
     788              :                                                      int verbose)
     789              : {
     790              :     DltDaemonRegisteredUsers *user_list;
     791              :     DltDaemonContext *context;
     792              :     int i;
     793              : 
     794            0 :     if (application->user_handle == DLT_FD_INIT)
     795              :         return;
     796              : 
     797            0 :     user_list = dlt_daemon_find_users_list_v2(daemon,  daemon->ecuid2len, daemon->ecuid2, verbose);
     798            0 :     if (user_list != NULL) {
     799            0 :         for (i = 0; i < user_list->num_contexts; i++) {
     800            0 :             context = &user_list->contexts[i];
     801            0 :             if (context->user_handle == application->user_handle)
     802            0 :                 context->user_handle = DLT_FD_INIT;
     803              :         }
     804              :     }
     805              : 
     806            0 :     if (application->owns_user_handle)
     807            0 :         close(application->user_handle);
     808              : 
     809            0 :     application->user_handle = DLT_FD_INIT;
     810            0 :     application->owns_user_handle = false;
     811              : }
     812              : 
     813            4 : DltDaemonApplication *dlt_daemon_application_add(DltDaemon *daemon,
     814              :                                                  char *apid,
     815              :                                                  pid_t pid,
     816              :                                                  char *description,
     817              :                                                  int fd,
     818              :                                                  char *ecu,
     819              :                                                  int verbose)
     820              : {
     821              :     DltDaemonApplication *application;
     822              :     DltDaemonApplication *old;
     823              :     int new_application;
     824              :     int dlt_user_handle;
     825              :     bool owns_user_handle;
     826              :     DltDaemonRegisteredUsers *user_list = NULL;
     827              : #ifdef DLT_DAEMON_USE_FIFO_IPC
     828              :     (void)fd;  /* To avoid compiler warning : unused variable */
     829              :     char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
     830              : #endif
     831              : 
     832            4 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
     833              :         return (DltDaemonApplication *)NULL;
     834              : 
     835            4 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     836              : 
     837            4 :     if (user_list == NULL)
     838              :         return (DltDaemonApplication *)NULL;
     839              : 
     840            4 :     if (user_list->applications == NULL) {
     841            4 :         user_list->applications = (DltDaemonApplication *)
     842            4 :             malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
     843              : 
     844            4 :         if (user_list->applications == NULL)
     845              :             return (DltDaemonApplication *)NULL;
     846              :     }
     847              : 
     848              :     new_application = 0;
     849              : 
     850              :     /* Check if application [apid] is already available */
     851            4 :     application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
     852              : 
     853            4 :     if (application == NULL) {
     854            4 :         user_list->num_applications += 1;
     855              : 
     856            4 :         if (user_list->num_applications != 0) {
     857            4 :             if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
     858              :                 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
     859            0 :                 old = user_list->applications;
     860            0 :                 user_list->applications = (DltDaemonApplication *)
     861            0 :                     malloc((size_t)sizeof(DltDaemonApplication) *
     862            0 :                            ((size_t)(user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1) *
     863              :                            (size_t)DLT_DAEMON_APPL_ALLOC_SIZE);
     864              : 
     865            0 :                 if (user_list->applications == NULL) {
     866            0 :                     user_list->applications = old;
     867            0 :                     user_list->num_applications -= 1;
     868            0 :                     return (DltDaemonApplication *)NULL;
     869              :                 }
     870              : 
     871            0 :                   memcpy(user_list->applications,
     872              :                          old,
     873            0 :                          (size_t)sizeof(DltDaemonApplication) * (size_t)user_list->num_applications);
     874            0 :                 free(old);
     875              :             }
     876              :         }
     877              : 
     878            4 :         application = &(user_list->applications[(size_t)(user_list->num_applications - 1)]);
     879              : 
     880            4 :         dlt_set_id(application->apid, apid);
     881            4 :         application->pid = 0;
     882            4 :         application->application_description = NULL;
     883            4 :         application->num_contexts = 0;
     884            4 :         application->user_handle = DLT_FD_INIT;
     885            4 :         application->owns_user_handle = false;
     886              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     887              :         application->trace_load_settings = NULL;
     888              :         application->trace_load_settings_count = 0;
     889              : #endif
     890              : 
     891              :         new_application = 1;
     892              : 
     893              :     }
     894            0 :     else if ((pid != application->pid) && (application->pid != 0))
     895              :     {
     896              : 
     897            0 :         dlt_vlog(LOG_WARNING,
     898              :                  "Duplicate registration of ApplicationID: '%.4s'; registering from PID %d, existing from PID %d\n",
     899              :                  apid,
     900              :                  pid,
     901              :                  application->pid);
     902              :     }
     903              : 
     904              :     /* Store application description and pid of application */
     905            4 :     if (application->application_description) {
     906            0 :         free(application->application_description);
     907            0 :         application->application_description = NULL;
     908              :     }
     909              : 
     910            4 :     if (description != NULL) {
     911            4 :         application->application_description = malloc(strlen(description) + 1);
     912              : 
     913            4 :         if (application->application_description) {
     914            4 :             memcpy(application->application_description, description, strlen(description) + 1);
     915              :         } else {
     916            0 :             dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
     917            0 :             free(application);
     918            0 :             return (DltDaemonApplication *)NULL;
     919              :         }
     920              :     }
     921              : 
     922            4 :     if (application->pid != pid) {
     923            3 :         dlt_daemon_application_reset_user_handle(daemon, application, verbose);
     924            3 :         application->pid = 0;
     925              :     }
     926              : 
     927              :     /* open user pipe only if it is not yet opened */
     928            4 :     if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
     929              :         dlt_user_handle = DLT_FD_INIT;
     930              :         owns_user_handle = false;
     931              : 
     932              : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
     933              :         if (fd >= DLT_FD_MINIMUM) {
     934              :             dlt_user_handle = fd;
     935              :             owns_user_handle = false;
     936              :         }
     937              : #endif
     938              : #ifdef DLT_DAEMON_USE_FIFO_IPC
     939              :         if (dlt_user_handle < DLT_FD_MINIMUM) {
     940              :             int ret = snprintf(filename,
     941              :                             DLT_DAEMON_COMMON_TEXTBUFSIZE,
     942              :                             "%s/dltpipes/dlt%d",
     943              :                             dltFifoBaseDir,
     944              :                             (int)pid);
     945            3 :             if (ret < 0 || ret >= DLT_DAEMON_COMMON_TEXTBUFSIZE) {
     946            0 :                 filename[0] = '\0';
     947              :             }
     948              : 
     949              :             dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
     950              : 
     951            3 :             if (dlt_user_handle < 0) {
     952            0 :                 int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
     953            0 :                 dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
     954              :             } else {
     955              :                 owns_user_handle = true;
     956              :             }
     957              :         }
     958              : #endif
     959              :         /* check if file descriptor was already used, and make it invalid if it
     960              :         * is reused. This prevents sending messages to wrong file descriptor */
     961            3 :         dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
     962            3 :         dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
     963              : 
     964            3 :         application->user_handle = dlt_user_handle;
     965            3 :         application->owns_user_handle = owns_user_handle;
     966            3 :         application->pid = pid;
     967              :     }
     968              : 
     969              :     /* Sort */
     970            4 :     if (new_application) {
     971            4 :         qsort(user_list->applications,
     972            4 :               (size_t) user_list->num_applications,
     973              :               sizeof(DltDaemonApplication),
     974              :               dlt_daemon_cmp_apid);
     975              : 
     976              :         /* Find new position of application with apid*/
     977            4 :         application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
     978              :     }
     979              : 
     980              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
     981              :     application->num_context_log_level_settings = 0;
     982              :     application->context_log_level_settings = NULL;
     983              : #endif
     984              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     985              :     if (application->trace_load_settings == NULL) {
     986              :         DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
     987              :         int num_settings = 0;
     988              :         DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
     989              :             daemon,
     990              :             application->apid,
     991              :             NULL /*load settings for all contexts*/,
     992              :             &pre_configured_trace_load_settings,
     993              :             &num_settings,
     994              :             verbose);
     995              : 
     996              :         DltTraceLoadSettings *app_level = NULL;
     997              :         if ((find_trace_settings_return_value == DLT_RETURN_OK) &&
     998              :             (pre_configured_trace_load_settings != NULL) &&
     999              :             (num_settings != 0)) {
    1000              :             application->trace_load_settings = pre_configured_trace_load_settings;
    1001              :             application->trace_load_settings_count = num_settings;
    1002              :             app_level = dlt_find_runtime_trace_load_settings(
    1003              :                 application->trace_load_settings,
    1004              :                 application->trace_load_settings_count, application->apid,
    1005              :                 NULL);
    1006              :         }
    1007              : 
    1008              :         // app is not configured, set daemon defaults
    1009              :         if (app_level == NULL) {
    1010              :             DltTraceLoadSettings *temp = realloc(application->trace_load_settings,
    1011              :                                                  (application->trace_load_settings_count + 1) *
    1012              :                                                      sizeof(DltTraceLoadSettings));
    1013              : 
    1014              :             if (temp != NULL) {
    1015              :                 application->trace_load_settings = temp;
    1016              :                 ++application->trace_load_settings_count;
    1017              : 
    1018              :                 app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
    1019              :                 memset(app_level, 0, sizeof(DltTraceLoadSettings));
    1020              :                 app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
    1021              :                 app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
    1022              :                 memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
    1023              :                 memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
    1024              :             } else {
    1025              :                 dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
    1026              :             }
    1027              : 
    1028              :             // We inserted the application id at the end, to make sure
    1029              :             // Lookups are working properly later on, we have to sort the list again.
    1030              :             qsort(application->trace_load_settings,
    1031              :                   (size_t)application->trace_load_settings_count,
    1032              :                   sizeof(DltTraceLoadSettings),
    1033              :                   dlt_daemon_compare_trace_load_settings);
    1034              :         }
    1035              :     }
    1036              : 
    1037              : #endif
    1038              : 
    1039              :     return application;
    1040              : }
    1041              : 
    1042            0 : DltDaemonApplication *dlt_daemon_application_add_v2(DltDaemon *daemon,
    1043              :                                                  uint8_t apidlen,
    1044              :                                                  char *apid,
    1045              :                                                  pid_t pid,
    1046              :                                                  char *description,
    1047              :                                                  int fd,
    1048              :                                                  uint8_t eculen,
    1049              :                                                  char *ecu,
    1050              :                                                  int verbose)
    1051              : {
    1052              :     DltDaemonApplication *application;
    1053              :     DltDaemonApplication *old;
    1054              :     int new_application;
    1055              :     int dlt_user_handle;
    1056              :     bool owns_user_handle;
    1057              :     DltDaemonRegisteredUsers *user_list = NULL;
    1058              : #ifdef DLT_DAEMON_USE_FIFO_IPC
    1059              :     (void)fd;  /* To avoid compiler warning : unused variable */
    1060              :     char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
    1061              : #endif
    1062              : 
    1063            0 :     if ((daemon == NULL) || (apidlen == 0) || (eculen == 0) ||
    1064            0 :         (apid == NULL) || (ecu == NULL))
    1065              :         return (DltDaemonApplication *)NULL;
    1066              : 
    1067            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    1068              : 
    1069            0 :     if (user_list == NULL)
    1070              :         return (DltDaemonApplication *)NULL;
    1071              : 
    1072            0 :     if (user_list->applications == NULL) {
    1073            0 :         user_list->applications = (DltDaemonApplication *)
    1074            0 :             malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
    1075              : 
    1076            0 :         if (user_list->applications == NULL)
    1077              :             return (DltDaemonApplication *)NULL;
    1078              :     }
    1079              : 
    1080              :     new_application = 0;
    1081              : 
    1082              :     /* Check if application [apid] is already available */
    1083            0 :     dlt_daemon_application_find_v2(daemon, apidlen, apid, eculen, ecu, verbose, &application);
    1084              : 
    1085            0 :     if (application == NULL) {
    1086            0 :         user_list->num_applications += 1;
    1087              : 
    1088            0 :         if (user_list->num_applications != 0) {
    1089            0 :             if ((user_list->num_applications % DLT_DAEMON_APPL_ALLOC_SIZE) == 0) {
    1090              :                 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
    1091            0 :                 old = user_list->applications;
    1092            0 :                 user_list->applications = (DltDaemonApplication *)
    1093            0 :                     malloc(sizeof(DltDaemonApplication) *
    1094            0 :                            (((size_t)user_list->num_applications / DLT_DAEMON_APPL_ALLOC_SIZE) + 1) *
    1095              :                            DLT_DAEMON_APPL_ALLOC_SIZE);
    1096              : 
    1097            0 :                 if (user_list->applications == NULL) {
    1098            0 :                     user_list->applications = old;
    1099            0 :                     user_list->num_applications -= 1;
    1100            0 :                     return (DltDaemonApplication *)NULL;
    1101              :                 }
    1102              : 
    1103            0 :                 memcpy(user_list->applications,
    1104              :                        old,
    1105              :                        sizeof(DltDaemonApplication) * (size_t)user_list->num_applications);
    1106            0 :                 free(old);
    1107              :             }
    1108              :         }
    1109              : 
    1110            0 :         application = &(user_list->applications[user_list->num_applications - 1]);
    1111              : 
    1112            0 :         memset(application->apid2, 0, DLT_V2_ID_SIZE);
    1113            0 :         application->apid2len = apidlen;
    1114            0 :         dlt_set_id_v2(application->apid2, apid, apidlen);
    1115            0 :         application->pid = 0;
    1116            0 :         application->application_description = NULL;
    1117            0 :         application->num_contexts = 0;
    1118            0 :         application->user_handle = DLT_FD_INIT;
    1119            0 :         application->owns_user_handle = false;
    1120              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    1121              :         application->trace_load_settings = NULL;
    1122              :         application->trace_load_settings_count = 0;
    1123              : #endif
    1124              : 
    1125              :         new_application = 1;
    1126              :     }
    1127            0 :     else if ((pid != application->pid) && (application->pid != 0))
    1128              :     {
    1129              : 
    1130            0 :         dlt_vlog(LOG_WARNING,
    1131              :                  "Duplicate registration of ApplicationID: '%s'; registering from PID %d, existing from PID %d\n",
    1132              :                  apid,
    1133              :                  pid,
    1134              :                  application->pid);
    1135              :     }
    1136              : 
    1137              :     /* Store application description and pid of application */
    1138            0 :     if (application->application_description) {
    1139            0 :         free(application->application_description);
    1140            0 :         application->application_description = NULL;
    1141              :     }
    1142              : 
    1143            0 :     if (description != NULL) {
    1144            0 :         application->application_description = malloc(strlen(description) + 1);
    1145              : 
    1146            0 :         if (application->application_description) {
    1147            0 :             memcpy(application->application_description, description, strlen(description) + 1);
    1148              :         } else {
    1149            0 :             dlt_log(LOG_ERR, "Cannot allocate memory to store application description\n");
    1150            0 :             free(application);
    1151            0 :             return (DltDaemonApplication *)NULL;
    1152              :         }
    1153              :     }
    1154              : 
    1155            0 :     if (application->pid != pid) {
    1156            0 :         dlt_daemon_application_reset_user_handle_v2(daemon, application, verbose);
    1157            0 :         application->pid = 0;
    1158              :     }
    1159              : 
    1160              :     /* open user pipe only if it is not yet opened */
    1161            0 :     if ((application->user_handle == DLT_FD_INIT) && (pid != 0)) {
    1162              :         dlt_user_handle = DLT_FD_INIT;
    1163              :         owns_user_handle = false;
    1164              : 
    1165              : #if defined DLT_DAEMON_USE_UNIX_SOCKET_IPC || defined DLT_DAEMON_VSOCK_IPC_ENABLE
    1166              :         if (fd >= DLT_FD_MINIMUM) {
    1167              :             dlt_user_handle = fd;
    1168              :             owns_user_handle = false;
    1169              :         }
    1170              : #endif
    1171              : #ifdef DLT_DAEMON_USE_FIFO_IPC
    1172              :         if (dlt_user_handle < DLT_FD_MINIMUM) {
    1173              :             int ret = snprintf(filename,
    1174              :                                DLT_DAEMON_COMMON_TEXTBUFSIZE,
    1175              :                                "%s/dltpipes/dlt%d",
    1176              :                                dltFifoBaseDir,
    1177              :                                pid);
    1178              : 
    1179            0 :             if (ret < 0 || ret >= DLT_DAEMON_COMMON_TEXTBUFSIZE) {
    1180            0 :                 dlt_log(LOG_ERR, "Failed to construct FIFO filename - path too long!\n");
    1181            0 :                 return NULL;
    1182              :             }
    1183              : 
    1184              :             dlt_user_handle = open(filename, O_WRONLY | O_NONBLOCK);
    1185              : 
    1186            0 :             if (dlt_user_handle < 0) {
    1187            0 :                 int prio = (errno == ENOENT) ? LOG_INFO : LOG_WARNING;
    1188            0 :                 dlt_vlog(prio, "open() failed to %s, errno=%d (%s)!\n", filename, errno, strerror(errno));
    1189              :             } else {
    1190              :                 owns_user_handle = true;
    1191              :             }
    1192              :         }
    1193              : #endif
    1194              :         /* check if file descriptor was already used, and make it invalid if it
    1195              :         * is reused. This prevents sending messages to wrong file descriptor */
    1196            0 :         dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
    1197            0 :         dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
    1198              : 
    1199            0 :         application->user_handle = dlt_user_handle;
    1200            0 :         application->owns_user_handle = owns_user_handle;
    1201            0 :         application->pid = pid;
    1202              :     }
    1203              : 
    1204              :     /* Sort */
    1205            0 :     if (new_application) {
    1206            0 :         qsort(user_list->applications,
    1207            0 :               (size_t) user_list->num_applications,
    1208              :               sizeof(DltDaemonApplication),
    1209              :               dlt_daemon_cmp_apid_v2);
    1210              :         /* Find new position of application with apid*/
    1211            0 :         dlt_daemon_application_find_v2(daemon, apidlen, apid, eculen, ecu, verbose, &application);
    1212              :     }
    1213              : 
    1214              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1215              :     application->num_context_log_level_settings = 0;
    1216              :     application->context_log_level_settings = NULL;
    1217              : #endif
    1218              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    1219              :     if (application->trace_load_settings == NULL) {
    1220              :         DltTraceLoadSettings* pre_configured_trace_load_settings = NULL;
    1221              :         int num_settings = 0;
    1222              :         DltReturnValue find_trace_settings_return_value = dlt_daemon_find_preconfigured_trace_load_settings(
    1223              :             daemon,
    1224              :             application->apid,
    1225              :             NULL /*load settings for all contexts*/,
    1226              :             &pre_configured_trace_load_settings,
    1227              :             &num_settings,
    1228              :             verbose);
    1229              : 
    1230              :         DltTraceLoadSettings *app_level = NULL;
    1231              :         if ((find_trace_settings_return_value == DLT_RETURN_OK) &&
    1232              :             (pre_configured_trace_load_settings != NULL) &&
    1233              :             (num_settings != 0)) {
    1234              :             application->trace_load_settings = pre_configured_trace_load_settings;
    1235              :             application->trace_load_settings_count = num_settings;
    1236              :             app_level = dlt_find_runtime_trace_load_settings(
    1237              :                 application->trace_load_settings,
    1238              :                 application->trace_load_settings_count, application->apid,
    1239              :                 NULL);
    1240              :         }
    1241              : 
    1242              :         // app is not configured, set daemon defaults
    1243              :         if (app_level == NULL) {
    1244              :             DltTraceLoadSettings *temp = realloc(application->trace_load_settings,
    1245              :                                                  (application->trace_load_settings_count + 1) *
    1246              :                                                      sizeof(DltTraceLoadSettings));
    1247              : 
    1248              :             if (temp != NULL) {
    1249              :                 application->trace_load_settings = temp;
    1250              :                 ++application->trace_load_settings_count;
    1251              : 
    1252              :                 app_level = &application->trace_load_settings[application->trace_load_settings_count - 1];
    1253              :                 memset(app_level, 0, sizeof(DltTraceLoadSettings));
    1254              :                 app_level[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
    1255              :                 app_level[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
    1256              :                 memcpy(&app_level[0].apid, apid, DLT_ID_SIZE);
    1257              :                 memset(&app_level[0].tl_stat, 0, sizeof(DltTraceLoadStat));
    1258              :             } else {
    1259              :                 dlt_vlog(DLT_LOG_FATAL, "Failed to allocate memory for trace load settings\n");
    1260              :             }
    1261              : 
    1262              :             // We inserted the application id at the end, to make sure
    1263              :             // Lookups are working properly later on, we have to sort the list again.
    1264              :             qsort(application->trace_load_settings,
    1265              :                   (size_t)application->trace_load_settings_count,
    1266              :                   sizeof(DltTraceLoadSettings),
    1267              :                   dlt_daemon_compare_trace_load_settings);
    1268              :         }
    1269              :     }
    1270              : 
    1271              : #endif
    1272              : 
    1273            0 :     return application;
    1274              : }
    1275              : 
    1276            0 : int dlt_daemon_application_del(DltDaemon *daemon,
    1277              :                                DltDaemonApplication *application,
    1278              :                                char *ecu,
    1279              :                                int verbose)
    1280              : {
    1281              :     int pos;
    1282              :     DltDaemonRegisteredUsers *user_list = NULL;
    1283              : 
    1284            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1285              : 
    1286            0 :     if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
    1287              :         return -1;
    1288              : 
    1289            0 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1290              : 
    1291            0 :     if (user_list == NULL)
    1292              :         return -1;
    1293              : 
    1294            0 :     if (user_list->num_applications > 0) {
    1295            0 :         dlt_daemon_application_reset_user_handle(daemon, application, verbose);
    1296              : 
    1297              :         /* Free description of application to be deleted */
    1298            0 :         if (application->application_description) {
    1299            0 :             free(application->application_description);
    1300            0 :             application->application_description = NULL;
    1301              :         }
    1302              : 
    1303              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    1304              :         if (application->trace_load_settings != NULL) {
    1305              :             free(application->trace_load_settings);
    1306              :             application->trace_load_settings = NULL;
    1307              :             application->trace_load_settings_count = 0;
    1308              :         }
    1309              : #endif
    1310            0 :         pos = (int) (application - (user_list->applications));
    1311              : 
    1312              :         /* move all applications above pos to pos */
    1313            0 :         memmove(&(user_list->applications[pos]),
    1314            0 :                 &(user_list->applications[pos + 1]),
    1315            0 :                 (size_t)sizeof(DltDaemonApplication) * (size_t)((user_list->num_applications - 1) - pos));
    1316              : 
    1317              :         /* Clear last application */
    1318            0 :         memset(&(user_list->applications[user_list->num_applications - 1]),
    1319              :                0,
    1320              :                sizeof(DltDaemonApplication));
    1321              : 
    1322            0 :         user_list->num_applications--;
    1323              :     }
    1324              : 
    1325              :     return 0;
    1326              : }
    1327              : 
    1328            0 : int dlt_daemon_application_del_v2(DltDaemon *daemon,
    1329              :                                DltDaemonApplication *application,
    1330              :                                uint8_t eculen,
    1331              :                                char *ecu,
    1332              :                                int verbose)
    1333              : {
    1334              :     int pos;
    1335              :     DltDaemonRegisteredUsers *user_list = NULL;
    1336              : 
    1337            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1338              : 
    1339            0 :     if ((daemon == NULL) || (application == NULL) || (ecu == NULL))
    1340              :         return -1;
    1341              : 
    1342            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    1343              : 
    1344            0 :     if (user_list == NULL)
    1345              :         return -1;
    1346              : 
    1347            0 :     if (user_list->num_applications > 0) {
    1348            0 :         dlt_daemon_application_reset_user_handle_v2(daemon, application, verbose);
    1349              : 
    1350              :         /* Free description of application to be deleted */
    1351            0 :         if (application->application_description) {
    1352            0 :             free(application->application_description);
    1353            0 :             application->application_description = NULL;
    1354              :         }
    1355              : 
    1356              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    1357              :         if (application->trace_load_settings != NULL) {
    1358              :             free(application->trace_load_settings);
    1359              :             application->trace_load_settings = NULL;
    1360              :             application->trace_load_settings_count = 0;
    1361              :         }
    1362              : #endif
    1363            0 :         pos = (int) (application - (user_list->applications));
    1364              : 
    1365              :         /* move all applications above pos to pos */
    1366            0 :         memmove(&(user_list->applications[pos]),
    1367            0 :                 &(user_list->applications[pos + 1]),
    1368            0 :                 sizeof(DltDaemonApplication) * (size_t)((user_list->num_applications - 1) - pos));
    1369              :         //TBD: Check usage of sizeof(DltDaemonApplication) since added new ptr members
    1370              : 
    1371              :         /* Clear last application */
    1372            0 :         memset(&(user_list->applications[user_list->num_applications - 1]),
    1373              :                0,
    1374              :                sizeof(DltDaemonApplication));
    1375              :         //TBD: Check usage of sizeof(DltDaemonApplication) since added new ptr members
    1376              : 
    1377            0 :         user_list->num_applications--;
    1378              :     }
    1379              : 
    1380              :     return 0;
    1381              : }
    1382              : 
    1383           36 : DltDaemonApplication *dlt_daemon_application_find(DltDaemon *daemon,
    1384              :                                                   char *apid,
    1385              :                                                   char *ecu,
    1386              :                                                   int verbose)
    1387              : {
    1388              :     DltDaemonApplication application;
    1389              :     DltDaemonRegisteredUsers *user_list = NULL;
    1390              : 
    1391           36 :     PRINT_FUNCTION_VERBOSE(verbose);
    1392              : 
    1393           36 :     if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) ||
    1394           36 :         (apid[0] == '\0') || (ecu == NULL))
    1395              :         return (DltDaemonApplication *)NULL;
    1396              : 
    1397           36 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1398              : 
    1399           36 :     if ((user_list == NULL) || (user_list->num_applications == 0))
    1400              :         return (DltDaemonApplication *)NULL;
    1401              : 
    1402              :     /* Check, if apid is smaller than smallest apid or greater than greatest apid */
    1403           31 :     if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) ||
    1404           31 :         (memcmp(apid,
    1405           31 :                 user_list->applications[user_list->num_applications - 1].apid,
    1406              :                 DLT_ID_SIZE) > 0))
    1407              :         return (DltDaemonApplication *)NULL;
    1408              : 
    1409           31 :     dlt_set_id(application.apid, apid);
    1410           31 :     return (DltDaemonApplication *)bsearch(&application,
    1411           31 :                                            user_list->applications,
    1412           31 :                                            (size_t) user_list->num_applications,
    1413              :                                            sizeof(DltDaemonApplication),
    1414              :                                            dlt_daemon_cmp_apid);
    1415              : }
    1416              : 
    1417            0 : void dlt_daemon_application_find_v2(DltDaemon *daemon,
    1418              :                                     uint8_t apidlen,
    1419              :                                     char *apid,
    1420              :                                     uint8_t eculen,
    1421              :                                     char *ecu,
    1422              :                                     int verbose,
    1423              :                                     DltDaemonApplication **application)
    1424              : {
    1425              :     DltDaemonRegisteredUsers *user_list = NULL;
    1426            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1427              :     DltDaemonApplication search_app;
    1428              :     memset(search_app.apid2, 0, DLT_V2_ID_SIZE);
    1429              : 
    1430            0 :     if ((daemon == NULL) || (daemon->user_list == NULL) ||
    1431            0 :         (apidlen == 0) || (apid == NULL) ||
    1432            0 :         (eculen == 0) || (ecu == NULL)){
    1433              : 
    1434            0 :         *application = NULL;
    1435            0 :         return;
    1436              :         }
    1437              : 
    1438            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    1439              : 
    1440            0 :     if ((user_list == NULL) || (user_list->num_applications == 0)){
    1441            0 :         *application = NULL;
    1442            0 :         return;
    1443              :     }
    1444              : 
    1445            0 :     search_app.apid2len = apidlen;
    1446            0 :     dlt_set_id_v2(search_app.apid2, apid, apidlen);
    1447              : 
    1448              :     // Search using the temporary structure
    1449            0 :     *application = (DltDaemonApplication *)bsearch(&search_app,
    1450            0 :                                            user_list->applications,
    1451            0 :                                            (size_t) user_list->num_applications,
    1452              :                                            sizeof(DltDaemonApplication),
    1453              :                                            dlt_daemon_cmp_apid_v2);
    1454              : 
    1455            0 :     return;
    1456              : }
    1457              : 
    1458              : 
    1459            1 : int dlt_daemon_applications_load(DltDaemon *daemon, const char *filename, int verbose)
    1460              : {
    1461              :     FILE *fd;
    1462              :     ID4 apid;
    1463              :     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
    1464              :     char *ret;
    1465              :     char *pb;
    1466              : 
    1467            1 :     PRINT_FUNCTION_VERBOSE(verbose);
    1468              : 
    1469            1 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1470              :         return -1;
    1471              : 
    1472            1 :     fd = fopen(filename, "r");
    1473              : 
    1474            1 :     if (fd == NULL) {
    1475            1 :         dlt_vlog(LOG_WARNING,
    1476              :                  "%s: cannot open file %s: %s\n",
    1477              :                  __func__,
    1478              :                  filename,
    1479            1 :                  strerror(errno));
    1480              : 
    1481            1 :         return -1;
    1482              :     }
    1483              : 
    1484            0 :     while (!feof(fd)) {
    1485              :         /* Clear buf */
    1486              :         memset(buf, 0, sizeof(buf));
    1487              : 
    1488              :         /* Get line */
    1489              :         ret = fgets(buf, sizeof(buf), fd);
    1490              : 
    1491            0 :         if (NULL == ret) {
    1492              :             /* fgets always null pointer if the last byte of the file is a new line
    1493              :              * We need to check here if there was an error or was it feof.*/
    1494            0 :             if (ferror(fd)) {
    1495            0 :                 dlt_vlog(LOG_WARNING,
    1496              :                          "%s: fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
    1497              :                          __func__,
    1498            0 :                          strerror(errno));
    1499            0 :                 fclose(fd);
    1500            0 :                 return -1;
    1501              :             }
    1502            0 :             else if (feof(fd))
    1503              :             {
    1504            0 :                 fclose(fd);
    1505            0 :                 return 0;
    1506              :             }
    1507              :             else {
    1508            0 :                 dlt_vlog(LOG_WARNING,
    1509              :                          "%s: fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
    1510              :                          __func__);
    1511            0 :                 fclose(fd);
    1512            0 :                 return -1;
    1513              :             }
    1514              :         }
    1515              : 
    1516            0 :         if (strcmp(buf, "") != 0) {
    1517              :             /* Split line */
    1518            0 :             pb = strtok(buf, ":");
    1519              : 
    1520            0 :             if (pb != NULL) {
    1521            0 :                 dlt_set_id(apid, pb);
    1522            0 :                 pb = strtok(NULL, ":");
    1523              : 
    1524            0 :                 if (pb != NULL) {
    1525              :                     /* pb contains now the description */
    1526              :                     /* pid is unknown at loading time */
    1527            0 :                     if (dlt_daemon_application_add(daemon,
    1528              :                                                    apid,
    1529              :                                                    0,
    1530              :                                                    pb,
    1531              :                                                    -1,
    1532            0 :                                                    daemon->ecuid,
    1533              :                                                    verbose) == 0) {
    1534            0 :                         dlt_vlog(LOG_WARNING,
    1535              :                                  "%s: dlt_daemon_application_add failed for %4s\n",
    1536              :                                  __func__,
    1537              :                                  apid);
    1538            0 :                         fclose(fd);
    1539            0 :                         return -1;
    1540              :                     }
    1541              :                 }
    1542              :             }
    1543              :         }
    1544              :     }
    1545              : 
    1546            0 :     fclose(fd);
    1547              : 
    1548            0 :     return 0;
    1549              : }
    1550              : 
    1551            0 : int dlt_daemon_applications_save(DltDaemon *daemon, const char *filename, int verbose)
    1552              : {
    1553              :     FILE *fd;
    1554              :     int i;
    1555              : 
    1556              :     char apid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
    1557              :     DltDaemonRegisteredUsers *user_list = NULL;
    1558              : 
    1559            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1560              : 
    1561            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1562              :         return -1;
    1563              : 
    1564              :     memset(apid, 0, sizeof(apid));
    1565              : 
    1566            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1567              : 
    1568            0 :     if (user_list == NULL)
    1569              :         return -1;
    1570              : 
    1571            0 :     if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
    1572            0 :         fd = fopen(filename, "w");
    1573              : 
    1574            0 :         if (fd != NULL) {
    1575            0 :             for (i = 0; i < user_list->num_applications; i++) {
    1576            0 :                 dlt_set_id(apid, user_list->applications[i].apid);
    1577              : 
    1578            0 :                 if ((user_list->applications[i].application_description) &&
    1579            0 :                     (user_list->applications[i].application_description[0] != '\0'))
    1580              :                     fprintf(fd,
    1581              :                             "%s:%s:\n",
    1582              :                             apid,
    1583              :                             user_list->applications[i].application_description);
    1584              :                 else
    1585              :                     fprintf(fd, "%s::\n", apid);
    1586              :             }
    1587              : 
    1588            0 :             fclose(fd);
    1589              :         }
    1590              :         else {
    1591            0 :             dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n",
    1592              :                      __func__,
    1593              :                      filename);
    1594              :         }
    1595              :     }
    1596              : 
    1597              :     return 0;
    1598              : }
    1599            0 : int dlt_daemon_applications_save_v2(DltDaemon *daemon, const char *filename, int verbose)
    1600              : {
    1601              :     FILE *fd;
    1602              :     int i;
    1603              : 
    1604              :     char apid[DLT_V2_ID_SIZE];
    1605              :     DltDaemonRegisteredUsers *user_list = NULL;
    1606              : 
    1607            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1608              : 
    1609            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    1610              :         return -1;
    1611              : 
    1612            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    1613              : 
    1614            0 :     if (user_list == NULL)
    1615              :         return -1;
    1616              : 
    1617            0 :     if ((user_list->applications != NULL) && (user_list->num_applications > 0)) {
    1618            0 :         fd = fopen(filename, "w");
    1619              : 
    1620            0 :         if (fd != NULL) {
    1621            0 :             for (i = 0; i < user_list->num_applications; i++) {
    1622            0 :                 dlt_set_id_v2(apid, user_list->applications[i].apid2, user_list->applications[i].apid2len);
    1623              : 
    1624            0 :                 if ((user_list->applications[i].application_description) &&
    1625            0 :                     (user_list->applications[i].application_description[0] != '\0'))
    1626              :                     fprintf(fd,
    1627              :                             "%s:%s:\n",
    1628              :                             apid,
    1629              :                             user_list->applications[i].application_description);
    1630              :                 else
    1631              :                     fprintf(fd, "%s::\n", apid);
    1632              :             }
    1633              : 
    1634            0 :             fclose(fd);
    1635              :         }
    1636              :         else {
    1637            0 :             dlt_vlog(LOG_ERR, "%s: open %s failed! No application information stored.\n",
    1638              :                      __func__,
    1639              :                      filename);
    1640              :         }
    1641              :     }
    1642              : 
    1643              :     return 0;
    1644              : }
    1645              : 
    1646           15 : DltDaemonContext *dlt_daemon_context_add(DltDaemon *daemon,
    1647              :                                          char *apid,
    1648              :                                          char *ctid,
    1649              :                                          int8_t log_level,
    1650              :                                          int8_t trace_status,
    1651              :                                          int log_level_pos,
    1652              :                                          int user_handle,
    1653              :                                          char *description,
    1654              :                                          char *ecu,
    1655              :                                          int verbose)
    1656              : {
    1657              :     DltDaemonApplication *application;
    1658              :     DltDaemonContext *context;
    1659              :     DltDaemonContext *old;
    1660              :     int new_context = 0;
    1661              :     DltDaemonRegisteredUsers *user_list = NULL;
    1662              : 
    1663           15 :     PRINT_FUNCTION_VERBOSE(verbose);
    1664              : 
    1665           15 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
    1666           15 :         (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
    1667              :         return (DltDaemonContext *)NULL;
    1668              : 
    1669           15 :     if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
    1670              :         return (DltDaemonContext *)NULL;
    1671              : 
    1672           15 :     if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
    1673              :         return (DltDaemonContext *)NULL;
    1674              : 
    1675           15 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1676              : 
    1677           15 :     if (user_list == NULL)
    1678              :         return (DltDaemonContext *)NULL;
    1679              : 
    1680           15 :     if (user_list->contexts == NULL) {
    1681            4 :         user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1682              : 
    1683            4 :         if (user_list->contexts == NULL)
    1684              :             return (DltDaemonContext *)NULL;
    1685              :     }
    1686              : 
    1687              :     /* Check if application [apid] is available */
    1688           15 :     application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
    1689              : 
    1690           15 :     if (application == NULL)
    1691              :         return (DltDaemonContext *)NULL;
    1692              : 
    1693              :     /* Check if context [apid, ctid] is already available */
    1694           15 :     context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
    1695              : 
    1696           15 :     if (context == NULL) {
    1697           15 :         user_list->num_contexts += 1;
    1698              : 
    1699           15 :         if (user_list->num_contexts != 0) {
    1700           15 :             if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
    1701              :                 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
    1702            0 :                 old = user_list->contexts;
    1703            0 :                 user_list->contexts = (DltDaemonContext *)calloc(1, (size_t) sizeof(DltDaemonContext) *
    1704            0 :                                                                 ((size_t)(user_list->num_contexts /
    1705              :                                                                 DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1) *
    1706              :                                                                 (size_t)DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1707              : 
    1708            0 :                 if (user_list->contexts == NULL) {
    1709            0 :                     user_list->contexts = old;
    1710            0 :                     user_list->num_contexts -= 1;
    1711            0 :                     return (DltDaemonContext *)NULL;
    1712              :                 }
    1713              : 
    1714            0 :                 memcpy(user_list->contexts,
    1715              :                        old,
    1716            0 :                        (size_t) sizeof(DltDaemonContext) * (size_t)user_list->num_contexts);
    1717            0 :                 free(old);
    1718              :             }
    1719              :         }
    1720              : 
    1721           15 :         context = &(user_list->contexts[(size_t)(user_list->num_contexts - 1)]);
    1722              :         memset(context, 0, sizeof(DltDaemonContext));
    1723              : 
    1724           15 :         dlt_set_id(context->apid, apid);
    1725           15 :         dlt_set_id(context->ctid, ctid);
    1726              : 
    1727              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    1728              :         context->trace_load_settings = NULL;
    1729              : #endif
    1730              : 
    1731           15 :         application->num_contexts++;
    1732              :         new_context = 1;
    1733              :     }
    1734              : 
    1735              :     /* Set context description */
    1736           15 :     if (context->context_description) {
    1737            0 :         free(context->context_description);
    1738            0 :         context->context_description = NULL;
    1739              :     }
    1740              : 
    1741           15 :     if (description != NULL) {
    1742           15 :         context->context_description = malloc(strlen(description) + 1);
    1743              : 
    1744           15 :         if (context->context_description) {
    1745           15 :             memcpy(context->context_description, description, strlen(description) + 1);
    1746              :         }
    1747              :     }
    1748              : 
    1749              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1750              :     /* configure initial log level */
    1751              :     DltDaemonContextLogSettings *settings = NULL;
    1752              :     settings = dlt_daemon_find_configured_app_id_ctx_id_settings(
    1753              :             daemon, context->apid, ctid);
    1754              : 
    1755              :     if (settings != NULL) {
    1756              :         /* set log level */
    1757              :         log_level = settings->log_level;
    1758              : 
    1759              :         DltDaemonContextLogSettings *ct_settings = NULL;
    1760              :         ct_settings = dlt_daemon_find_app_log_level_config(application, ctid);
    1761              : 
    1762              :         /* ct_settings != null: context and app id combination already exists */
    1763              :         if (ct_settings == NULL) {
    1764              :           /* copy the configuration into the DltDaemonApplication for faster access later */
    1765              :           DltDaemonContextLogSettings *tmp =
    1766              :               realloc(application->context_log_level_settings,
    1767              :                       (++application->num_context_log_level_settings) *
    1768              :                           sizeof(DltDaemonContextLogSettings));
    1769              :           application->context_log_level_settings = tmp;
    1770              : 
    1771              :           ct_settings =
    1772              :               &application->context_log_level_settings[application->num_context_log_level_settings - 1];
    1773              :           memcpy(ct_settings, settings, sizeof(DltDaemonContextLogSettings));
    1774              :           memcpy(ct_settings->ctid, ctid, DLT_ID_SIZE);
    1775              :       }
    1776              :     }
    1777              : #endif
    1778              : 
    1779           15 :     if ((strncmp(daemon->ecuid, ecu, DLT_ID_SIZE) == 0) && (daemon->force_ll_ts)) {
    1780              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1781              :         if (log_level > daemon->default_log_level && settings == NULL)
    1782              : #else
    1783            0 :         if (log_level > daemon->default_log_level)
    1784              : #endif
    1785              :             log_level = daemon->default_log_level;
    1786              : 
    1787            0 :         if (trace_status > daemon->default_trace_status)
    1788              :             trace_status = daemon->default_trace_status;
    1789              : 
    1790            0 :         dlt_vlog(LOG_NOTICE,
    1791              :             "Adapting ll_ts for context: %.4s:%.4s with %i %i\n",
    1792              :             apid,
    1793              :             ctid,
    1794              :             log_level,
    1795              :             trace_status);
    1796              :     }
    1797              : 
    1798              :     /* Store log level and trace status,
    1799              :      * if this is a new context, or
    1800              :      * if this is an old context and the runtime cfg was not loaded */
    1801           15 :     if ((new_context == 1) ||
    1802            0 :         ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
    1803           15 :         context->log_level = log_level;
    1804           15 :         context->trace_status = trace_status;
    1805              :     }
    1806              : 
    1807           15 :     context->log_level_pos = log_level_pos;
    1808           15 :     context->user_handle = user_handle;
    1809              : 
    1810              :     /* In case a context is loaded from runtime config file,
    1811              :      * the user_handle is 0 and we mark that context as predefined.
    1812              :      */
    1813           15 :     if (context->user_handle == 0)
    1814            0 :         context->predefined = true;
    1815              :     else
    1816           15 :         context->predefined = false;
    1817              : 
    1818              :     /* Sort */
    1819           15 :     if (new_context) {
    1820           15 :         qsort(user_list->contexts,
    1821           15 :               (size_t) user_list->num_contexts,
    1822              :               sizeof(DltDaemonContext),
    1823              :               dlt_daemon_cmp_apid_ctid);
    1824              : 
    1825              :         /* Find new position of context with apid, ctid */
    1826           15 :         context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
    1827              :     }
    1828              : 
    1829              :     return context;
    1830              : }
    1831              : 
    1832            0 : DltDaemonContext *dlt_daemon_context_add_v2(DltDaemon *daemon,
    1833              :                                          uint8_t apidlen,
    1834              :                                          char *apid,
    1835              :                                          uint8_t ctidlen,
    1836              :                                          char *ctid,
    1837              :                                          int8_t log_level,
    1838              :                                          int8_t trace_status,
    1839              :                                          int log_level_pos,
    1840              :                                          int user_handle,
    1841              :                                          char *description,
    1842              :                                          uint8_t eculen,
    1843              :                                          char *ecu,
    1844              :                                          int verbose)
    1845              : {
    1846              :     DltDaemonContext *context;
    1847              :     DltDaemonContext *old;
    1848              :     int new_context = 0;
    1849              :     DltDaemonRegisteredUsers *user_list = NULL;
    1850            0 :     DltDaemonApplication *application = NULL;
    1851              : 
    1852            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1853              : 
    1854            0 :     if ((daemon == NULL) || (apid == NULL) ||
    1855            0 :         (ctid == NULL) || (ecu == NULL) || (apidlen == 0) || (ctidlen == 0))
    1856              :         return (DltDaemonContext *)NULL;
    1857              : 
    1858            0 :     if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
    1859              :         return (DltDaemonContext *)NULL;
    1860              : 
    1861            0 :     if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
    1862              :         return (DltDaemonContext *)NULL;
    1863              : 
    1864            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    1865              : 
    1866            0 :     if (user_list == NULL)
    1867              :         return (DltDaemonContext *)NULL;
    1868              : 
    1869            0 :     if (user_list->contexts == NULL) {
    1870            0 :         user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1871              : 
    1872            0 :         if (user_list->contexts == NULL)
    1873              :             return (DltDaemonContext *)NULL;
    1874              :     }
    1875              : 
    1876              :     /* Check if application [apid] is available */
    1877            0 :     dlt_daemon_application_find_v2(daemon, apidlen, apid, eculen, ecu, verbose, &application);
    1878              : 
    1879              : 
    1880            0 :     if (application == NULL){
    1881              :         return (DltDaemonContext *)NULL;
    1882              :     }
    1883              : 
    1884              :     /* Check if context [apid, ctid] is already available */
    1885            0 :     context = dlt_daemon_context_find_v2(daemon, apidlen, apid, ctidlen, ctid, eculen, ecu, verbose);
    1886              : 
    1887            0 :     if (context == NULL) {
    1888            0 :         user_list->num_contexts += 1;
    1889            0 :         if (user_list->num_contexts != 0) {
    1890            0 :             if ((user_list->num_contexts % DLT_DAEMON_CONTEXT_ALLOC_SIZE) == 0) {
    1891              :                 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
    1892            0 :                 old = user_list->contexts;
    1893            0 :                 user_list->contexts = (DltDaemonContext *)calloc(1, (size_t) sizeof(DltDaemonContext) *
    1894            0 :                                                                  (((size_t)user_list->num_contexts /
    1895              :                                                                    DLT_DAEMON_CONTEXT_ALLOC_SIZE) + 1) *
    1896              :                                                                  DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1897              : 
    1898            0 :                 if (user_list->contexts == NULL) {
    1899            0 :                     user_list->contexts = old;
    1900            0 :                     user_list->num_contexts -= 1;
    1901            0 :                     return (DltDaemonContext *)NULL;
    1902              :                 }
    1903              : 
    1904            0 :                 memcpy(user_list->contexts,
    1905              :                        old,
    1906              :                        (size_t) sizeof(DltDaemonContext) * (size_t)user_list->num_contexts);
    1907            0 :                 free(old);
    1908              :             }
    1909              :         }
    1910            0 :         context = &(user_list->contexts[user_list->num_contexts - 1]);
    1911              :         memset(context, 0, sizeof(DltDaemonContext));
    1912              : 
    1913            0 :         context->apid2 = (char *)malloc(DLT_V2_ID_SIZE * sizeof(char));
    1914            0 :         if (context->apid2 == NULL) {
    1915              :             return (DltDaemonContext *)NULL;
    1916              :         }
    1917            0 :         dlt_set_id_v2(context->apid2, apid, apidlen);
    1918            0 :         context->apid2len = apidlen;
    1919            0 :         context->ctid2 = (char *)malloc(DLT_V2_ID_SIZE * sizeof(char));
    1920            0 :         if (context->ctid2 == NULL) {
    1921            0 :             free(context->apid2);
    1922            0 :             context->apid2 = NULL;
    1923            0 :             return (DltDaemonContext *)NULL;
    1924              :         }
    1925            0 :         dlt_set_id_v2(context->ctid2, ctid, ctidlen);
    1926            0 :         context->ctid2len = ctidlen;
    1927              : 
    1928            0 :         application->num_contexts++;
    1929              :         new_context = 1;
    1930              :     }
    1931              : 
    1932              :     /* Set context description */
    1933            0 :     if (context->context_description) {
    1934            0 :         free(context->context_description);
    1935            0 :         context->context_description = NULL;
    1936              :     }
    1937              : 
    1938            0 :     if (description != NULL) {
    1939            0 :         context->context_description = malloc(strlen(description) + 1);
    1940              : 
    1941            0 :         if (context->context_description) {
    1942            0 :             memcpy(context->context_description, description, strlen(description) + 1);
    1943              :         }
    1944              :     }
    1945              : 
    1946              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1947              :     /* configure initial log level */
    1948              :     DltDaemonContextLogSettings *settings = NULL;
    1949              :     settings = dlt_daemon_find_configured_app_id_ctx_id_settings(
    1950              :             daemon, context->apid, ctid);
    1951              : 
    1952              :     if (settings != NULL) {
    1953              :         /* set log level */
    1954              :         log_level = settings->log_level;
    1955              : 
    1956              :         DltDaemonContextLogSettings *ct_settings = NULL;
    1957              :         ct_settings = dlt_daemon_find_app_log_level_config(application, ctid);
    1958              : 
    1959              :         /* ct_settings != null: context and app id combination already exists */
    1960              :         if (ct_settings == NULL) {
    1961              :           /* copy the configuration into the DltDaemonApplication for faster access later */
    1962              :           DltDaemonContextLogSettings *tmp =
    1963              :               realloc(application->context_log_level_settings,
    1964              :                       (++application->num_context_log_level_settings) *
    1965              :                           sizeof(DltDaemonContextLogSettings));
    1966              :           application->context_log_level_settings = tmp;
    1967              : 
    1968              :           ct_settings =
    1969              :               &application->context_log_level_settings[application->num_context_log_level_settings - 1];
    1970              :           memcpy(ct_settings, settings, sizeof(DltDaemonContextLogSettings));
    1971              :           memcpy(ct_settings->ctid, ctid, DLT_ID_SIZE);
    1972              :       }
    1973              :     }
    1974              : #endif
    1975              : 
    1976            0 :     if ((strncmp(daemon->ecuid2, ecu, eculen) == 0) && (daemon->force_ll_ts)) {
    1977              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    1978              :         if (log_level > daemon->default_log_level && settings == NULL)
    1979              : #else
    1980            0 :         if (log_level > daemon->default_log_level)
    1981              : #endif
    1982              :             log_level = daemon->default_log_level;
    1983              : 
    1984            0 :         if (trace_status > daemon->default_trace_status)
    1985              :             trace_status = daemon->default_trace_status;
    1986              : 
    1987            0 :         dlt_vlog(LOG_NOTICE,
    1988              :             "Adapting ll_ts for context: %s:%s with %i %i\n",
    1989              :             apid,
    1990              :             ctid,
    1991              :             log_level,
    1992              :             trace_status); //TBD: adjust length %.6s according to apidlen and ctidlen
    1993              :     }
    1994              : 
    1995              :     /* Store log level and trace status,
    1996              :      * if this is a new context, or
    1997              :      * if this is an old context and the runtime cfg was not loaded */
    1998            0 :     if ((new_context == 1) ||
    1999            0 :         ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
    2000            0 :         context->log_level = log_level;
    2001            0 :         context->trace_status = trace_status;
    2002              :     }
    2003              : 
    2004            0 :     context->log_level_pos = log_level_pos;
    2005            0 :     context->user_handle = user_handle;
    2006              : 
    2007              :     /* In case a context is loaded from runtime config file,
    2008              :      * the user_handle is 0 and we mark that context as predefined.
    2009              :      */
    2010            0 :     if (context->user_handle == 0)
    2011            0 :         context->predefined = true;
    2012              :     else
    2013            0 :         context->predefined = false;
    2014              : 
    2015              :     /* Sort */
    2016            0 :     if (new_context) {
    2017            0 :         qsort(user_list->contexts,
    2018            0 :               (size_t) user_list->num_contexts,
    2019              :               sizeof(DltDaemonContext),
    2020              :               dlt_daemon_cmp_apid_ctid_v2);
    2021              : 
    2022              :         /* Find new position of context with apid, ctid */
    2023            0 :         context = dlt_daemon_context_find_v2(daemon, apidlen, apid, ctidlen, ctid, eculen, ecu, verbose);
    2024              :     }
    2025              :     return context;
    2026              : }
    2027              : 
    2028              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    2029              : static void dlt_daemon_free_context_log_settings(
    2030              :     DltDaemonApplication *application,
    2031              :     DltDaemonContext *context)
    2032              : {
    2033              :     DltDaemonContextLogSettings *ct_settings;
    2034              :     int i;
    2035              :     int skipped = 0;
    2036              : 
    2037              :     ct_settings = dlt_daemon_find_app_log_level_config(application, context->ctid);
    2038              :     if (ct_settings == NULL) {
    2039              :         return;
    2040              :     }
    2041              : 
    2042              :     /* move all data forward */
    2043              :     for (i = 0; i < application->num_context_log_level_settings; ++i) {
    2044              :         /* skip given context to delete it */
    2045              :         if (i + skipped < application->num_context_log_level_settings &&
    2046              :             strncmp(application->context_log_level_settings[i+skipped].ctid, context->ctid, DLT_ID_SIZE) == 0) {
    2047              :             ++skipped;
    2048              :             continue;
    2049              :         }
    2050              : 
    2051              :         memcpy(&application->context_log_level_settings[i-skipped],
    2052              :                 &application->context_log_level_settings[i],
    2053              :                 sizeof(DltDaemonContextLogSettings));
    2054              :     }
    2055              : 
    2056              :     application->num_context_log_level_settings -= skipped;
    2057              : 
    2058              :     /* if size is equal to zero, and ptr is not NULL, then realloc is equivalent to free(ptr) */
    2059              :     application->context_log_level_settings = realloc(application->context_log_level_settings,
    2060              :             sizeof(DltDaemonContextLogSettings) * (application->num_context_log_level_settings));
    2061              : 
    2062              : }
    2063              : #endif
    2064              : 
    2065            0 : int dlt_daemon_context_del(DltDaemon *daemon,
    2066              :                            DltDaemonContext *context,
    2067              :                            char *ecu,
    2068              :                            int verbose)
    2069              : {
    2070              :     int pos;
    2071              :     DltDaemonApplication *application;
    2072              :     DltDaemonRegisteredUsers *user_list = NULL;
    2073              : 
    2074            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2075              : 
    2076            0 :     if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
    2077              :         return -1;
    2078              : 
    2079            0 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    2080              : 
    2081            0 :     if (user_list == NULL)
    2082              :         return -1;
    2083              : 
    2084            0 :     if (user_list->num_contexts > 0) {
    2085            0 :         application = dlt_daemon_application_find(daemon, context->apid, ecu, verbose);
    2086              : 
    2087              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    2088              :         dlt_daemon_free_context_log_settings(application, context);
    2089              : #endif
    2090              :         /* Free description of context to be deleted */
    2091            0 :         if (context->context_description) {
    2092            0 :             free(context->context_description);
    2093            0 :             context->context_description = NULL;
    2094              :         }
    2095              : 
    2096            0 :         pos = (int) (context - (user_list->contexts));
    2097              : 
    2098              :         /* move all contexts above pos to pos */
    2099            0 :         memmove(&(user_list->contexts[pos]),
    2100            0 :                 &(user_list->contexts[pos + 1]),
    2101            0 :                 (size_t)sizeof(DltDaemonContext) * (size_t)((user_list->num_contexts - 1) - pos));
    2102              : 
    2103              :         /* Clear last context */
    2104            0 :         memset(&(user_list->contexts[(size_t)(user_list->num_contexts - 1)]),
    2105              :                0,
    2106              :                (size_t)sizeof(DltDaemonContext));
    2107              : 
    2108            0 :         user_list->num_contexts--;
    2109              : 
    2110              :         /* Check if application [apid] is available */
    2111            0 :         if (application != NULL)
    2112            0 :             application->num_contexts--;
    2113              :     }
    2114              : 
    2115              :     return 0;
    2116              : }
    2117              : 
    2118            0 : int dlt_daemon_context_del_v2(DltDaemon *daemon,
    2119              :                            DltDaemonContext *context,
    2120              :                            uint8_t eculen,
    2121              :                            char *ecu,
    2122              :                            int verbose)
    2123              : {
    2124              :     int pos;
    2125              :     DltDaemonApplication *application;
    2126              :     DltDaemonRegisteredUsers *user_list = NULL;
    2127              : 
    2128            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2129              : 
    2130            0 :     if ((daemon == NULL) || (context == NULL) || (ecu == NULL))
    2131              :         return -1;
    2132              : 
    2133            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    2134              : 
    2135            0 :     if (user_list == NULL)
    2136              :         return -1;
    2137              : 
    2138            0 :     if (user_list->num_contexts > 0) {
    2139            0 :         dlt_daemon_application_find_v2(daemon, context->apid2len, context->apid2, eculen, ecu, verbose, &application);
    2140              : 
    2141              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    2142              :         dlt_daemon_free_context_log_settings(application, context);
    2143              : #endif
    2144              :         /* Free description of context to be deleted */
    2145            0 :         if (context->context_description) {
    2146            0 :             free(context->context_description);
    2147            0 :             context->context_description = NULL;
    2148              :         }
    2149              : 
    2150            0 :         pos = (int) (context - (user_list->contexts));
    2151              : 
    2152              :         /* move all contexts above pos to pos */
    2153            0 :         memmove(&(user_list->contexts[pos]),
    2154            0 :                 &(user_list->contexts[pos + 1]),
    2155            0 :                 (size_t)sizeof(DltDaemonContext) * (size_t)((user_list->num_contexts - 1) - pos));
    2156              : 
    2157              :         /* Clear last context */
    2158            0 :         memset(&(user_list->contexts[user_list->num_contexts - 1]),
    2159              :                0,
    2160              :                sizeof(DltDaemonContext));
    2161              : 
    2162            0 :         user_list->num_contexts--;
    2163              : 
    2164              :         /* Check if application [apid] is available */
    2165            0 :         if (application != NULL)
    2166            0 :             application->num_contexts--;
    2167              :     }
    2168              : 
    2169              :     return 0;
    2170              : }
    2171              : 
    2172           47 : DltDaemonContext *dlt_daemon_context_find(DltDaemon *daemon,
    2173              :                                           char *apid,
    2174              :                                           char *ctid,
    2175              :                                           char *ecu,
    2176              :                                           int verbose)
    2177              : {
    2178              :     DltDaemonContext context;
    2179              :     DltDaemonRegisteredUsers *user_list = NULL;
    2180              : 
    2181           47 :     PRINT_FUNCTION_VERBOSE(verbose);
    2182              : 
    2183           47 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
    2184           47 :         (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
    2185              :         return (DltDaemonContext *)NULL;
    2186              : 
    2187           47 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    2188              : 
    2189           47 :     if ((user_list == NULL) || (user_list->num_contexts == 0))
    2190              :         return (DltDaemonContext *)NULL;
    2191              : 
    2192              :     /* Check, if apid is smaller than smallest apid or greater than greatest apid */
    2193           29 :     if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) ||
    2194           29 :         (memcmp(apid,
    2195           29 :                 user_list->contexts[user_list->num_contexts - 1].apid,
    2196              :                 DLT_ID_SIZE) > 0))
    2197              :         return (DltDaemonContext *)NULL;
    2198              : 
    2199           29 :     dlt_set_id(context.apid, apid);
    2200           29 :     dlt_set_id(context.ctid, ctid);
    2201              : 
    2202           29 :     return (DltDaemonContext *)bsearch(&context,
    2203           29 :                                        user_list->contexts,
    2204           29 :                                        (size_t) user_list->num_contexts,
    2205              :                                        sizeof(DltDaemonContext),
    2206              :                                        dlt_daemon_cmp_apid_ctid);
    2207              : }
    2208              : 
    2209            0 : DltDaemonContext *dlt_daemon_context_find_v2(DltDaemon *daemon,
    2210              :                                              uint8_t apidlen,
    2211              :                                              char *apid,
    2212              :                                              uint8_t ctidlen,
    2213              :                                              char *ctid,
    2214              :                                              uint8_t eculen,
    2215              :                                              char *ecu,
    2216              :                                              int verbose)
    2217              : {
    2218              :     DltDaemonContext context;
    2219              :     DltDaemonRegisteredUsers *user_list = NULL;
    2220            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2221              : 
    2222            0 :     if ((daemon == NULL) || (apidlen == 0) || (apid == NULL) ||
    2223            0 :         (ctidlen == 0) || (ctid == NULL) || (eculen == 0) || (ecu == NULL))
    2224              :         return (DltDaemonContext *)NULL;
    2225              : 
    2226            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    2227              : 
    2228            0 :     if ((user_list == NULL) || (user_list->num_contexts == 0))
    2229              :         return (DltDaemonContext *)NULL;
    2230              : 
    2231            0 :     context.apid2 = (char *)malloc(DLT_V2_ID_SIZE * sizeof(char));
    2232            0 :     if (context.apid2 == NULL) {
    2233              :         return (DltDaemonContext *)NULL;
    2234              :     }
    2235            0 :     dlt_set_id_v2(context.apid2, apid, apidlen);
    2236            0 :     context.apid2len = apidlen;
    2237            0 :     context.ctid2 = (char *)malloc(DLT_V2_ID_SIZE * sizeof(char));
    2238            0 :     if (context.ctid2 == NULL) {
    2239            0 :         free(context.apid2);
    2240            0 :         return (DltDaemonContext *)NULL;
    2241              :     }
    2242            0 :     dlt_set_id_v2(context.ctid2, ctid, ctidlen);
    2243            0 :     context.ctid2len = ctidlen;
    2244              : 
    2245            0 :     DltDaemonContext *result = (DltDaemonContext *)bsearch(&context,
    2246            0 :                                        user_list->contexts,
    2247            0 :                                        (size_t) user_list->num_contexts,
    2248              :                                        sizeof(DltDaemonContext),
    2249              :                                        dlt_daemon_cmp_apid_ctid_v2);
    2250              : 
    2251              :     // Free temporary allocated memory
    2252            0 :     free(context.apid2);
    2253            0 :     free(context.ctid2);
    2254              : 
    2255            0 :     return result;
    2256              : }
    2257              : 
    2258            5 : int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,
    2259              :                                       char *ecu,
    2260              :                                       int fd,
    2261              :                                       int verbose)
    2262              : {
    2263              :     int i;
    2264              :     DltDaemonRegisteredUsers *user_list = NULL;
    2265              : 
    2266            5 :     PRINT_FUNCTION_VERBOSE(verbose);
    2267              : 
    2268            5 :     if ((daemon == NULL) || (ecu == NULL))
    2269              :         return -1;
    2270              : 
    2271            5 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    2272              : 
    2273            5 :     if (user_list != NULL) {
    2274           29 :         for (i = 0; i < user_list->num_contexts; i++)
    2275           24 :             if (user_list->contexts[i].user_handle == fd)
    2276            0 :                 user_list->contexts[i].user_handle = DLT_FD_INIT;
    2277              : 
    2278              :         return 0;
    2279              :     }
    2280              : 
    2281              :     return -1;
    2282              : }
    2283              : 
    2284            0 : int dlt_daemon_contexts_invalidate_fd_v2(DltDaemon *daemon,
    2285              :                                          char *ecu,
    2286              :                                          int fd,
    2287              :                                          int verbose)
    2288              : {
    2289              :     int i;
    2290              :     DltDaemonRegisteredUsers *user_list = NULL;
    2291              : 
    2292            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2293              : 
    2294            0 :     if ((daemon == NULL) || (ecu == NULL))
    2295              :         return -1;
    2296            0 :     uint8_t eculen = (uint8_t)strlen(ecu);
    2297            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, eculen, ecu, verbose);
    2298              : 
    2299            0 :     if (user_list != NULL) {
    2300            0 :         for (i = 0; i < user_list->num_contexts; i++)
    2301            0 :             if (user_list->contexts[i].user_handle == fd)
    2302            0 :                 user_list->contexts[i].user_handle = DLT_FD_INIT;
    2303              : 
    2304              :         return 0;
    2305              :     }
    2306              : 
    2307              :     return -1;
    2308              : }
    2309              : 
    2310            1 : int dlt_daemon_contexts_clear(DltDaemon *daemon, char *ecu, int verbose)
    2311              : {
    2312              :     int i;
    2313              :     DltDaemonRegisteredUsers *users = NULL;
    2314              : 
    2315            1 :     PRINT_FUNCTION_VERBOSE(verbose);
    2316              : 
    2317            1 :     if ((daemon == NULL) || (ecu == NULL))
    2318              :         return DLT_RETURN_WRONG_PARAMETER;
    2319              : 
    2320            1 :     users = dlt_daemon_find_users_list(daemon, ecu, verbose);
    2321              : 
    2322            1 :     if (users == NULL)
    2323              :         return DLT_RETURN_ERROR;
    2324              : 
    2325           13 :     for (i = 0; i < users->num_contexts; i++) {
    2326           12 :         if (users->contexts[i].context_description != NULL) {
    2327           12 :             free(users->contexts[i].context_description);
    2328           12 :             users->contexts[i].context_description = NULL;
    2329              :         }
    2330           12 :         if (users->contexts[i].apid2 != NULL) {
    2331            0 :             free(users->contexts[i].apid2);
    2332            0 :             users->contexts[i].apid2 = NULL;
    2333              :         }
    2334           12 :         if (users->contexts[i].ctid2 != NULL) {
    2335            0 :             free(users->contexts[i].ctid2);
    2336            0 :             users->contexts[i].ctid2 = NULL;
    2337              :         }
    2338              :     }
    2339              : 
    2340            1 :     if (users->contexts) {
    2341            1 :         free(users->contexts);
    2342            1 :         users->contexts = NULL;
    2343              :     }
    2344              : 
    2345            2 :     for (i = 0; i < users->num_applications; i++)
    2346            1 :         users->applications[i].num_contexts = 0;
    2347              : 
    2348            1 :     users->num_contexts = 0;
    2349              : 
    2350            1 :     return 0;
    2351              : }
    2352              : 
    2353            0 : int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose)
    2354              : {
    2355              :     FILE *fd;
    2356              :     ID4 apid, ctid;
    2357              :     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
    2358              :     char *ret;
    2359              :     char *pb;
    2360              :     int ll, ts;
    2361              : 
    2362            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2363              : 
    2364            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2365              :         return -1;
    2366              : 
    2367            0 :     fd = fopen(filename, "r");
    2368              : 
    2369            0 :     if (fd == NULL) {
    2370            0 :         dlt_vlog(LOG_WARNING,
    2371              :                  "DLT runtime-context load, cannot open file %s: %s\n",
    2372              :                  filename,
    2373            0 :                  strerror(errno));
    2374              : 
    2375            0 :         return -1;
    2376              :     }
    2377              : 
    2378            0 :     while (!feof(fd)) {
    2379              :         /* Clear buf */
    2380              :         memset(buf, 0, sizeof(buf));
    2381              : 
    2382              :         /* Get line */
    2383              :         ret = fgets(buf, sizeof(buf), fd);
    2384              : 
    2385            0 :         if (NULL == ret) {
    2386              :             /* fgets always returns null pointer if the last byte of the file is a new line.
    2387              :              * We need to check here if there was an error or was it feof.*/
    2388            0 :             if (ferror(fd)) {
    2389            0 :                 dlt_vlog(LOG_WARNING,
    2390              :                          "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
    2391              :                          __func__,
    2392            0 :                          strerror(errno));
    2393            0 :                 fclose(fd);
    2394            0 :                 return -1;
    2395              :             }
    2396            0 :             else if (feof(fd))
    2397              :             {
    2398            0 :                 fclose(fd);
    2399            0 :                 return 0;
    2400              :             }
    2401              :             else {
    2402            0 :                 dlt_vlog(LOG_WARNING,
    2403              :                          "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
    2404              :                          __func__);
    2405            0 :                 fclose(fd);
    2406            0 :                 return -1;
    2407              :             }
    2408              :         }
    2409              : 
    2410            0 :         if (strcmp(buf, "") != 0) {
    2411              :             /* Split line */
    2412            0 :             pb = strtok(buf, ":");
    2413              : 
    2414            0 :             if (pb != NULL) {
    2415            0 :                 dlt_set_id(apid, pb);
    2416            0 :                 pb = strtok(NULL, ":");
    2417              : 
    2418            0 :                 if (pb != NULL) {
    2419            0 :                     dlt_set_id(ctid, pb);
    2420            0 :                     pb = strtok(NULL, ":");
    2421              : 
    2422            0 :                     if (pb != NULL) {
    2423            0 :                         sscanf(pb, "%d", &ll);
    2424            0 :                         pb = strtok(NULL, ":");
    2425              : 
    2426            0 :                         if (pb != NULL) {
    2427            0 :                             sscanf(pb, "%d", &ts);
    2428            0 :                             pb = strtok(NULL, ":");
    2429              : 
    2430            0 :                             if (pb != NULL) {
    2431              :                                 /* pb contains now the description */
    2432              : 
    2433              :                                 /* log_level_pos, and user_handle are unknown at loading time */
    2434            0 :                                 if (dlt_daemon_context_add(daemon,
    2435              :                                                            apid,
    2436              :                                                            ctid,
    2437            0 :                                                            (int8_t)ll,
    2438            0 :                                                            (int8_t)ts,
    2439              :                                                            0,
    2440              :                                                            0,
    2441              :                                                            pb,
    2442            0 :                                                            daemon->ecuid,
    2443              :                                                            verbose) == NULL) {
    2444            0 :                                     dlt_vlog(LOG_WARNING,
    2445              :                                              "%s dlt_daemon_context_add failed\n",
    2446              :                                              __func__);
    2447            0 :                                     fclose(fd);
    2448            0 :                                     return -1;
    2449              :                                 }
    2450              :                             }
    2451              :                         }
    2452              :                     }
    2453              :                 }
    2454              :             }
    2455              :         }
    2456              :     }
    2457              : 
    2458            0 :     fclose(fd);
    2459              : 
    2460            0 :     return 0;
    2461              : }
    2462              : 
    2463            0 : int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
    2464              : {
    2465              :     FILE *fd;
    2466              :     int i;
    2467              : 
    2468              :     char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
    2469              :     DltDaemonRegisteredUsers *user_list = NULL;
    2470              : 
    2471            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2472              : 
    2473            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2474              :         return -1;
    2475              : 
    2476            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    2477              : 
    2478            0 :     if (user_list == NULL)
    2479              :         return -1;
    2480              : 
    2481              :     memset(apid, 0, sizeof(apid));
    2482              :     memset(ctid, 0, sizeof(ctid));
    2483              : 
    2484            0 :     if ((user_list->contexts) && (user_list->num_contexts > 0)) {
    2485            0 :         fd = fopen(filename, "w");
    2486              : 
    2487            0 :         if (fd != NULL) {
    2488            0 :             for (i = 0; i < user_list->num_contexts; i++) {
    2489            0 :                 dlt_set_id(apid, user_list->contexts[i].apid);
    2490            0 :                 dlt_set_id(ctid, user_list->contexts[i].ctid);
    2491              : 
    2492            0 :                 if ((user_list->contexts[i].context_description) &&
    2493            0 :                     (user_list->contexts[i].context_description[0] != '\0'))
    2494            0 :                     fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
    2495            0 :                             (int)(user_list->contexts[i].log_level),
    2496            0 :                             (int)(user_list->contexts[i].trace_status),
    2497              :                             user_list->contexts[i].context_description);
    2498              :                 else
    2499            0 :                     fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
    2500            0 :                             (int)(user_list->contexts[i].log_level),
    2501            0 :                             (int)(user_list->contexts[i].trace_status));
    2502              :             }
    2503              : 
    2504            0 :             fclose(fd);
    2505              :         }
    2506              :         else {
    2507            0 :             dlt_vlog(LOG_ERR,
    2508              :                      "%s: Cannot open %s. No context information stored\n",
    2509              :                      __func__,
    2510              :                      filename);
    2511              :         }
    2512              :     }
    2513              : 
    2514              :     return 0;
    2515              : }
    2516              : 
    2517            0 : int dlt_daemon_contexts_save_v2(DltDaemon *daemon, const char *filename, int verbose)
    2518              : {
    2519              :     FILE *fd;
    2520              :     int i;
    2521              : 
    2522              :     char apid[DLT_V2_ID_SIZE];
    2523              :     char ctid[DLT_V2_ID_SIZE];
    2524              :     DltDaemonRegisteredUsers *user_list = NULL;
    2525              : 
    2526            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2527              : 
    2528            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2529              :         return -1;
    2530              : 
    2531            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    2532              : 
    2533            0 :     if (user_list == NULL)
    2534              :         return -1;
    2535              : 
    2536            0 :     if ((user_list->contexts) && (user_list->num_contexts > 0)) {
    2537            0 :         fd = fopen(filename, "w");
    2538              : 
    2539            0 :         if (fd != NULL) {
    2540            0 :             for (i = 0; i < user_list->num_contexts; i++) {
    2541            0 :                 dlt_set_id_v2(apid, user_list->contexts[i].apid2, user_list->contexts[i].apid2len);
    2542            0 :                 dlt_set_id_v2(ctid, user_list->contexts[i].ctid2, user_list->contexts[i].ctid2len);
    2543              : 
    2544            0 :                 if ((user_list->contexts[i].context_description) &&
    2545            0 :                     (user_list->contexts[i].context_description[0] != '\0'))
    2546            0 :                     fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
    2547            0 :                             (int)(user_list->contexts[i].log_level),
    2548            0 :                             (int)(user_list->contexts[i].trace_status),
    2549              :                             user_list->contexts[i].context_description);
    2550              :                 else
    2551            0 :                     fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
    2552            0 :                             (int)(user_list->contexts[i].log_level),
    2553            0 :                             (int)(user_list->contexts[i].trace_status));
    2554              :             }
    2555              : 
    2556            0 :             fclose(fd);
    2557              :         }
    2558              :         else {
    2559            0 :             dlt_vlog(LOG_ERR,
    2560              :                      "%s: Cannot open %s. No context information stored\n",
    2561              :                      __func__,
    2562              :                      filename);
    2563              :         }
    2564              :     }
    2565              : 
    2566              :     return 0;
    2567              : }
    2568              : 
    2569            0 : int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
    2570              : {
    2571              :     FILE *fd;
    2572              : 
    2573            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2574              : 
    2575            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2576              :         return -1;
    2577              : 
    2578            0 :     fd = fopen(filename, "w");
    2579              : 
    2580            0 :     if (fd != NULL) {
    2581              :         fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
    2582            0 :         fprintf(fd, "LoggingMode = %d\n", daemon->mode);
    2583              : 
    2584            0 :         fclose(fd);
    2585              :     }
    2586              : 
    2587              :     return 0;
    2588              : }
    2589              : 
    2590            1 : int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose)
    2591              : {
    2592            1 :     if ((daemon == NULL) || (filename == NULL))
    2593              :         return -1;
    2594              : 
    2595              :     FILE *pFile;
    2596              :     char line[1024];
    2597              :     char token[1024];
    2598              :     char value[1024];
    2599              :     char *pch;
    2600              : 
    2601            1 :     PRINT_FUNCTION_VERBOSE(verbose);
    2602              : 
    2603            1 :     pFile = fopen (filename, "r");
    2604              : 
    2605            1 :     if (pFile != NULL) {
    2606              :         while (1) {
    2607              :             /* fetch line from configuration file */
    2608            2 :             if (fgets (line, 1024, pFile) != NULL) {
    2609            1 :                 pch = strtok (line, " =\r\n");
    2610            1 :                 token[0] = 0;
    2611            1 :                 value[0] = 0;
    2612              : 
    2613            2 :                 while (pch != NULL) {
    2614            1 :                     if (strcmp(pch, "#") == 0)
    2615              :                         break;
    2616              : 
    2617            1 :                     if (token[0] == 0) {
    2618              :                         strncpy(token, pch, sizeof(token) - 1);
    2619            1 :                         token[sizeof(token) - 1] = 0;
    2620              :                     }
    2621              :                     else {
    2622              :                         strncpy(value, pch, sizeof(value) - 1);
    2623            0 :                         value[sizeof(value) - 1] = 0;
    2624            0 :                         break;
    2625              :                     }
    2626              : 
    2627            1 :                     pch = strtok (NULL, " =\r\n");
    2628              :                 }
    2629              : 
    2630            1 :                 if (token[0] && value[0]) {
    2631              :                     /* parse arguments here */
    2632            0 :                     if (strcmp(token, "LoggingMode") == 0) {
    2633            0 :                         daemon->mode = atoi(value);
    2634            0 :                         dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token,
    2635              :                                  daemon->mode);
    2636              :                     }
    2637              :                     else {
    2638            0 :                         dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token,
    2639              :                                  value);
    2640              :                     }
    2641              :                 }
    2642              :             }
    2643              :             else {
    2644              :                 break;
    2645              :             }
    2646              :         }
    2647              : 
    2648            1 :         fclose (pFile);
    2649              :     }
    2650              :     else {
    2651            0 :         dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
    2652              :     }
    2653              : 
    2654              :     return 0;
    2655              : }
    2656              : 
    2657           15 : int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
    2658              : {
    2659              :     DltUserHeader userheader;
    2660              :     DltUserControlMsgLogLevel usercontext;
    2661              :     DltReturnValue ret;
    2662              :     DltDaemonApplication *app;
    2663              : 
    2664           15 :     PRINT_FUNCTION_VERBOSE(verbose);
    2665              : 
    2666           15 :     if ((daemon == NULL) || (context == NULL)) {
    2667            0 :         dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
    2668            0 :         return -1;
    2669              :     }
    2670              : 
    2671           15 :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
    2672            0 :         dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
    2673            0 :         return -1;
    2674              :     }
    2675              : 
    2676           15 :     if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
    2677           14 :         (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
    2678           12 :             usercontext.log_level = (uint8_t) (context->log_level >
    2679              :                 context->storage_log_level ? context->log_level : context->storage_log_level);
    2680              :     else /* Storage log level is not updated (is DEFAULT) then  no device is yet connected so ignore */
    2681            3 :         usercontext.log_level =
    2682            3 :             (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
    2683              : 
    2684           15 :     usercontext.trace_status =
    2685           15 :         (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
    2686              : 
    2687           15 :     usercontext.log_level_pos = context->log_level_pos;
    2688              : 
    2689           15 :     dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n",
    2690           15 :              context->apid,
    2691           15 :              context->ctid,
    2692           15 :              context->log_level,
    2693           15 :              usercontext.log_level,
    2694              :              context->trace_status,
    2695              :              usercontext.trace_status);
    2696              : 
    2697              :     /* log to FIFO */
    2698           15 :     errno = 0;
    2699           15 :     ret = dlt_user_log_out2_with_timeout(context->user_handle,
    2700              :                             &(userheader), sizeof(DltUserHeader),
    2701              :                             &(usercontext), sizeof(DltUserControlMsgLogLevel));
    2702              : 
    2703           15 :     if (ret < DLT_RETURN_OK) {
    2704            0 :         dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
    2705              :                  __func__,
    2706            0 :                  errno != 0 ? strerror(errno) : "Unknown error");
    2707              : 
    2708            0 :         if (errno == EPIPE || errno == EBADF) {
    2709            0 :             app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
    2710            0 :             if (app != NULL)
    2711            0 :                 dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2712              :         }
    2713              :     }
    2714              : 
    2715           15 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2716              : }
    2717              : 
    2718            0 : int dlt_daemon_user_send_log_level_v2(DltDaemon *daemon, DltDaemonContext *context, int verbose)
    2719              : {
    2720              :     DltUserHeader userheader;
    2721              :     DltUserControlMsgLogLevel usercontext;
    2722              :     DltReturnValue ret;
    2723            0 :     DltDaemonApplication *app = NULL;
    2724              : 
    2725            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2726              : 
    2727            0 :     if ((daemon == NULL) || (context == NULL)) {
    2728            0 :         dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
    2729            0 :         return -1;
    2730              :     }
    2731              : 
    2732            0 :     if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
    2733            0 :         dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
    2734            0 :         return -1;
    2735              :     }
    2736              : 
    2737            0 :     if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
    2738            0 :         (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
    2739            0 :             usercontext.log_level = (uint8_t) (context->log_level >
    2740              :                 context->storage_log_level ? context->log_level : context->storage_log_level);
    2741              :     else /* Storage log level is not updated (is DEFAULT) then  no device is yet connected so ignore */
    2742            0 :         usercontext.log_level =
    2743            0 :             (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
    2744              : 
    2745            0 :     usercontext.trace_status =
    2746            0 :         (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
    2747              : 
    2748            0 :     usercontext.log_level_pos = context->log_level_pos;
    2749              : 
    2750            0 :     dlt_vlog(LOG_NOTICE, "Send log-level to context: %s:%s [%i -> %i] [%i -> %i]\n",
    2751              :              context->apid2,
    2752              :              context->ctid2,
    2753            0 :              context->log_level,
    2754            0 :              usercontext.log_level,
    2755              :              context->trace_status,
    2756              :              usercontext.trace_status);
    2757              : 
    2758              :     /* log to FIFO */
    2759            0 :     errno = 0;
    2760            0 :     ret = dlt_user_log_out2_with_timeout(context->user_handle,
    2761              :                             &(userheader), sizeof(DltUserHeader),
    2762              :                             &(usercontext), sizeof(DltUserControlMsgLogLevel));
    2763              : 
    2764            0 :     if (ret < DLT_RETURN_OK) {
    2765            0 :         dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
    2766              :                  __func__,
    2767            0 :                  errno != 0 ? strerror(errno) : "Unknown error");
    2768              : 
    2769            0 :         if (errno == EPIPE || errno == EBADF) {
    2770            0 :             dlt_daemon_application_find_v2(daemon, context->apid2len, context->apid2,
    2771            0 :                                                  daemon->ecuid2len, daemon->ecuid2, verbose, &app);
    2772            0 :             if (app != NULL)
    2773            0 :                 dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2774              :         }
    2775              :     }
    2776            0 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2777              : }
    2778              : 
    2779            2 : int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
    2780              : {
    2781              :     DltUserHeader userheader;
    2782              :     DltUserControlMsgLogState logstate;
    2783              :     DltReturnValue ret;
    2784              : 
    2785            2 :     PRINT_FUNCTION_VERBOSE(verbose);
    2786              : 
    2787            2 :     if ((daemon == NULL) || (app == NULL))
    2788              :         return -1;
    2789              : 
    2790            2 :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
    2791              :         return -1;
    2792              : 
    2793            2 :     logstate.log_state = (int8_t)daemon->connectionState;
    2794              : 
    2795              :     /* log to FIFO */
    2796            2 :     ret = dlt_user_log_out2_with_timeout(app->user_handle,
    2797              :                             &(userheader), sizeof(DltUserHeader),
    2798              :                             &(logstate), sizeof(DltUserControlMsgLogState));
    2799              : 
    2800            2 :     if (ret < DLT_RETURN_OK) {
    2801            0 :         if (errno == EPIPE || errno == EBADF)
    2802            0 :             dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2803              :     }
    2804              : 
    2805            2 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2806              : }
    2807              : 
    2808            0 : int dlt_daemon_user_send_log_state_v2(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
    2809              : {
    2810              :     DltUserHeader userheader;
    2811              :     DltUserControlMsgLogState logstate;
    2812              :     DltReturnValue ret;
    2813              : 
    2814            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2815              : 
    2816            0 :     if ((daemon == NULL) || (app == NULL))
    2817              :         return -1;
    2818              : 
    2819            0 :     if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
    2820              :         return -1;
    2821              : 
    2822            0 :     logstate.log_state = (int8_t)daemon->connectionState;
    2823              : 
    2824              :     /* log to FIFO */
    2825            0 :     ret = dlt_user_log_out2_with_timeout(app->user_handle,
    2826              :                             &(userheader), sizeof(DltUserHeader),
    2827              :                             &(logstate.log_state), sizeof(int8_t));
    2828              : 
    2829            0 :     if (ret < DLT_RETURN_OK) {
    2830            0 :         if (errno == EPIPE || errno == EBADF)
    2831            0 :             dlt_daemon_application_reset_user_handle_v2(daemon, app, verbose);
    2832              :     }
    2833              : 
    2834            0 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2835              : }
    2836              : 
    2837            0 : void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,
    2838              :                                                  const char *filename,
    2839              :                                                  const char *filename1,
    2840              :                                                  int InitialContextLogLevel,
    2841              :                                                  int InitialContextTraceStatus,
    2842              :                                                  int InitialEnforceLlTsStatus,
    2843              :                                                  int verbose)
    2844              : {
    2845              :     FILE *fd;
    2846              : 
    2847            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2848              : 
    2849            0 :     if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
    2850            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2851            0 :         return;
    2852              :     }
    2853              : 
    2854            0 :     if ((filename[0] == '\0') || (filename1[0] == '\0')) {
    2855            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
    2856            0 :         return;
    2857              :     }
    2858              : 
    2859              :     /* Check for runtime cfg file and delete it, if available */
    2860            0 :     fd = fopen(filename, "r");
    2861              : 
    2862            0 :     if (fd != NULL) {
    2863              :         /* Close and delete file */
    2864            0 :         fclose(fd);
    2865            0 :         if (unlink(filename) != 0) {
    2866            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2867            0 :                     __func__, strerror(errno));
    2868              :         }
    2869              :     }
    2870              : 
    2871            0 :     fd = fopen(filename1, "r");
    2872              : 
    2873            0 :     if (fd != NULL) {
    2874              :         /* Close and delete file */
    2875            0 :         fclose(fd);
    2876            0 :         if (unlink(filename1) != 0) {
    2877            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2878            0 :                     __func__, strerror(errno));
    2879              :         }
    2880              :     }
    2881              : 
    2882            0 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
    2883            0 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
    2884            0 :     daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
    2885              : 
    2886              :     /* Reset all other things (log level, trace status, etc.
    2887              :      *                         to default values             */
    2888              : 
    2889              :     /* Inform user libraries about changed default log level/trace status */
    2890            0 :     dlt_daemon_user_send_default_update(daemon, verbose);
    2891              : }
    2892              : 
    2893            0 : void dlt_daemon_control_reset_to_factory_default_v2(DltDaemon *daemon,
    2894              :                                                  const char *filename,
    2895              :                                                  const char *filename1,
    2896              :                                                  int InitialContextLogLevel,
    2897              :                                                  int InitialContextTraceStatus,
    2898              :                                                  int InitialEnforceLlTsStatus,
    2899              :                                                  int verbose)
    2900              : {
    2901              :     FILE *fd;
    2902              : 
    2903            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2904              : 
    2905            0 :     if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
    2906            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2907            0 :         return;
    2908              :     }
    2909              : 
    2910            0 :     if ((filename[0] == '\0') || (filename1[0] == '\0')) {
    2911            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
    2912            0 :         return;
    2913              :     }
    2914              : 
    2915              :     /* Check for runtime cfg file and delete it, if available */
    2916            0 :     fd = fopen(filename, "r");
    2917              : 
    2918            0 :     if (fd != NULL) {
    2919              :         /* Close and delete file */
    2920            0 :         fclose(fd);
    2921            0 :         if (unlink(filename) != 0) {
    2922            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2923            0 :                     __func__, strerror(errno));
    2924              :         }
    2925              :     }
    2926              : 
    2927            0 :     fd = fopen(filename1, "r");
    2928              : 
    2929            0 :     if (fd != NULL) {
    2930              :         /* Close and delete file */
    2931            0 :         fclose(fd);
    2932            0 :         if (unlink(filename1) != 0) {
    2933            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2934            0 :                     __func__, strerror(errno));
    2935              :         }
    2936              :     }
    2937              : 
    2938            0 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
    2939            0 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
    2940            0 :     daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
    2941              : 
    2942              :     /* Reset all other things (log level, trace status, etc.
    2943              :      *                         to default values             */
    2944              : 
    2945              :     /* Inform user libraries about changed default log level/trace status */
    2946            0 :     dlt_daemon_user_send_default_update_v2(daemon, verbose);
    2947              : }
    2948              : 
    2949            0 : void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
    2950              : {
    2951              :     int32_t count;
    2952              :     DltDaemonContext *context;
    2953              :     DltDaemonRegisteredUsers *user_list = NULL;
    2954              : 
    2955            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2956              : 
    2957            0 :     if (daemon == NULL) {
    2958            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2959            0 :         return;
    2960              :     }
    2961              : 
    2962            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    2963              : 
    2964            0 :     if (user_list == NULL)
    2965              :         return;
    2966              : 
    2967            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    2968            0 :         context = &(user_list->contexts[count]);
    2969              : 
    2970            0 :         if (context != NULL) {
    2971            0 :             if ((context->log_level == DLT_LOG_DEFAULT) ||
    2972            0 :                 (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
    2973            0 :                 if (context->user_handle >= DLT_FD_MINIMUM)
    2974            0 :                     if (dlt_daemon_user_send_log_level(daemon,
    2975              :                                                        context,
    2976              :                                                        verbose) == -1)
    2977            0 :                         dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
    2978              :             }
    2979              :         }
    2980              :     }
    2981              : }
    2982              : 
    2983            0 : void dlt_daemon_user_send_default_update_v2(DltDaemon *daemon, int verbose)
    2984              : {
    2985              :     int32_t count;
    2986              :     DltDaemonContext *context;
    2987              :     DltDaemonRegisteredUsers *user_list = NULL;
    2988              : 
    2989            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2990              : 
    2991            0 :     if (daemon == NULL) {
    2992            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2993            0 :         return;
    2994              :     }
    2995              : 
    2996            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    2997              : 
    2998            0 :     if (user_list == NULL)
    2999              :         return;
    3000              : 
    3001            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3002            0 :         context = &(user_list->contexts[count]);
    3003              : 
    3004            0 :         if (context != NULL) {
    3005            0 :             if ((context->log_level == DLT_LOG_DEFAULT) ||
    3006            0 :                 (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
    3007            0 :                 if (context->user_handle >= DLT_FD_MINIMUM)
    3008            0 :                     if (dlt_daemon_user_send_log_level_v2(daemon,
    3009              :                                                        context,
    3010              :                                                        verbose) == -1)
    3011            0 :                         dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
    3012              :             }
    3013              :         }
    3014              :     }
    3015              : }
    3016              : 
    3017            0 : void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon,
    3018              :                                                int enforce_context_ll_and_ts,
    3019              :                                                int8_t context_log_level,
    3020              :                                                int8_t log_level,
    3021              :                                                int verbose)
    3022              : {
    3023              :     int32_t count = 0;
    3024              :     DltDaemonContext *context = NULL;
    3025              :     DltDaemonRegisteredUsers *user_list = NULL;
    3026              : 
    3027            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3028              : 
    3029            0 :     if (daemon == NULL)
    3030              :         return;
    3031              : 
    3032            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    3033              : 
    3034            0 :     if (user_list == NULL)
    3035              :         return;
    3036              : 
    3037            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3038            0 :         context = &(user_list->contexts[count]);
    3039              : 
    3040            0 :         if (context) {
    3041            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3042            0 :                 context->log_level = log_level;
    3043              : 
    3044            0 :                 if (enforce_context_ll_and_ts) {
    3045              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    3046              :                     DltDaemonContextLogSettings *settings =
    3047              :                         dlt_daemon_find_configured_app_id_ctx_id_settings(
    3048              :                             daemon, context->apid, context->ctid);
    3049              :                     if (settings != NULL) {
    3050              :                         if (log_level > settings->log_level) {
    3051              :                           context->log_level = settings->log_level;
    3052              :                         }
    3053              :                     } else
    3054              : #endif
    3055            0 :                     if (log_level > context_log_level) {
    3056            0 :                         context->log_level = (int8_t)context_log_level;
    3057              :                     }
    3058              :                 }
    3059              : 
    3060            0 :                 if (dlt_daemon_user_send_log_level(daemon,
    3061              :                                                    context,
    3062              :                                                    verbose) == -1)
    3063            0 :                     dlt_vlog(LOG_WARNING,
    3064              :                              "Cannot send log level %.4s:%.4s -> %i\n",
    3065            0 :                              context->apid,
    3066            0 :                              context->ctid,
    3067            0 :                              context->log_level);
    3068              :             }
    3069              :         }
    3070              :     }
    3071              : }
    3072              : 
    3073            0 : void dlt_daemon_user_send_all_log_level_update_v2(DltDaemon *daemon,
    3074              :                                                int enforce_context_ll_and_ts,
    3075              :                                                int8_t context_log_level,
    3076              :                                                int8_t log_level,
    3077              :                                                int verbose)
    3078              : {
    3079              :     int32_t count = 0;
    3080              :     DltDaemonContext *context = NULL;
    3081              :     DltDaemonRegisteredUsers *user_list = NULL;
    3082              : 
    3083            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3084              : 
    3085            0 :     if (daemon == NULL)
    3086              :         return;
    3087              : 
    3088            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    3089              : 
    3090            0 :     if (user_list == NULL)
    3091              :         return;
    3092              : 
    3093            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3094            0 :         context = &(user_list->contexts[count]);
    3095              : 
    3096            0 :         if (context) {
    3097            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3098            0 :                 context->log_level = log_level;
    3099              : 
    3100            0 :                 if (enforce_context_ll_and_ts) {
    3101              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    3102              :                     //TBD: Check if function params require apid/ctid lengths
    3103              :                     DltDaemonContextLogSettingsV2 *settings =
    3104              :                         dlt_daemon_find_configured_app_id_ctx_id_settings_v2(
    3105              :                             daemon, context->apid, context->ctid);
    3106              :                     if (settings != NULL) {
    3107              :                         if (log_level > settings->log_level) {
    3108              :                           context->log_level = settings->log_level;
    3109              :                         }
    3110              :                     } else
    3111              : #endif
    3112            0 :                     if (log_level > context_log_level) {
    3113            0 :                         context->log_level = (int8_t)context_log_level;
    3114              :                     }
    3115              :                 }
    3116              : 
    3117            0 :                 if (dlt_daemon_user_send_log_level_v2(daemon,
    3118              :                                                    context,
    3119              :                                                    verbose) == -1)
    3120            0 :                     dlt_vlog(LOG_WARNING,
    3121              :                              "Cannot send log level %.4s:%.4s -> %i\n",
    3122            0 :                              context->apid,
    3123            0 :                              context->ctid,
    3124            0 :                              context->log_level);
    3125              :             }
    3126              :         }
    3127              :     }
    3128              : }
    3129              : 
    3130            0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose)
    3131              : {
    3132              :     int32_t count = 0;
    3133              :     DltDaemonContext *context = NULL;
    3134              :     DltDaemonRegisteredUsers *user_list = NULL;
    3135              : 
    3136            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3137              : 
    3138            0 :     if (daemon == NULL)
    3139              :         return;
    3140              : 
    3141            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    3142              : 
    3143            0 :     if (user_list == NULL)
    3144              :         return;
    3145              : 
    3146            0 :     dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
    3147              : 
    3148            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3149            0 :         context = &(user_list->contexts[count]);
    3150              : 
    3151            0 :         if (context) {
    3152            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3153            0 :                 context->trace_status = trace_status;
    3154              : 
    3155            0 :                 if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
    3156            0 :                     dlt_vlog(LOG_WARNING,
    3157              :                              "Cannot send trace status %.4s:%.4s -> %i\n",
    3158            0 :                              context->apid,
    3159            0 :                              context->ctid,
    3160            0 :                              context->trace_status);
    3161              :             }
    3162              :         }
    3163              :     }
    3164              : }
    3165              : 
    3166            0 : void dlt_daemon_user_send_all_trace_status_update_v2(DltDaemon *daemon, int8_t trace_status, int verbose)
    3167              : {
    3168              :     int32_t count = 0;
    3169              :     DltDaemonContext *context = NULL;
    3170              :     DltDaemonRegisteredUsers *user_list = NULL;
    3171              : 
    3172            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3173              : 
    3174            0 :     if (daemon == NULL)
    3175              :         return;
    3176              : 
    3177            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    3178              : 
    3179            0 :     if (user_list == NULL)
    3180              :         return;
    3181              : 
    3182            0 :     dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
    3183              : 
    3184            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3185            0 :         context = &(user_list->contexts[count]);
    3186              : 
    3187            0 :         if (context) {
    3188            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3189            0 :                 context->trace_status = trace_status;
    3190              : 
    3191            0 :                 if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1)
    3192            0 :                     dlt_vlog(LOG_WARNING,
    3193              :                              "Cannot send trace status %.*s:%.*s -> %i\n",
    3194            0 :                              context->apid2len,
    3195              :                              context->apid2,
    3196            0 :                              context->ctid2len,
    3197              :                              context->ctid2,
    3198            0 :                              context->trace_status);
    3199              :             }
    3200              :         }
    3201              :     }
    3202              : }
    3203              : 
    3204            1 : void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
    3205              : {
    3206              :     int32_t count;
    3207              :     DltDaemonApplication *app;
    3208              :     DltDaemonRegisteredUsers *user_list = NULL;
    3209              : 
    3210            1 :     PRINT_FUNCTION_VERBOSE(verbose);
    3211              : 
    3212            1 :     if (daemon == NULL) {
    3213            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3214            0 :         return;
    3215              :     }
    3216              : 
    3217            1 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    3218              : 
    3219            1 :     if (user_list == NULL)
    3220              :         return;
    3221              : 
    3222            2 :     for (count = 0; count < user_list->num_applications; count++) {
    3223            1 :         app = &(user_list->applications[count]);
    3224              : 
    3225            1 :         if (app != NULL) {
    3226            1 :             if (app->user_handle >= DLT_FD_MINIMUM) {
    3227            1 :                 if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
    3228            0 :                     dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d %s\n", app->apid, app->pid, __func__);
    3229              :             }
    3230              :         }
    3231              :     }
    3232              : }
    3233              : 
    3234            0 : void dlt_daemon_user_send_all_log_state_v2(DltDaemon *daemon, int verbose)
    3235              : {
    3236              :     int32_t count;
    3237              :     DltDaemonApplication *app;
    3238              :     DltDaemonRegisteredUsers *user_list = NULL;
    3239              : 
    3240            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3241              : 
    3242            0 :     if (daemon == NULL) {
    3243            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3244            0 :         return;
    3245              :     }
    3246              : 
    3247            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    3248              : 
    3249            0 :     if (user_list == NULL)
    3250              :         return;
    3251              : 
    3252            0 :     for (count = 0; count < user_list->num_applications; count++) {
    3253            0 :         app = &(user_list->applications[count]);
    3254              : 
    3255            0 :         if (app != NULL) {
    3256            0 :             if (app->user_handle >= DLT_FD_MINIMUM) {
    3257            0 :                 if (dlt_daemon_user_send_log_state_v2(daemon, app, verbose) == -1) {
    3258            0 :                     dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %s, PID: %d %s\n", app->apid2, app->pid, __func__);
    3259              :                 }
    3260              :             }
    3261              :         }
    3262              :     }
    3263              : }
    3264              : 
    3265            2 : void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
    3266              : {
    3267            2 :     switch (newState) {
    3268            0 :     case DLT_DAEMON_STATE_INIT:
    3269            0 :         dlt_log(LOG_INFO, "Switched to init state.\n");
    3270            0 :         daemon->state = DLT_DAEMON_STATE_INIT;
    3271            0 :         break;
    3272            2 :     case DLT_DAEMON_STATE_BUFFER:
    3273            2 :         dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
    3274            2 :         daemon->state = DLT_DAEMON_STATE_BUFFER;
    3275            2 :         break;
    3276            0 :     case DLT_DAEMON_STATE_BUFFER_FULL:
    3277            0 :         dlt_log(LOG_INFO, "Switched to buffer full state.\n");
    3278            0 :         daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
    3279            0 :         break;
    3280            0 :     case DLT_DAEMON_STATE_SEND_BUFFER:
    3281            0 :         dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
    3282            0 :         daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
    3283            0 :         break;
    3284            0 :     case DLT_DAEMON_STATE_SEND_DIRECT:
    3285            0 :         dlt_log(LOG_INFO, "Switched to send direct state.\n");
    3286            0 :         daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
    3287            0 :         break;
    3288              :     }
    3289            2 : }
    3290              : 
    3291              : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
    3292              : bool dlt_daemon_trigger_systemd_watchdog_if_necessary(DltDaemon *daemon) {
    3293              :     if (daemon->watchdog_trigger_interval == 0) {
    3294              :         return false;
    3295              :     }
    3296              : 
    3297              :     const unsigned int uptime_seconds = dlt_uptime() / 10000;
    3298              :     const unsigned int seconds_since_last_trigger = uptime_seconds - daemon->watchdog_last_trigger_time;
    3299              :     if (seconds_since_last_trigger < daemon->watchdog_trigger_interval) {
    3300              :         return false;
    3301              :     }
    3302              :     if (sd_notify(0, "WATCHDOG=1") < 0) {
    3303              :         dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
    3304              :         return false;
    3305              :     }
    3306              :     else
    3307              :         daemon->watchdog_last_trigger_time = uptime_seconds;
    3308              : 
    3309              :     return true;
    3310              : }
    3311              : 
    3312              : #endif
    3313              : 
    3314              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    3315              : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
    3316              : {
    3317              :     DltUserHeader userheader;
    3318              :     DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
    3319              :     uint32_t trace_load_settings_count;
    3320              :     DltReturnValue ret;
    3321              : 
    3322              : 
    3323              :     PRINT_FUNCTION_VERBOSE(verbose);
    3324              : 
    3325              :     if ((daemon == NULL) || (app == NULL)) return -1;
    3326              : 
    3327              :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
    3328              : 
    3329              :     DltTraceLoadSettings* app_settings = app->trace_load_settings;
    3330              : 
    3331              :     if (app_settings != NULL) {
    3332              :         trace_load_settings_count = app->trace_load_settings_count;
    3333              :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    3334              :         for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
    3335              :             // App id is not transmitted as the user library only
    3336              :             // has one application ID
    3337              :             memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
    3338              :             trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
    3339              :             trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
    3340              : 
    3341              :             if (app_settings[i].ctid[0] == '\0') {
    3342              :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
    3343              :                          app->apid,
    3344              :                          app_settings[i].soft_limit,
    3345              :                          app_settings[i].hard_limit);
    3346              :             } else {
    3347              :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
    3348              :                          app->apid,
    3349              :                          app_settings[i].ctid,
    3350              :                          app_settings[i].soft_limit,
    3351              :                          app_settings[i].hard_limit);
    3352              :             }
    3353              : 
    3354              :         }
    3355              :     }
    3356              :     else {
    3357              :         dlt_vlog(LOG_INFO,
    3358              :                  "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
    3359              : 
    3360              :         trace_load_settings_count = 1;
    3361              :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
    3362              : 
    3363              :         memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
    3364              :         trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
    3365              :         trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
    3366              :     }
    3367              : 
    3368              :     /* log to FIFO */
    3369              :     ret = dlt_user_log_out3_with_timeout(app->user_handle,
    3370              :                                          &(userheader), sizeof(DltUserHeader),
    3371              :                                          &(trace_load_settings_count), sizeof(uint32_t),
    3372              :                                          trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    3373              : 
    3374              :     if (ret < DLT_RETURN_OK) {
    3375              :         if (errno == EPIPE || errno == EBADF)
    3376              :             dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    3377              :     }
    3378              : 
    3379              :     free(trace_load_settings_user_msg);
    3380              : 
    3381              :     return ret;
    3382              : }
    3383              : #endif
        

Generated by: LCOV version 2.0-1