LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_common.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 25.8 % 1068 276
Test Date: 2026-02-03 07:35:37 Functions: 37.0 % 54 20

            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            6 :     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            6 :     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            6 : static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
     125              : {
     126            6 :     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            6 :     cmp = memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
     134              : 
     135            6 :     if (cmp < 0)
     136              :         ret = -1;
     137            6 :     else if (cmp == 0)
     138            6 :         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           54 : DltDaemonRegisteredUsers *dlt_daemon_find_users_list(DltDaemon *daemon,
     178              :                                                      char *ecu,
     179              :                                                      int verbose)
     180              : {
     181           54 :     PRINT_FUNCTION_VERBOSE(verbose);
     182              : 
     183              :     int i = 0;
     184              : 
     185           54 :     if ((daemon == NULL) || (ecu == NULL)) {
     186            0 :         dlt_vlog(LOG_ERR, "%s: Wrong parameters", __func__);
     187            0 :         return (DltDaemonRegisteredUsers *)NULL;
     188              :     }
     189              : 
     190           54 :     for (i = 0; i < daemon->num_user_lists; i++)
     191           42 :         if (strncmp(ecu, daemon->user_list[i].ecu, DLT_ID_SIZE) == 0)
     192           42 :             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            4 : 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            4 :     PRINT_FUNCTION_VERBOSE(verbose);
     630              : 
     631            4 :     if ((daemon == NULL) || (ecu == NULL))
     632              :         return DLT_RETURN_ERROR;
     633              : 
     634            4 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     635              : 
     636            4 :     if (user_list != NULL) {
     637            6 :         for (i = 0; i < user_list->num_applications; i++)
     638            2 :             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            1 :     for (i = 0; i < user_list->num_applications; i++)
     689            0 :         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            0 :             free(user_list->applications[i].application_description);
     703            0 :             user_list->applications[i].application_description = NULL;
     704              :         }
     705              : 
     706            1 :     if (user_list->applications != NULL)
     707            0 :         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            2 : 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            2 :     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            3 : 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            3 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') || (ecu == NULL))
     833              :         return (DltDaemonApplication *)NULL;
     834              : 
     835            3 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
     836              : 
     837            3 :     if (user_list == NULL)
     838              :         return (DltDaemonApplication *)NULL;
     839              : 
     840            3 :     if (user_list->applications == NULL) {
     841            3 :         user_list->applications = (DltDaemonApplication *)
     842            3 :             malloc(sizeof(DltDaemonApplication) * DLT_DAEMON_APPL_ALLOC_SIZE);
     843              : 
     844            3 :         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            3 :     application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
     852              : 
     853            3 :     if (application == NULL) {
     854            3 :         user_list->num_applications += 1;
     855              : 
     856            3 :         if (user_list->num_applications != 0) {
     857            3 :             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            3 :         application = &(user_list->applications[(size_t)(user_list->num_applications - 1)]);
     879              : 
     880            3 :         dlt_set_id(application->apid, apid);
     881            3 :         application->pid = 0;
     882            3 :         application->application_description = NULL;
     883            3 :         application->num_contexts = 0;
     884            3 :         application->user_handle = DLT_FD_INIT;
     885            3 :         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            3 :     if (application->application_description) {
     906            0 :         free(application->application_description);
     907            0 :         application->application_description = NULL;
     908              :     }
     909              : 
     910            3 :     if (description != NULL) {
     911            3 :         application->application_description = malloc(strlen(description) + 1);
     912              : 
     913            3 :         if (application->application_description) {
     914            3 :             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            3 :     if (application->pid != pid) {
     923            2 :         dlt_daemon_application_reset_user_handle(daemon, application, verbose);
     924            2 :         application->pid = 0;
     925              :     }
     926              : 
     927              :     /* open user pipe only if it is not yet opened */
     928            3 :     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            2 :             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            2 :             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            2 :         dlt_daemon_applications_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
     962            2 :         dlt_daemon_contexts_invalidate_fd(daemon, ecu, dlt_user_handle, verbose);
     963              : 
     964            2 :         application->user_handle = dlt_user_handle;
     965            2 :         application->owns_user_handle = owns_user_handle;
     966            2 :         application->pid = pid;
     967              :     }
     968              : 
     969              :     /* Sort */
     970            3 :     if (new_application) {
     971            3 :         qsort(user_list->applications,
     972            3 :               (size_t) user_list->num_applications,
     973              :               sizeof(DltDaemonApplication),
     974              :               dlt_daemon_cmp_apid);
     975              : 
     976              :         /* Find new position of application with apid*/
     977            3 :         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           11 : 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           11 :     PRINT_FUNCTION_VERBOSE(verbose);
    1392              : 
    1393           11 :     if ((daemon == NULL) || (daemon->user_list == NULL) || (apid == NULL) ||
    1394           11 :         (apid[0] == '\0') || (ecu == NULL))
    1395              :         return (DltDaemonApplication *)NULL;
    1396              : 
    1397           11 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1398              : 
    1399           11 :     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            6 :     if ((memcmp(apid, user_list->applications[0].apid, DLT_ID_SIZE) < 0) ||
    1404            6 :         (memcmp(apid,
    1405            6 :                 user_list->applications[user_list->num_applications - 1].apid,
    1406              :                 DLT_ID_SIZE) > 0))
    1407              :         return (DltDaemonApplication *)NULL;
    1408              : 
    1409            6 :     dlt_set_id(application.apid, apid);
    1410            6 :     return (DltDaemonApplication *)bsearch(&application,
    1411            6 :                                            user_list->applications,
    1412            6 :                                            (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            3 : 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            3 :     PRINT_FUNCTION_VERBOSE(verbose);
    1664              : 
    1665            3 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
    1666            3 :         (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
    1667              :         return (DltDaemonContext *)NULL;
    1668              : 
    1669            3 :     if ((log_level < DLT_LOG_DEFAULT) || (log_level > DLT_LOG_VERBOSE))
    1670              :         return (DltDaemonContext *)NULL;
    1671              : 
    1672            3 :     if ((trace_status < DLT_TRACE_STATUS_DEFAULT) || (trace_status > DLT_TRACE_STATUS_ON))
    1673              :         return (DltDaemonContext *)NULL;
    1674              : 
    1675            3 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    1676              : 
    1677            3 :     if (user_list == NULL)
    1678              :         return (DltDaemonContext *)NULL;
    1679              : 
    1680            3 :     if (user_list->contexts == NULL) {
    1681            3 :         user_list->contexts = (DltDaemonContext *)calloc(1, sizeof(DltDaemonContext) * DLT_DAEMON_CONTEXT_ALLOC_SIZE);
    1682              : 
    1683            3 :         if (user_list->contexts == NULL)
    1684              :             return (DltDaemonContext *)NULL;
    1685              :     }
    1686              : 
    1687              :     /* Check if application [apid] is available */
    1688            3 :     application = dlt_daemon_application_find(daemon, apid, ecu, verbose);
    1689              : 
    1690            3 :     if (application == NULL)
    1691              :         return (DltDaemonContext *)NULL;
    1692              : 
    1693              :     /* Check if context [apid, ctid] is already available */
    1694            3 :     context = dlt_daemon_context_find(daemon, apid, ctid, ecu, verbose);
    1695              : 
    1696            3 :     if (context == NULL) {
    1697            3 :         user_list->num_contexts += 1;
    1698              : 
    1699            3 :         if (user_list->num_contexts != 0) {
    1700            3 :             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            3 :         context = &(user_list->contexts[(size_t)(user_list->num_contexts - 1)]);
    1722              :         memset(context, 0, sizeof(DltDaemonContext));
    1723              : 
    1724            3 :         dlt_set_id(context->apid, apid);
    1725            3 :         dlt_set_id(context->ctid, ctid);
    1726              : 
    1727              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    1728              :         context->trace_load_settings = NULL;
    1729              : #endif
    1730              : 
    1731            3 :         application->num_contexts++;
    1732              :         new_context = 1;
    1733              :     }
    1734              : 
    1735              :     /* Set context description */
    1736            3 :     if (context->context_description) {
    1737            0 :         free(context->context_description);
    1738            0 :         context->context_description = NULL;
    1739              :     }
    1740              : 
    1741            3 :     if (description != NULL) {
    1742            3 :         context->context_description = malloc(strlen(description) + 1);
    1743              : 
    1744            3 :         if (context->context_description) {
    1745            3 :             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            3 :     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            3 :     if ((new_context == 1) ||
    1802            0 :         ((new_context == 0) && (daemon->runtime_context_cfg_loaded == 0))) {
    1803            3 :         context->log_level = log_level;
    1804            3 :         context->trace_status = trace_status;
    1805              :     }
    1806              : 
    1807            3 :     context->log_level_pos = log_level_pos;
    1808            3 :     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            3 :     if (context->user_handle == 0)
    1814            0 :         context->predefined = true;
    1815              :     else
    1816            3 :         context->predefined = false;
    1817              : 
    1818              :     /* Sort */
    1819            3 :     if (new_context) {
    1820            3 :         qsort(user_list->contexts,
    1821            3 :               (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            3 :         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 = (DltDaemonApplication *)malloc(sizeof(DltDaemonApplication));
    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           23 : 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           23 :     PRINT_FUNCTION_VERBOSE(verbose);
    2182              : 
    2183           23 :     if ((daemon == NULL) || (apid == NULL) || (apid[0] == '\0') ||
    2184           23 :         (ctid == NULL) || (ctid[0] == '\0') || (ecu == NULL))
    2185              :         return (DltDaemonContext *)NULL;
    2186              : 
    2187           23 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    2188              : 
    2189           23 :     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            6 :     if ((memcmp(apid, user_list->contexts[0].apid, DLT_ID_SIZE) < 0) ||
    2194            6 :         (memcmp(apid,
    2195            6 :                 user_list->contexts[user_list->num_contexts - 1].apid,
    2196              :                 DLT_ID_SIZE) > 0))
    2197              :         return (DltDaemonContext *)NULL;
    2198              : 
    2199            6 :     dlt_set_id(context.apid, apid);
    2200            6 :     dlt_set_id(context.ctid, ctid);
    2201              : 
    2202            6 :     return (DltDaemonContext *)bsearch(&context,
    2203            6 :                                        user_list->contexts,
    2204            6 :                                        (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            4 : 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            4 :     PRINT_FUNCTION_VERBOSE(verbose);
    2267              : 
    2268            4 :     if ((daemon == NULL) || (ecu == NULL))
    2269              :         return -1;
    2270              : 
    2271            4 :     user_list = dlt_daemon_find_users_list(daemon, ecu, verbose);
    2272              : 
    2273            4 :     if (user_list != NULL) {
    2274            4 :         for (i = 0; i < user_list->num_contexts; i++)
    2275            0 :             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            1 :     for (i = 0; i < users->num_contexts; i++)
    2326            0 :         if (users->contexts[i].context_description != NULL) {
    2327            0 :             free(users->contexts[i].context_description);
    2328            0 :             users->contexts[i].context_description = NULL;
    2329              :         }
    2330              : 
    2331            1 :     if (users->contexts) {
    2332            0 :         free(users->contexts);
    2333            0 :         users->contexts = NULL;
    2334              :     }
    2335              : 
    2336            1 :     for (i = 0; i < users->num_applications; i++)
    2337            0 :         users->applications[i].num_contexts = 0;
    2338              : 
    2339            1 :     users->num_contexts = 0;
    2340              : 
    2341            1 :     return 0;
    2342              : }
    2343              : 
    2344            0 : int dlt_daemon_contexts_load(DltDaemon *daemon, const char *filename, int verbose)
    2345              : {
    2346              :     FILE *fd;
    2347              :     ID4 apid, ctid;
    2348              :     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
    2349              :     char *ret;
    2350              :     char *pb;
    2351              :     int ll, ts;
    2352              : 
    2353            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2354              : 
    2355            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2356              :         return -1;
    2357              : 
    2358            0 :     fd = fopen(filename, "r");
    2359              : 
    2360            0 :     if (fd == NULL) {
    2361            0 :         dlt_vlog(LOG_WARNING,
    2362              :                  "DLT runtime-context load, cannot open file %s: %s\n",
    2363              :                  filename,
    2364            0 :                  strerror(errno));
    2365              : 
    2366            0 :         return -1;
    2367              :     }
    2368              : 
    2369            0 :     while (!feof(fd)) {
    2370              :         /* Clear buf */
    2371              :         memset(buf, 0, sizeof(buf));
    2372              : 
    2373              :         /* Get line */
    2374              :         ret = fgets(buf, sizeof(buf), fd);
    2375              : 
    2376            0 :         if (NULL == ret) {
    2377              :             /* fgets always returns null pointer if the last byte of the file is a new line.
    2378              :              * We need to check here if there was an error or was it feof.*/
    2379            0 :             if (ferror(fd)) {
    2380            0 :                 dlt_vlog(LOG_WARNING,
    2381              :                          "%s fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
    2382              :                          __func__,
    2383            0 :                          strerror(errno));
    2384            0 :                 fclose(fd);
    2385            0 :                 return -1;
    2386              :             }
    2387            0 :             else if (feof(fd))
    2388              :             {
    2389            0 :                 fclose(fd);
    2390            0 :                 return 0;
    2391              :             }
    2392              :             else {
    2393            0 :                 dlt_vlog(LOG_WARNING,
    2394              :                          "%s fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n",
    2395              :                          __func__);
    2396            0 :                 fclose(fd);
    2397            0 :                 return -1;
    2398              :             }
    2399              :         }
    2400              : 
    2401            0 :         if (strcmp(buf, "") != 0) {
    2402              :             /* Split line */
    2403            0 :             pb = strtok(buf, ":");
    2404              : 
    2405            0 :             if (pb != NULL) {
    2406            0 :                 dlt_set_id(apid, pb);
    2407            0 :                 pb = strtok(NULL, ":");
    2408              : 
    2409            0 :                 if (pb != NULL) {
    2410            0 :                     dlt_set_id(ctid, pb);
    2411            0 :                     pb = strtok(NULL, ":");
    2412              : 
    2413            0 :                     if (pb != NULL) {
    2414            0 :                         sscanf(pb, "%d", &ll);
    2415            0 :                         pb = strtok(NULL, ":");
    2416              : 
    2417            0 :                         if (pb != NULL) {
    2418            0 :                             sscanf(pb, "%d", &ts);
    2419            0 :                             pb = strtok(NULL, ":");
    2420              : 
    2421            0 :                             if (pb != NULL) {
    2422              :                                 /* pb contains now the description */
    2423              : 
    2424              :                                 /* log_level_pos, and user_handle are unknown at loading time */
    2425            0 :                                 if (dlt_daemon_context_add(daemon,
    2426              :                                                            apid,
    2427              :                                                            ctid,
    2428            0 :                                                            (int8_t)ll,
    2429            0 :                                                            (int8_t)ts,
    2430              :                                                            0,
    2431              :                                                            0,
    2432              :                                                            pb,
    2433            0 :                                                            daemon->ecuid,
    2434              :                                                            verbose) == NULL) {
    2435            0 :                                     dlt_vlog(LOG_WARNING,
    2436              :                                              "%s dlt_daemon_context_add failed\n",
    2437              :                                              __func__);
    2438            0 :                                     fclose(fd);
    2439            0 :                                     return -1;
    2440              :                                 }
    2441              :                             }
    2442              :                         }
    2443              :                     }
    2444              :                 }
    2445              :             }
    2446              :         }
    2447              :     }
    2448              : 
    2449            0 :     fclose(fd);
    2450              : 
    2451            0 :     return 0;
    2452              : }
    2453              : 
    2454            0 : int dlt_daemon_contexts_save(DltDaemon *daemon, const char *filename, int verbose)
    2455              : {
    2456              :     FILE *fd;
    2457              :     int i;
    2458              : 
    2459              :     char apid[DLT_ID_SIZE + 1], ctid[DLT_ID_SIZE + 1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
    2460              :     DltDaemonRegisteredUsers *user_list = NULL;
    2461              : 
    2462            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2463              : 
    2464            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2465              :         return -1;
    2466              : 
    2467            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    2468              : 
    2469            0 :     if (user_list == NULL)
    2470              :         return -1;
    2471              : 
    2472              :     memset(apid, 0, sizeof(apid));
    2473              :     memset(ctid, 0, sizeof(ctid));
    2474              : 
    2475            0 :     if ((user_list->contexts) && (user_list->num_contexts > 0)) {
    2476            0 :         fd = fopen(filename, "w");
    2477              : 
    2478            0 :         if (fd != NULL) {
    2479            0 :             for (i = 0; i < user_list->num_contexts; i++) {
    2480            0 :                 dlt_set_id(apid, user_list->contexts[i].apid);
    2481            0 :                 dlt_set_id(ctid, user_list->contexts[i].ctid);
    2482              : 
    2483            0 :                 if ((user_list->contexts[i].context_description) &&
    2484            0 :                     (user_list->contexts[i].context_description[0] != '\0'))
    2485            0 :                     fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
    2486            0 :                             (int)(user_list->contexts[i].log_level),
    2487            0 :                             (int)(user_list->contexts[i].trace_status),
    2488              :                             user_list->contexts[i].context_description);
    2489              :                 else
    2490            0 :                     fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
    2491            0 :                             (int)(user_list->contexts[i].log_level),
    2492            0 :                             (int)(user_list->contexts[i].trace_status));
    2493              :             }
    2494              : 
    2495            0 :             fclose(fd);
    2496              :         }
    2497              :         else {
    2498            0 :             dlt_vlog(LOG_ERR,
    2499              :                      "%s: Cannot open %s. No context information stored\n",
    2500              :                      __func__,
    2501              :                      filename);
    2502              :         }
    2503              :     }
    2504              : 
    2505              :     return 0;
    2506              : }
    2507              : 
    2508            0 : int dlt_daemon_contexts_save_v2(DltDaemon *daemon, const char *filename, int verbose)
    2509              : {
    2510              :     FILE *fd;
    2511              :     int i;
    2512              : 
    2513              :     char apid[DLT_V2_ID_SIZE];
    2514              :     char ctid[DLT_V2_ID_SIZE];
    2515              :     DltDaemonRegisteredUsers *user_list = NULL;
    2516              : 
    2517            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2518              : 
    2519            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2520              :         return -1;
    2521              : 
    2522            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    2523              : 
    2524            0 :     if (user_list == NULL)
    2525              :         return -1;
    2526              : 
    2527            0 :     if ((user_list->contexts) && (user_list->num_contexts > 0)) {
    2528            0 :         fd = fopen(filename, "w");
    2529              : 
    2530            0 :         if (fd != NULL) {
    2531            0 :             for (i = 0; i < user_list->num_contexts; i++) {
    2532            0 :                 dlt_set_id_v2(apid, user_list->contexts[i].apid2, user_list->contexts[i].apid2len);
    2533            0 :                 dlt_set_id_v2(ctid, user_list->contexts[i].ctid2, user_list->contexts[i].ctid2len);
    2534              : 
    2535            0 :                 if ((user_list->contexts[i].context_description) &&
    2536            0 :                     (user_list->contexts[i].context_description[0] != '\0'))
    2537            0 :                     fprintf(fd, "%s:%s:%d:%d:%s:\n", apid, ctid,
    2538            0 :                             (int)(user_list->contexts[i].log_level),
    2539            0 :                             (int)(user_list->contexts[i].trace_status),
    2540              :                             user_list->contexts[i].context_description);
    2541              :                 else
    2542            0 :                     fprintf(fd, "%s:%s:%d:%d::\n", apid, ctid,
    2543            0 :                             (int)(user_list->contexts[i].log_level),
    2544            0 :                             (int)(user_list->contexts[i].trace_status));
    2545              :             }
    2546              : 
    2547            0 :             fclose(fd);
    2548              :         }
    2549              :         else {
    2550            0 :             dlt_vlog(LOG_ERR,
    2551              :                      "%s: Cannot open %s. No context information stored\n",
    2552              :                      __func__,
    2553              :                      filename);
    2554              :         }
    2555              :     }
    2556              : 
    2557              :     return 0;
    2558              : }
    2559              : 
    2560            0 : int dlt_daemon_configuration_save(DltDaemon *daemon, const char *filename, int verbose)
    2561              : {
    2562              :     FILE *fd;
    2563              : 
    2564            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2565              : 
    2566            0 :     if ((daemon == NULL) || (filename == NULL) || (filename[0] == '\0'))
    2567              :         return -1;
    2568              : 
    2569            0 :     fd = fopen(filename, "w");
    2570              : 
    2571            0 :     if (fd != NULL) {
    2572              :         fprintf(fd, "# 0 = off, 1 = external, 2 = internal, 3 = both\n");
    2573            0 :         fprintf(fd, "LoggingMode = %d\n", daemon->mode);
    2574              : 
    2575            0 :         fclose(fd);
    2576              :     }
    2577              : 
    2578              :     return 0;
    2579              : }
    2580              : 
    2581            1 : int dlt_daemon_configuration_load(DltDaemon *daemon, const char *filename, int verbose)
    2582              : {
    2583            1 :     if ((daemon == NULL) || (filename == NULL))
    2584              :         return -1;
    2585              : 
    2586              :     FILE *pFile;
    2587              :     char line[1024];
    2588              :     char token[1024];
    2589              :     char value[1024];
    2590              :     char *pch;
    2591              : 
    2592            1 :     PRINT_FUNCTION_VERBOSE(verbose);
    2593              : 
    2594            1 :     pFile = fopen (filename, "r");
    2595              : 
    2596            1 :     if (pFile != NULL) {
    2597              :         while (1) {
    2598              :             /* fetch line from configuration file */
    2599            2 :             if (fgets (line, 1024, pFile) != NULL) {
    2600            1 :                 pch = strtok (line, " =\r\n");
    2601            1 :                 token[0] = 0;
    2602            1 :                 value[0] = 0;
    2603              : 
    2604            2 :                 while (pch != NULL) {
    2605            1 :                     if (strcmp(pch, "#") == 0)
    2606              :                         break;
    2607              : 
    2608            1 :                     if (token[0] == 0) {
    2609              :                         strncpy(token, pch, sizeof(token) - 1);
    2610            1 :                         token[sizeof(token) - 1] = 0;
    2611              :                     }
    2612              :                     else {
    2613              :                         strncpy(value, pch, sizeof(value) - 1);
    2614            0 :                         value[sizeof(value) - 1] = 0;
    2615            0 :                         break;
    2616              :                     }
    2617              : 
    2618            1 :                     pch = strtok (NULL, " =\r\n");
    2619              :                 }
    2620              : 
    2621            1 :                 if (token[0] && value[0]) {
    2622              :                     /* parse arguments here */
    2623            0 :                     if (strcmp(token, "LoggingMode") == 0) {
    2624            0 :                         daemon->mode = atoi(value);
    2625            0 :                         dlt_vlog(LOG_INFO, "Runtime Option: %s=%d\n", token,
    2626              :                                  daemon->mode);
    2627              :                     }
    2628              :                     else {
    2629            0 :                         dlt_vlog(LOG_WARNING, "Unknown option: %s=%s\n", token,
    2630              :                                  value);
    2631              :                     }
    2632              :                 }
    2633              :             }
    2634              :             else {
    2635              :                 break;
    2636              :             }
    2637              :         }
    2638              : 
    2639            1 :         fclose (pFile);
    2640              :     }
    2641              :     else {
    2642            0 :         dlt_vlog(LOG_INFO, "Cannot open configuration file: %s\n", filename);
    2643              :     }
    2644              : 
    2645              :     return 0;
    2646              : }
    2647              : 
    2648            3 : int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, int verbose)
    2649              : {
    2650              :     DltUserHeader userheader;
    2651              :     DltUserControlMsgLogLevel usercontext;
    2652              :     DltReturnValue ret;
    2653              :     DltDaemonApplication *app;
    2654              : 
    2655            3 :     PRINT_FUNCTION_VERBOSE(verbose);
    2656              : 
    2657            3 :     if ((daemon == NULL) || (context == NULL)) {
    2658            0 :         dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
    2659            0 :         return -1;
    2660              :     }
    2661              : 
    2662            3 :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
    2663            0 :         dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
    2664            0 :         return -1;
    2665              :     }
    2666              : 
    2667            3 :     if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
    2668            2 :         (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
    2669            0 :             usercontext.log_level = (uint8_t) (context->log_level >
    2670              :                 context->storage_log_level ? context->log_level : context->storage_log_level);
    2671              :     else /* Storage log level is not updated (is DEFAULT) then  no device is yet connected so ignore */
    2672            3 :         usercontext.log_level =
    2673            3 :             (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
    2674              : 
    2675            3 :     usercontext.trace_status =
    2676            3 :         (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
    2677              : 
    2678            3 :     usercontext.log_level_pos = context->log_level_pos;
    2679              : 
    2680            3 :     dlt_vlog(LOG_NOTICE, "Send log-level to context: %.4s:%.4s [%i -> %i] [%i -> %i]\n",
    2681            3 :              context->apid,
    2682            3 :              context->ctid,
    2683            3 :              context->log_level,
    2684            3 :              usercontext.log_level,
    2685              :              context->trace_status,
    2686              :              usercontext.trace_status);
    2687              : 
    2688              :     /* log to FIFO */
    2689            3 :     errno = 0;
    2690            3 :     ret = dlt_user_log_out2_with_timeout(context->user_handle,
    2691              :                             &(userheader), sizeof(DltUserHeader),
    2692              :                             &(usercontext), sizeof(DltUserControlMsgLogLevel));
    2693              : 
    2694            3 :     if (ret < DLT_RETURN_OK) {
    2695            0 :         dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
    2696              :                  __func__,
    2697            0 :                  errno != 0 ? strerror(errno) : "Unknown error");
    2698              : 
    2699            0 :         if (errno == EPIPE || errno == EBADF) {
    2700            0 :             app = dlt_daemon_application_find(daemon, context->apid, daemon->ecuid, verbose);
    2701            0 :             if (app != NULL)
    2702            0 :                 dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2703              :         }
    2704              :     }
    2705              : 
    2706            3 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2707              : }
    2708              : 
    2709            0 : int dlt_daemon_user_send_log_level_v2(DltDaemon *daemon, DltDaemonContext *context, int verbose)
    2710              : {
    2711              :     DltUserHeader userheader;
    2712              :     DltUserControlMsgLogLevel usercontext;
    2713              :     DltReturnValue ret;
    2714            0 :     DltDaemonApplication *app = (DltDaemonApplication *)malloc(sizeof(DltDaemonApplication));
    2715              : 
    2716            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2717              : 
    2718            0 :     if ((daemon == NULL) || (context == NULL)) {
    2719            0 :         dlt_vlog(LOG_ERR, "NULL parameter in %s", __func__);
    2720            0 :         return -1;
    2721              :     }
    2722              : 
    2723            0 :     if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_LEVEL) < DLT_RETURN_OK) {
    2724            0 :         dlt_vlog(LOG_ERR, "Failed to set userheader in %s", __func__);
    2725            0 :         return -1;
    2726              :     }
    2727              : 
    2728            0 :     if ((context->storage_log_level != DLT_LOG_DEFAULT) &&
    2729            0 :         (daemon->maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_OFF))
    2730            0 :             usercontext.log_level = (uint8_t) (context->log_level >
    2731              :                 context->storage_log_level ? context->log_level : context->storage_log_level);
    2732              :     else /* Storage log level is not updated (is DEFAULT) then  no device is yet connected so ignore */
    2733            0 :         usercontext.log_level =
    2734            0 :             (uint8_t) ((context->log_level == DLT_LOG_DEFAULT) ? daemon->default_log_level : context->log_level);
    2735              : 
    2736            0 :     usercontext.trace_status =
    2737            0 :         (uint8_t) ((context->trace_status == DLT_TRACE_STATUS_DEFAULT) ? daemon->default_trace_status : context->trace_status);
    2738              : 
    2739            0 :     usercontext.log_level_pos = context->log_level_pos;
    2740              : 
    2741            0 :     dlt_vlog(LOG_NOTICE, "Send log-level to context: %s:%s [%i -> %i] [%i -> %i]\n",
    2742              :              context->apid2,
    2743              :              context->ctid2,
    2744            0 :              context->log_level,
    2745            0 :              usercontext.log_level,
    2746              :              context->trace_status,
    2747              :              usercontext.trace_status);
    2748              : 
    2749              :     /* log to FIFO */
    2750            0 :     errno = 0;
    2751            0 :     ret = dlt_user_log_out2_with_timeout(context->user_handle,
    2752              :                             &(userheader), sizeof(DltUserHeader),
    2753              :                             &(usercontext), sizeof(DltUserControlMsgLogLevel));
    2754              : 
    2755            0 :     if (ret < DLT_RETURN_OK) {
    2756            0 :         dlt_vlog(LOG_ERR, "Failed to send data to application in %s: %s",
    2757              :                  __func__,
    2758            0 :                  errno != 0 ? strerror(errno) : "Unknown error");
    2759              : 
    2760            0 :         if (errno == EPIPE || errno == EBADF) {
    2761            0 :             dlt_daemon_application_find_v2(daemon, context->apid2len, context->apid2,
    2762            0 :                                                  daemon->ecuid2len, daemon->ecuid2, verbose, &app);
    2763            0 :             if (app != NULL)
    2764            0 :                 dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2765              :         }
    2766            0 :         free(app);
    2767              :     }
    2768            0 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2769              : }
    2770              : 
    2771            0 : int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
    2772              : {
    2773              :     DltUserHeader userheader;
    2774              :     DltUserControlMsgLogState logstate;
    2775              :     DltReturnValue ret;
    2776              : 
    2777            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2778              : 
    2779            0 :     if ((daemon == NULL) || (app == NULL))
    2780              :         return -1;
    2781              : 
    2782            0 :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
    2783              :         return -1;
    2784              : 
    2785            0 :     logstate.log_state = daemon->connectionState;
    2786              : 
    2787              :     /* log to FIFO */
    2788            0 :     ret = dlt_user_log_out2_with_timeout(app->user_handle,
    2789              :                             &(userheader), sizeof(DltUserHeader),
    2790              :                             &(logstate), sizeof(DltUserControlMsgLogState));
    2791              : 
    2792            0 :     if (ret < DLT_RETURN_OK) {
    2793            0 :         if (errno == EPIPE || errno == EBADF)
    2794            0 :             dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    2795              :     }
    2796              : 
    2797            0 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2798              : }
    2799              : 
    2800            0 : int dlt_daemon_user_send_log_state_v2(DltDaemon *daemon, DltDaemonApplication *app, int verbose)
    2801              : {
    2802              :     DltUserHeader userheader;
    2803              :     DltUserControlMsgLogState logstate;
    2804              :     DltReturnValue ret;
    2805              : 
    2806            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2807              : 
    2808            0 :     if ((daemon == NULL) || (app == NULL))
    2809              :         return -1;
    2810              : 
    2811            0 :     if (dlt_user_set_userheader_v2(&userheader, DLT_USER_MESSAGE_LOG_STATE) < DLT_RETURN_OK)
    2812              :         return -1;
    2813              : 
    2814            0 :     logstate.log_state = daemon->connectionState;
    2815              : 
    2816              :     /* log to FIFO */
    2817            0 :     ret = dlt_user_log_out2_with_timeout(app->user_handle,
    2818              :                             &(userheader), sizeof(DltUserHeader),
    2819              :                             &(logstate.log_state), sizeof(int8_t));
    2820              : 
    2821            0 :     if (ret < DLT_RETURN_OK) {
    2822            0 :         if (errno == EPIPE || errno == EBADF)
    2823            0 :             dlt_daemon_application_reset_user_handle_v2(daemon, app, verbose);
    2824              :     }
    2825              : 
    2826            0 :     return (ret == DLT_RETURN_OK) ? DLT_RETURN_OK : DLT_RETURN_ERROR;
    2827              : }
    2828              : 
    2829            0 : void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,
    2830              :                                                  const char *filename,
    2831              :                                                  const char *filename1,
    2832              :                                                  int InitialContextLogLevel,
    2833              :                                                  int InitialContextTraceStatus,
    2834              :                                                  int InitialEnforceLlTsStatus,
    2835              :                                                  int verbose)
    2836              : {
    2837              :     FILE *fd;
    2838              : 
    2839            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2840              : 
    2841            0 :     if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
    2842            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2843            0 :         return;
    2844              :     }
    2845              : 
    2846            0 :     if ((filename[0] == '\0') || (filename1[0] == '\0')) {
    2847            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
    2848            0 :         return;
    2849              :     }
    2850              : 
    2851              :     /* Check for runtime cfg file and delete it, if available */
    2852            0 :     fd = fopen(filename, "r");
    2853              : 
    2854            0 :     if (fd != NULL) {
    2855              :         /* Close and delete file */
    2856            0 :         fclose(fd);
    2857            0 :         if (unlink(filename) != 0) {
    2858            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2859            0 :                     __func__, strerror(errno));
    2860              :         }
    2861              :     }
    2862              : 
    2863            0 :     fd = fopen(filename1, "r");
    2864              : 
    2865            0 :     if (fd != NULL) {
    2866              :         /* Close and delete file */
    2867            0 :         fclose(fd);
    2868            0 :         if (unlink(filename1) != 0) {
    2869            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2870            0 :                     __func__, strerror(errno));
    2871              :         }
    2872              :     }
    2873              : 
    2874            0 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
    2875            0 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
    2876            0 :     daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
    2877              : 
    2878              :     /* Reset all other things (log level, trace status, etc.
    2879              :      *                         to default values             */
    2880              : 
    2881              :     /* Inform user libraries about changed default log level/trace status */
    2882            0 :     dlt_daemon_user_send_default_update(daemon, verbose);
    2883              : }
    2884              : 
    2885            0 : void dlt_daemon_control_reset_to_factory_default_v2(DltDaemon *daemon,
    2886              :                                                  const char *filename,
    2887              :                                                  const char *filename1,
    2888              :                                                  int InitialContextLogLevel,
    2889              :                                                  int InitialContextTraceStatus,
    2890              :                                                  int InitialEnforceLlTsStatus,
    2891              :                                                  int verbose)
    2892              : {
    2893              :     FILE *fd;
    2894              : 
    2895            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2896              : 
    2897            0 :     if ((daemon == NULL) || (filename == NULL) || (filename1 == NULL)) {
    2898            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2899            0 :         return;
    2900              :     }
    2901              : 
    2902            0 :     if ((filename[0] == '\0') || (filename1[0] == '\0')) {
    2903            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Empty string\n");
    2904            0 :         return;
    2905              :     }
    2906              : 
    2907              :     /* Check for runtime cfg file and delete it, if available */
    2908            0 :     fd = fopen(filename, "r");
    2909              : 
    2910            0 :     if (fd != NULL) {
    2911              :         /* Close and delete file */
    2912            0 :         fclose(fd);
    2913            0 :         if (unlink(filename) != 0) {
    2914            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2915            0 :                     __func__, strerror(errno));
    2916              :         }
    2917              :     }
    2918              : 
    2919            0 :     fd = fopen(filename1, "r");
    2920              : 
    2921            0 :     if (fd != NULL) {
    2922              :         /* Close and delete file */
    2923            0 :         fclose(fd);
    2924            0 :         if (unlink(filename1) != 0) {
    2925            0 :             dlt_vlog(LOG_WARNING, "%s: unlink() failed: %s\n",
    2926            0 :                     __func__, strerror(errno));
    2927              :         }
    2928              :     }
    2929              : 
    2930            0 :     daemon->default_log_level = (int8_t) InitialContextLogLevel;
    2931            0 :     daemon->default_trace_status = (int8_t) InitialContextTraceStatus;
    2932            0 :     daemon->force_ll_ts = (int8_t) InitialEnforceLlTsStatus;
    2933              : 
    2934              :     /* Reset all other things (log level, trace status, etc.
    2935              :      *                         to default values             */
    2936              : 
    2937              :     /* Inform user libraries about changed default log level/trace status */
    2938            0 :     dlt_daemon_user_send_default_update_v2(daemon, verbose);
    2939              : }
    2940              : 
    2941            0 : void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
    2942              : {
    2943              :     int32_t count;
    2944              :     DltDaemonContext *context;
    2945              :     DltDaemonRegisteredUsers *user_list = NULL;
    2946              : 
    2947            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2948              : 
    2949            0 :     if (daemon == NULL) {
    2950            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2951            0 :         return;
    2952              :     }
    2953              : 
    2954            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    2955              : 
    2956            0 :     if (user_list == NULL)
    2957              :         return;
    2958              : 
    2959            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    2960            0 :         context = &(user_list->contexts[count]);
    2961              : 
    2962            0 :         if (context != NULL) {
    2963            0 :             if ((context->log_level == DLT_LOG_DEFAULT) ||
    2964            0 :                 (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
    2965            0 :                 if (context->user_handle >= DLT_FD_MINIMUM)
    2966            0 :                     if (dlt_daemon_user_send_log_level(daemon,
    2967              :                                                        context,
    2968              :                                                        verbose) == -1)
    2969            0 :                         dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
    2970              :             }
    2971              :         }
    2972              :     }
    2973              : }
    2974              : 
    2975            0 : void dlt_daemon_user_send_default_update_v2(DltDaemon *daemon, int verbose)
    2976              : {
    2977              :     int32_t count;
    2978              :     DltDaemonContext *context;
    2979              :     DltDaemonRegisteredUsers *user_list = NULL;
    2980              : 
    2981            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2982              : 
    2983            0 :     if (daemon == NULL) {
    2984            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    2985            0 :         return;
    2986              :     }
    2987              : 
    2988            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    2989              : 
    2990            0 :     if (user_list == NULL)
    2991              :         return;
    2992              : 
    2993            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    2994            0 :         context = &(user_list->contexts[count]);
    2995              : 
    2996            0 :         if (context != NULL) {
    2997            0 :             if ((context->log_level == DLT_LOG_DEFAULT) ||
    2998            0 :                 (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) {
    2999            0 :                 if (context->user_handle >= DLT_FD_MINIMUM)
    3000            0 :                     if (dlt_daemon_user_send_log_level_v2(daemon,
    3001              :                                                        context,
    3002              :                                                        verbose) == -1)
    3003            0 :                         dlt_vlog(LOG_WARNING, "Cannot update default of %.4s:%.4s\n", context->apid, context->ctid);
    3004              :             }
    3005              :         }
    3006              :     }
    3007              : }
    3008              : 
    3009            0 : void dlt_daemon_user_send_all_log_level_update(DltDaemon *daemon,
    3010              :                                                int enforce_context_ll_and_ts,
    3011              :                                                int8_t context_log_level,
    3012              :                                                int8_t log_level,
    3013              :                                                int verbose)
    3014              : {
    3015              :     int32_t count = 0;
    3016              :     DltDaemonContext *context = NULL;
    3017              :     DltDaemonRegisteredUsers *user_list = NULL;
    3018              : 
    3019            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3020              : 
    3021            0 :     if (daemon == NULL)
    3022              :         return;
    3023              : 
    3024            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    3025              : 
    3026            0 :     if (user_list == NULL)
    3027              :         return;
    3028              : 
    3029            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3030            0 :         context = &(user_list->contexts[count]);
    3031              : 
    3032            0 :         if (context) {
    3033            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3034            0 :                 context->log_level = log_level;
    3035              : 
    3036            0 :                 if (enforce_context_ll_and_ts) {
    3037              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    3038              :                     DltDaemonContextLogSettings *settings =
    3039              :                         dlt_daemon_find_configured_app_id_ctx_id_settings(
    3040              :                             daemon, context->apid, context->ctid);
    3041              :                     if (settings != NULL) {
    3042              :                         if (log_level > settings->log_level) {
    3043              :                           context->log_level = settings->log_level;
    3044              :                         }
    3045              :                     } else
    3046              : #endif
    3047            0 :                     if (log_level > context_log_level) {
    3048            0 :                         context->log_level = (int8_t)context_log_level;
    3049              :                     }
    3050              :                 }
    3051              : 
    3052            0 :                 if (dlt_daemon_user_send_log_level(daemon,
    3053              :                                                    context,
    3054              :                                                    verbose) == -1)
    3055            0 :                     dlt_vlog(LOG_WARNING,
    3056              :                              "Cannot send log level %.4s:%.4s -> %i\n",
    3057            0 :                              context->apid,
    3058            0 :                              context->ctid,
    3059            0 :                              context->log_level);
    3060              :             }
    3061              :         }
    3062              :     }
    3063              : }
    3064              : 
    3065            0 : void dlt_daemon_user_send_all_log_level_update_v2(DltDaemon *daemon,
    3066              :                                                int enforce_context_ll_and_ts,
    3067              :                                                int8_t context_log_level,
    3068              :                                                int8_t log_level,
    3069              :                                                int verbose)
    3070              : {
    3071              :     int32_t count = 0;
    3072              :     DltDaemonContext *context = NULL;
    3073              :     DltDaemonRegisteredUsers *user_list = NULL;
    3074              : 
    3075            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3076              : 
    3077            0 :     if (daemon == NULL)
    3078              :         return;
    3079              : 
    3080            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    3081              : 
    3082            0 :     if (user_list == NULL)
    3083              :         return;
    3084              : 
    3085            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3086            0 :         context = &(user_list->contexts[count]);
    3087              : 
    3088            0 :         if (context) {
    3089            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3090            0 :                 context->log_level = log_level;
    3091              : 
    3092            0 :                 if (enforce_context_ll_and_ts) {
    3093              : #ifdef DLT_LOG_LEVEL_APP_CONFIG
    3094              :                     //TBD: Check if function params require apid/ctid lengths
    3095              :                     DltDaemonContextLogSettingsV2 *settings =
    3096              :                         dlt_daemon_find_configured_app_id_ctx_id_settings_v2(
    3097              :                             daemon, context->apid, context->ctid);
    3098              :                     if (settings != NULL) {
    3099              :                         if (log_level > settings->log_level) {
    3100              :                           context->log_level = settings->log_level;
    3101              :                         }
    3102              :                     } else
    3103              : #endif
    3104            0 :                     if (log_level > context_log_level) {
    3105            0 :                         context->log_level = (int8_t)context_log_level;
    3106              :                     }
    3107              :                 }
    3108              : 
    3109            0 :                 if (dlt_daemon_user_send_log_level_v2(daemon,
    3110              :                                                    context,
    3111              :                                                    verbose) == -1)
    3112            0 :                     dlt_vlog(LOG_WARNING,
    3113              :                              "Cannot send log level %.4s:%.4s -> %i\n",
    3114            0 :                              context->apid,
    3115            0 :                              context->ctid,
    3116            0 :                              context->log_level);
    3117              :             }
    3118              :         }
    3119              :     }
    3120              : }
    3121              : 
    3122            0 : void dlt_daemon_user_send_all_trace_status_update(DltDaemon *daemon, int8_t trace_status, int verbose)
    3123              : {
    3124              :     int32_t count = 0;
    3125              :     DltDaemonContext *context = NULL;
    3126              :     DltDaemonRegisteredUsers *user_list = NULL;
    3127              : 
    3128            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3129              : 
    3130            0 :     if (daemon == NULL)
    3131              :         return;
    3132              : 
    3133            0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    3134              : 
    3135            0 :     if (user_list == NULL)
    3136              :         return;
    3137              : 
    3138            0 :     dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
    3139              : 
    3140            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3141            0 :         context = &(user_list->contexts[count]);
    3142              : 
    3143            0 :         if (context) {
    3144            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3145            0 :                 context->trace_status = trace_status;
    3146              : 
    3147            0 :                 if (dlt_daemon_user_send_log_level(daemon, context, verbose) == -1)
    3148            0 :                     dlt_vlog(LOG_WARNING,
    3149              :                              "Cannot send trace status %.4s:%.4s -> %i\n",
    3150            0 :                              context->apid,
    3151            0 :                              context->ctid,
    3152            0 :                              context->trace_status);
    3153              :             }
    3154              :         }
    3155              :     }
    3156              : }
    3157              : 
    3158            0 : void dlt_daemon_user_send_all_trace_status_update_v2(DltDaemon *daemon, int8_t trace_status, int verbose)
    3159              : {
    3160              :     int32_t count = 0;
    3161              :     DltDaemonContext *context = NULL;
    3162              :     DltDaemonRegisteredUsers *user_list = NULL;
    3163              : 
    3164            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3165              : 
    3166            0 :     if (daemon == NULL)
    3167              :         return;
    3168              : 
    3169            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    3170              : 
    3171            0 :     if (user_list == NULL)
    3172              :         return;
    3173              : 
    3174            0 :     dlt_vlog(LOG_NOTICE, "All trace status is updated -> %i\n", trace_status);
    3175              : 
    3176            0 :     for (count = 0; count < user_list->num_contexts; count++) {
    3177            0 :         context = &(user_list->contexts[count]);
    3178              : 
    3179            0 :         if (context) {
    3180            0 :             if (context->user_handle >= DLT_FD_MINIMUM) {
    3181            0 :                 context->trace_status = trace_status;
    3182              : 
    3183            0 :                 if (dlt_daemon_user_send_log_level_v2(daemon, context, verbose) == -1)
    3184            0 :                     dlt_vlog(LOG_WARNING,
    3185              :                              "Cannot send trace status %.*s:%.*s -> %i\n",
    3186            0 :                              context->apid2len,
    3187              :                              context->apid2,
    3188            0 :                              context->ctid2len,
    3189              :                              context->ctid2,
    3190            0 :                              context->trace_status);
    3191              :             }
    3192              :         }
    3193              :     }
    3194              : }
    3195              : 
    3196            1 : void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
    3197              : {
    3198              :     int32_t count;
    3199              :     DltDaemonApplication *app;
    3200              :     DltDaemonRegisteredUsers *user_list = NULL;
    3201              : 
    3202            1 :     PRINT_FUNCTION_VERBOSE(verbose);
    3203              : 
    3204            1 :     if (daemon == NULL) {
    3205            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3206            0 :         return;
    3207              :     }
    3208              : 
    3209            1 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    3210              : 
    3211            1 :     if (user_list == NULL)
    3212              :         return;
    3213              : 
    3214            1 :     for (count = 0; count < user_list->num_applications; count++) {
    3215            0 :         app = &(user_list->applications[count]);
    3216              : 
    3217            0 :         if (app != NULL) {
    3218            0 :             if (app->user_handle >= DLT_FD_MINIMUM) {
    3219            0 :                 if (dlt_daemon_user_send_log_state(daemon, app, verbose) == -1)
    3220            0 :                     dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %.4s, PID: %d %s\n", app->apid, app->pid, __func__);
    3221              :             }
    3222              :         }
    3223              :     }
    3224              : }
    3225              : 
    3226            0 : void dlt_daemon_user_send_all_log_state_v2(DltDaemon *daemon, int verbose)
    3227              : {
    3228              :     int32_t count;
    3229              :     DltDaemonApplication *app;
    3230              :     DltDaemonRegisteredUsers *user_list = NULL;
    3231              : 
    3232            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3233              : 
    3234            0 :     if (daemon == NULL) {
    3235            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3236            0 :         return;
    3237              :     }
    3238              : 
    3239            0 :     user_list = dlt_daemon_find_users_list_v2(daemon, daemon->ecuid2len, daemon->ecuid2, verbose);
    3240              : 
    3241            0 :     if (user_list == NULL)
    3242              :         return;
    3243              : 
    3244            0 :     for (count = 0; count < user_list->num_applications; count++) {
    3245            0 :         app = &(user_list->applications[count]);
    3246              : 
    3247            0 :         if (app != NULL) {
    3248            0 :             if (app->user_handle >= DLT_FD_MINIMUM) {
    3249            0 :                 if (dlt_daemon_user_send_log_state_v2(daemon, app, verbose) == -1) {
    3250            0 :                     dlt_vlog(LOG_WARNING, "Cannot send log state to Apid: %s, PID: %d %s\n", app->apid2, app->pid, __func__);
    3251              :                 }
    3252              :             }
    3253              :         }
    3254              :     }
    3255              : }
    3256              : 
    3257            2 : void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
    3258              : {
    3259            2 :     switch (newState) {
    3260            0 :     case DLT_DAEMON_STATE_INIT:
    3261            0 :         dlt_log(LOG_INFO, "Switched to init state.\n");
    3262            0 :         daemon->state = DLT_DAEMON_STATE_INIT;
    3263            0 :         break;
    3264            2 :     case DLT_DAEMON_STATE_BUFFER:
    3265            2 :         dlt_log(LOG_INFO, "Switched to buffer state for socket connections.\n");
    3266            2 :         daemon->state = DLT_DAEMON_STATE_BUFFER;
    3267            2 :         break;
    3268            0 :     case DLT_DAEMON_STATE_BUFFER_FULL:
    3269            0 :         dlt_log(LOG_INFO, "Switched to buffer full state.\n");
    3270            0 :         daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
    3271            0 :         break;
    3272            0 :     case DLT_DAEMON_STATE_SEND_BUFFER:
    3273            0 :         dlt_log(LOG_INFO, "Switched to send buffer state for socket connections.\n");
    3274            0 :         daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
    3275            0 :         break;
    3276            0 :     case DLT_DAEMON_STATE_SEND_DIRECT:
    3277            0 :         dlt_log(LOG_INFO, "Switched to send direct state.\n");
    3278            0 :         daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;
    3279            0 :         break;
    3280              :     }
    3281            2 : }
    3282              : 
    3283              : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
    3284              : bool dlt_daemon_trigger_systemd_watchdog_if_necessary(DltDaemon *daemon) {
    3285              :     if (daemon->watchdog_trigger_interval == 0) {
    3286              :         return false;
    3287              :     }
    3288              : 
    3289              :     const unsigned int uptime_seconds = dlt_uptime() / 10000;
    3290              :     const unsigned int seconds_since_last_trigger = uptime_seconds - daemon->watchdog_last_trigger_time;
    3291              :     if (seconds_since_last_trigger < daemon->watchdog_trigger_interval) {
    3292              :         return false;
    3293              :     }
    3294              :     if (sd_notify(0, "WATCHDOG=1") < 0) {
    3295              :         dlt_vlog(LOG_WARNING, "%s: Could not reset systemd watchdog\n", __func__);
    3296              :         return false;
    3297              :     }
    3298              :     else
    3299              :         daemon->watchdog_last_trigger_time = uptime_seconds;
    3300              : 
    3301              :     return true;
    3302              : }
    3303              : 
    3304              : #endif
    3305              : 
    3306              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    3307              : int dlt_daemon_user_send_trace_load_config(DltDaemon *const daemon, DltDaemonApplication *app, const int verbose)
    3308              : {
    3309              :     DltUserHeader userheader;
    3310              :     DltUserControlMsgTraceSettingMsg* trace_load_settings_user_msg;
    3311              :     uint32_t trace_load_settings_count;
    3312              :     DltReturnValue ret;
    3313              : 
    3314              : 
    3315              :     PRINT_FUNCTION_VERBOSE(verbose);
    3316              : 
    3317              :     if ((daemon == NULL) || (app == NULL)) return -1;
    3318              : 
    3319              :     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_TRACE_LOAD) < DLT_RETURN_OK) return -1;
    3320              : 
    3321              :     DltTraceLoadSettings* app_settings = app->trace_load_settings;
    3322              : 
    3323              :     if (app_settings != NULL) {
    3324              :         trace_load_settings_count = app->trace_load_settings_count;
    3325              :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    3326              :         for (uint32_t i = 0U; i < trace_load_settings_count; i++) {
    3327              :             // App id is not transmitted as the user library only
    3328              :             // has one application ID
    3329              :             memcpy(trace_load_settings_user_msg[i].ctid, app_settings[i].ctid, DLT_ID_SIZE);
    3330              :             trace_load_settings_user_msg[i].soft_limit = app_settings[i].soft_limit;
    3331              :             trace_load_settings_user_msg[i].hard_limit = app_settings[i].hard_limit;
    3332              : 
    3333              :             if (app_settings[i].ctid[0] == '\0') {
    3334              :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, soft limit %u, hard limit %u\n",
    3335              :                          app->apid,
    3336              :                          app_settings[i].soft_limit,
    3337              :                          app_settings[i].hard_limit);
    3338              :             } else {
    3339              :                 dlt_vlog(LOG_NOTICE, "Sending trace load config to app %.4s, ctid %.4s, soft limit %u, hard limit %u\n",
    3340              :                          app->apid,
    3341              :                          app_settings[i].ctid,
    3342              :                          app_settings[i].soft_limit,
    3343              :                          app_settings[i].hard_limit);
    3344              :             }
    3345              : 
    3346              :         }
    3347              :     }
    3348              :     else {
    3349              :         dlt_vlog(LOG_INFO,
    3350              :                  "No trace load settings for application %s, setting daemon defaults.\n", app->apid);
    3351              : 
    3352              :         trace_load_settings_count = 1;
    3353              :         trace_load_settings_user_msg = malloc(sizeof(DltUserControlMsgTraceSettingMsg));
    3354              : 
    3355              :         memset(trace_load_settings_user_msg, 0, sizeof(DltTraceLoadSettings));
    3356              :         trace_load_settings_user_msg[0].soft_limit = DLT_TRACE_LOAD_DAEMON_SOFT_LIMIT_DEFAULT;
    3357              :         trace_load_settings_user_msg[0].hard_limit = DLT_TRACE_LOAD_DAEMON_HARD_LIMIT_DEFAULT;
    3358              :     }
    3359              : 
    3360              :     /* log to FIFO */
    3361              :     ret = dlt_user_log_out3_with_timeout(app->user_handle,
    3362              :                                          &(userheader), sizeof(DltUserHeader),
    3363              :                                          &(trace_load_settings_count), sizeof(uint32_t),
    3364              :                                          trace_load_settings_user_msg, sizeof(DltUserControlMsgTraceSettingMsg) * trace_load_settings_count);
    3365              : 
    3366              :     if (ret < DLT_RETURN_OK) {
    3367              :         if (errno == EPIPE || errno == EBADF)
    3368              :             dlt_daemon_application_reset_user_handle(daemon, app, verbose);
    3369              :     }
    3370              : 
    3371              :     free(trace_load_settings_user_msg);
    3372              : 
    3373              :     return ret;
    3374              : }
    3375              : #endif
        

Generated by: LCOV version 2.0-1