LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_common.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 28.0 % 1038 291
Test Date: 2026-08-27 10:11:10 Functions: 38.9 % 54 21

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

Generated by: LCOV version 2.0-1