LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_client.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 261 966 27.0 %
Date: 2024-10-22 04:07:23 Functions: 13 33 39.4 %

          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
      18             :  * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
      19             :  * Markus Klein <Markus.Klein@esk.fraunhofer.de>
      20             :  * Mikko Rapeli <mikko.rapeli@bmw.de>
      21             :  *
      22             :  * \copyright Copyright © 2011-2015 BMW AG. \n
      23             :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      24             :  *
      25             :  * \file dlt_daemon_client.c
      26             :  */
      27             : 
      28             : #include <netdb.h>
      29             : #include <ctype.h>
      30             : #include <stdio.h>      /* for printf() and fprintf() */
      31             : #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
      32             : #include <sys/stat.h>   /* for stat() */
      33             : #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
      34             : #include <stdlib.h>     /* for atoi() and exit() */
      35             : #include <string.h>     /* for memset() */
      36             : #include <unistd.h>     /* for close() */
      37             : #include <signal.h>
      38             : #include <syslog.h>
      39             : #include <errno.h>
      40             : #include <pthread.h>
      41             : 
      42             : #ifdef linux
      43             : #   include <sys/timerfd.h>
      44             : #endif
      45             : #include <sys/time.h>
      46             : #if defined(linux) && defined(__NR_statx)
      47             : #   include <linux/stat.h>
      48             : #endif
      49             : 
      50             : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
      51             : #   include <systemd/sd-daemon.h>
      52             : #endif
      53             : 
      54             : #include "dlt_types.h"
      55             : #include "dlt_log.h"
      56             : #include "dlt-daemon.h"
      57             : #include "dlt-daemon_cfg.h"
      58             : #include "dlt_daemon_common_cfg.h"
      59             : 
      60             : #include "dlt_daemon_socket.h"
      61             : #include "dlt_daemon_serial.h"
      62             : 
      63             : #include "dlt_daemon_client.h"
      64             : #include "dlt_daemon_connection.h"
      65             : #include "dlt_daemon_event_handler.h"
      66             : 
      67             : #include "dlt_daemon_offline_logstorage.h"
      68             : #include "dlt_gateway.h"
      69             : 
      70             : /** Inline function to calculate/set the requested log level or traces status
      71             :  *  with default log level or trace status when "ForceContextLogLevelAndTraceStatus"
      72             :  *  is enabled and set to 1 in dlt.conf file.
      73             :  *
      74             :  * @param request_log The requested log level (or) trace status
      75             :  * @param context_log The default log level (or) trace status
      76             :  *
      77             :  * @return The log level if requested log level is lower or equal to ContextLogLevel
      78             :  */
      79             : static inline int8_t getStatus(uint8_t request_log, int context_log)
      80             : {
      81           0 :     return (request_log <= context_log) ? request_log : context_log;
      82             : }
      83             : 
      84             : #ifdef UDP_CONNECTION_SUPPORT
      85             : #   include "dlt_daemon_udp_socket.h"
      86             : #endif
      87             : 
      88             : /** @brief Sends up to 2 messages to all the clients.
      89             :  *
      90             :  * Runs through the client list and sends the messages to them. If the message
      91             :  * transfer fails and the connection is a socket connection, the socket is closed.
      92             :  * Takes and release dlt_daemon_mutex.
      93             :  *
      94             :  * @param daemon Daemon structure needed for socket closure.
      95             :  * @param daemon_local Daemon local structure
      96             :  * @param data1 The first message to be sent.
      97             :  * @param size1 The size of the first message.
      98             :  * @param data2 The second message to be send.
      99             :  * @param size2 The second message size.
     100             :  * @param verbose Needed for socket closure.
     101             :  *
     102             :  * @return The amount of data transfered.
     103             :  */
     104         214 : static int dlt_daemon_client_send_all_multiple(DltDaemon *daemon,
     105             :                                                DltDaemonLocal *daemon_local,
     106             :                                                void *data1,
     107             :                                                int size1,
     108             :                                                void *data2,
     109             :                                                int size2,
     110             :                                                int verbose)
     111             : {
     112             :     int sent = 0;
     113             :     unsigned int i = 0;
     114             :     int ret = 0;
     115             :     DltConnection *temp = NULL;
     116             :     int type_mask =
     117             :         (DLT_CON_MASK_CLIENT_MSG_TCP | DLT_CON_MASK_CLIENT_MSG_SERIAL);
     118             : 
     119         214 :     PRINT_FUNCTION_VERBOSE(verbose);
     120             : 
     121         214 :     if ((daemon == NULL) || (daemon_local == NULL)) {
     122           0 :         dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
     123           0 :         return 0;
     124             :     }
     125             : 
     126        1286 :     for (i = 0; i < daemon_local->pEvent.nfds; i++)
     127             :     {
     128        1072 :         temp = dlt_event_handler_find_connection(&(daemon_local->pEvent),
     129        1072 :                                         daemon_local->pEvent.pfd[i].fd);
     130             : 
     131        1072 :         if ((temp == NULL) || (temp->receiver == NULL) ||
     132        1072 :             !((1 << temp->type) & type_mask)) {
     133         856 :             dlt_log(LOG_DEBUG, "The connection not found or the connection type not TCP/Serial.\n");
     134         856 :             continue;
     135             :         }
     136             : 
     137         216 :         ret = dlt_connection_send_multiple(temp,
     138             :                                            data1,
     139             :                                            size1,
     140             :                                            data2,
     141             :                                            size2,
     142             :                                            daemon->sendserialheader);
     143             : 
     144         216 :         if ((ret != DLT_DAEMON_ERROR_OK) &&
     145           0 :             (DLT_CONNECTION_CLIENT_MSG_TCP == temp->type)) {
     146           0 :             dlt_daemon_close_socket(temp->receiver->fd,
     147             :                                     daemon,
     148             :                                     daemon_local,
     149             :                                     verbose);
     150             :         }
     151             : 
     152         216 :         if (ret != DLT_DAEMON_ERROR_OK)
     153           0 :             dlt_vlog(LOG_WARNING, "%s: send dlt message failed\n", __func__);
     154             :         else
     155             :             /* If sent to at  least one client,
     156             :              * then do not store in ring buffer
     157             :              */
     158             :             sent = 1;
     159             :     } /* for */
     160             : 
     161             : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     162             :     if (sent)
     163             :     {
     164             :         const uint32_t serial_header = daemon->sendserialheader ? sizeof(dltSerialHeader) : 0;
     165             :         daemon->bytes_sent += size1 + size2 + serial_header;
     166             :     }
     167             : #endif
     168             : 
     169             :     return sent;
     170             : }
     171             : 
     172        5886 : int dlt_daemon_client_send(int sock,
     173             :                            DltDaemon *daemon,
     174             :                            DltDaemonLocal *daemon_local,
     175             :                            void *storage_header,
     176             :                            int storage_header_size,
     177             :                            void *data1,
     178             :                            int size1,
     179             :                            void *data2,
     180             :                            int size2,
     181             :                            int verbose)
     182             : {
     183             :     int sent, ret;
     184             :     int ret_logstorage = 0;
     185             :     static int sent_message_overflow_cnt = 0;
     186             : 
     187        5886 :     if ((daemon == NULL) || (daemon_local == NULL)) {
     188           0 :         dlt_vlog(LOG_ERR, "%s: Invalid arguments\n", __func__);
     189           0 :         return DLT_DAEMON_ERROR_UNKNOWN;
     190             :     }
     191             : 
     192        5886 :     if ((sock != DLT_DAEMON_SEND_TO_ALL) && (sock != DLT_DAEMON_SEND_FORCE)) {
     193             :         /* Send message to specific socket */
     194          16 :         if (isatty(sock)) {
     195           0 :             if ((ret =
     196           0 :                      dlt_daemon_serial_send(sock, data1, size1, data2, size2,
     197           0 :                                             daemon->sendserialheader))) {
     198           0 :                 dlt_vlog(LOG_WARNING, "%s: serial send dlt message failed\n", __func__);
     199           0 :                 return ret;
     200             :             }
     201             :         } else {
     202          16 :             if ((ret =
     203          16 :                      dlt_daemon_socket_send(sock, data1, size1, data2, size2,
     204          16 :                                             daemon->sendserialheader))) {
     205           0 :                 dlt_vlog(LOG_WARNING, "%s: socket send dlt message failed\n", __func__);
     206           0 :                 return ret;
     207             :             }
     208             :         }
     209             : 
     210          16 :         return DLT_DAEMON_ERROR_OK;
     211             :     }
     212             : 
     213             :     /* write message to offline trace */
     214             :     /* In the SEND_BUFFER state we must skip offline tracing because the offline traces */
     215             :     /* are going without buffering directly to the offline trace. Thus we have to filter out */
     216             :     /* the traces that are coming from the buffer. */
     217        5870 :     if ((sock != DLT_DAEMON_SEND_FORCE) && (daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)) {
     218        5866 :         if (((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
     219           0 :             && daemon_local->flags.offlineTraceDirectory[0]) {
     220           0 :             if (dlt_offline_trace_write(&(daemon_local->offlineTrace), storage_header, storage_header_size, data1,
     221             :                                         size1, data2, size2)) {
     222             :                 static int error_dlt_offline_trace_write_failed = 0;
     223             : 
     224           0 :                 if (!error_dlt_offline_trace_write_failed) {
     225           0 :                     dlt_vlog(LOG_ERR, "%s: dlt_offline_trace_write failed!\n", __func__);
     226           0 :                     error_dlt_offline_trace_write_failed = 1;
     227             :                 }
     228             : 
     229             :                 /*return DLT_DAEMON_ERROR_WRITE_FAILED; */
     230             :             }
     231             :         }
     232             : 
     233             :         /* write messages to offline logstorage only if there is an extended header set
     234             :          * this need to be checked because the function is dlt_daemon_client_send is called by
     235             :          * newly introduced dlt_daemon_log_internal */
     236        5866 :         if (daemon_local->flags.offlineLogstorageMaxDevices > 0)
     237        5839 :             ret_logstorage = dlt_daemon_logstorage_write(daemon,
     238             :                                                          &daemon_local->flags,
     239             :                                                          storage_header,
     240             :                                                          storage_header_size,
     241             :                                                          data1,
     242             :                                                          size1,
     243             :                                                          data2,
     244             :                                                          size2);
     245             :     }
     246             : 
     247             :     /* send messages to daemon socket */
     248        5870 :     if ((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) {
     249             : #ifdef UDP_CONNECTION_SUPPORT
     250             :         if (daemon_local->UDPConnectionSetup == MULTICAST_CONNECTION_ENABLED) {
     251             :             /* Forward message to network client if network routing is not disabled */
     252             :             if (ret_logstorage != 1) {
     253             :                 dlt_daemon_udp_dltmsg_multicast(data1,
     254             :                                                 size1,
     255             :                                                 data2,
     256             :                                                 size2,
     257             :                                                 verbose);
     258             :             }
     259             :         }
     260             : 
     261             : #endif
     262             : 
     263        5870 :         if ((sock == DLT_DAEMON_SEND_FORCE) || (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT)) {
     264             :             /* Forward message to network client if network routing is not disabled */
     265         415 :             if (ret_logstorage != 1) {
     266         214 :                 sent = dlt_daemon_client_send_all_multiple(daemon,
     267             :                                                            daemon_local,
     268             :                                                            data1,
     269             :                                                            size1,
     270             :                                                            data2,
     271             :                                                            size2,
     272             :                                                            verbose);
     273             : 
     274         214 :                 if ((sock == DLT_DAEMON_SEND_FORCE) && !sent) {
     275             :                     return DLT_DAEMON_ERROR_SEND_FAILED;
     276             :                 }
     277             :             }
     278             :         }
     279             :     }
     280             : 
     281             :     /* Message was not sent to client, so store it in client ringbuffer */
     282        5870 :     if ((sock != DLT_DAEMON_SEND_FORCE) &&
     283        5866 :         ((daemon->state == DLT_DAEMON_STATE_BUFFER) || (daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
     284             :          (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL))) {
     285        5455 :         if (daemon->state != DLT_DAEMON_STATE_BUFFER_FULL) {
     286             :             /* Store message in history buffer */
     287        5455 :             ret = dlt_buffer_push3(&(daemon->client_ringbuffer), data1, size1, data2, size2, 0, 0);
     288        5455 :             if (ret < DLT_RETURN_OK) {
     289           0 :                 dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_BUFFER_FULL);
     290             :             }
     291             :         }
     292        5455 :         if (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL) {
     293           0 :             daemon->overflow_counter += 1;
     294           0 :             if (daemon->overflow_counter == 1)
     295           0 :                 dlt_vlog(LOG_INFO, "%s: Buffer is full! Messages will be discarded.\n", __func__);
     296             : 
     297           0 :             return DLT_DAEMON_ERROR_BUFFER_FULL;
     298             :         }
     299             :     } else {
     300         415 :         if ((daemon->overflow_counter > 0) &&
     301           0 :             (daemon_local->client_connections > 0)) {
     302           0 :             sent_message_overflow_cnt++;
     303           0 :             if (sent_message_overflow_cnt >= 2) {
     304           0 :                 sent_message_overflow_cnt--;
     305             :             }
     306             :             else {
     307           0 :                 if (dlt_daemon_send_message_overflow(daemon, daemon_local,
     308             :                                           verbose) == DLT_DAEMON_ERROR_OK) {
     309           0 :                     dlt_vlog(LOG_WARNING,
     310             :                              "%s: %u messages discarded! Now able to send messages to the client.\n",
     311             :                              __func__,
     312             :                              daemon->overflow_counter);
     313           0 :                     daemon->overflow_counter = 0;
     314           0 :                     sent_message_overflow_cnt--;
     315             :                 }
     316             :             }
     317             :         }
     318             :     }
     319             : 
     320             :     return DLT_DAEMON_ERROR_OK;
     321             : 
     322             : }
     323             : 
     324        5809 : int dlt_daemon_client_send_message_to_all_client(DltDaemon *daemon,
     325             :                                        DltDaemonLocal *daemon_local,
     326             :                                        int verbose)
     327             : {
     328             :     static char text[DLT_DAEMON_TEXTSIZE];
     329             :     char * ecu_ptr = NULL;
     330             : 
     331        5809 :     PRINT_FUNCTION_VERBOSE(verbose);
     332             : 
     333        5809 :     if ((daemon == NULL) || (daemon_local == NULL)) {
     334           0 :         dlt_vlog(LOG_ERR, "%s: invalid arguments\n", __func__);
     335           0 :         return DLT_DAEMON_ERROR_UNKNOWN;
     336             :     }
     337             : 
     338             :     /* set overwrite ecu id */
     339        5809 :     if ((daemon_local->flags.evalue[0]) &&
     340           0 :         (strncmp(daemon_local->msg.headerextra.ecu,
     341             :                  DLT_DAEMON_ECU_ID, DLT_ID_SIZE) == 0)) {
     342             :         /* Set header extra parameters */
     343           0 :         dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid);
     344             : 
     345             :         /*msg.headerextra.seid = 0; */
     346           0 :         if (dlt_message_set_extraparameters(&(daemon_local->msg), 0)) {
     347           0 :             dlt_vlog(LOG_WARNING,
     348             :                      "%s: failed to set message extra parameters.\n", __func__);
     349           0 :             return DLT_DAEMON_ERROR_UNKNOWN;
     350             :         }
     351             : 
     352             :         /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
     353           0 :         daemon_local->msg.headerextra.tmsp =
     354           0 :                         DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
     355             :     }
     356             : 
     357             :     /* prepare storage header */
     358        5809 :     if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) {
     359        5809 :         ecu_ptr = daemon_local->msg.headerextra.ecu;
     360             :     } else {
     361           0 :         ecu_ptr = daemon->ecuid;
     362             :     }
     363             : 
     364        5809 :     if (dlt_set_storageheader(daemon_local->msg.storageheader, ecu_ptr)) {
     365           0 :         dlt_vlog(LOG_WARNING,
     366             :                  "%s: failed to set storage header with header type: 0x%x\n",
     367           0 :                  __func__, daemon_local->msg.standardheader->htyp);
     368           0 :         return DLT_DAEMON_ERROR_UNKNOWN;
     369             :     }
     370             : 
     371             :     /* if no filter set or filter is matching display message */
     372        5809 :     if (daemon_local->flags.xflag) {
     373           0 :         if (DLT_RETURN_OK !=
     374           0 :             dlt_message_print_hex(&(daemon_local->msg), text,
     375             :                                   DLT_DAEMON_TEXTSIZE, verbose))
     376           0 :             dlt_log(LOG_WARNING, "dlt_message_print_hex() failed!\n");
     377        5809 :     } else if (daemon_local->flags.aflag) {
     378           0 :         if (DLT_RETURN_OK !=
     379           0 :             dlt_message_print_ascii(&(daemon_local->msg), text,
     380             :                                     DLT_DAEMON_TEXTSIZE, verbose))
     381           0 :             dlt_log(LOG_WARNING, "dlt_message_print_ascii() failed!\n");
     382        5809 :     } else if (daemon_local->flags.sflag) {
     383           0 :         if (DLT_RETURN_OK !=
     384           0 :             dlt_message_print_header(&(daemon_local->msg), text,
     385             :                                      DLT_DAEMON_TEXTSIZE, verbose))
     386           0 :             dlt_log(LOG_WARNING, "dlt_message_print_header() failed!\n");
     387             :     }
     388             : 
     389             :     /* send message to client or write to log file */
     390        5809 :     return dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL, daemon, daemon_local,
     391        5809 :                 daemon_local->msg.headerbuffer, sizeof(DltStorageHeader),
     392             :                 daemon_local->msg.headerbuffer + sizeof(DltStorageHeader),
     393        5809 :                 (int) (daemon_local->msg.headersize - sizeof(DltStorageHeader)),
     394        5809 :                 daemon_local->msg.databuffer, (int) daemon_local->msg.datasize, verbose);
     395             : 
     396             : }
     397             : 
     398          21 : int dlt_daemon_client_send_control_message(int sock,
     399             :                                            DltDaemon *daemon,
     400             :                                            DltDaemonLocal *daemon_local,
     401             :                                            DltMessage *msg,
     402             :                                            char *apid,
     403             :                                            char *ctid,
     404             :                                            int verbose)
     405             : {
     406             :     int ret;
     407             :     int32_t len;
     408             : 
     409          21 :     PRINT_FUNCTION_VERBOSE(verbose);
     410             : 
     411          21 :     if ((daemon == 0) || (msg == 0) || (apid == 0) || (ctid == 0))
     412             :         return DLT_DAEMON_ERROR_UNKNOWN;
     413             : 
     414             :     /* prepare storage header */
     415          21 :     msg->storageheader = (DltStorageHeader *)msg->headerbuffer;
     416             : 
     417          21 :     if (dlt_set_storageheader(msg->storageheader, daemon->ecuid) == DLT_RETURN_ERROR)
     418             :         return DLT_DAEMON_ERROR_UNKNOWN;
     419             : 
     420             :     /* prepare standard header */
     421          21 :     msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader));
     422          21 :     msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
     423             : 
     424             : #if (BYTE_ORDER == BIG_ENDIAN)
     425             :     msg->standardheader->htyp = (msg->standardheader->htyp | DLT_HTYP_MSBF);
     426             : #endif
     427             : 
     428          21 :     msg->standardheader->mcnt = 0;
     429             : 
     430             :     /* Set header extra parameters */
     431          21 :     dlt_set_id(msg->headerextra.ecu, daemon->ecuid);
     432             : 
     433             :     /*msg->headerextra.seid = 0; */
     434             : 
     435          21 :     msg->headerextra.tmsp = dlt_uptime();
     436             : 
     437          21 :     dlt_message_set_extraparameters(msg, verbose);
     438             : 
     439             :     /* prepare extended header */
     440          21 :     msg->extendedheader =
     441          21 :         (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
     442          21 :                               DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
     443          21 :     msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
     444             : 
     445          21 :     msg->extendedheader->noar = 1; /* number of arguments */
     446             : 
     447          21 :     if (strcmp(apid, "") == 0)
     448          21 :         dlt_set_id(msg->extendedheader->apid, DLT_DAEMON_CTRL_APID);       /* application id */
     449             :     else
     450           0 :         dlt_set_id(msg->extendedheader->apid, apid);
     451             : 
     452          21 :     if (strcmp(ctid, "") == 0)
     453          21 :         dlt_set_id(msg->extendedheader->ctid, DLT_DAEMON_CTRL_CTID);       /* context id */
     454             :     else
     455           0 :         dlt_set_id(msg->extendedheader->ctid, ctid);
     456             : 
     457             :     /* prepare length information */
     458          21 :     msg->headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) +
     459          21 :         DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
     460             : 
     461          21 :     len = (int32_t) (msg->headersize - sizeof(DltStorageHeader) + msg->datasize);
     462             : 
     463          21 :     if (len > UINT16_MAX) {
     464           0 :         dlt_log(LOG_WARNING, "Huge control message discarded!\n");
     465           0 :         return DLT_DAEMON_ERROR_UNKNOWN;
     466             :     }
     467             : 
     468          21 :     msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
     469             : 
     470          21 :     if ((ret =
     471          21 :              dlt_daemon_client_send(sock, daemon, daemon_local, msg->headerbuffer, sizeof(DltStorageHeader),
     472             :                                     msg->headerbuffer + sizeof(DltStorageHeader),
     473          21 :                                     (int) (msg->headersize - sizeof(DltStorageHeader)),
     474          21 :                                     msg->databuffer, (int) msg->datasize, verbose))) {
     475           0 :         dlt_log(LOG_DEBUG, "dlt_daemon_control_send_control_message: DLT message send to all failed!.\n");
     476           0 :         return ret;
     477             :     }
     478             : 
     479             :     return DLT_DAEMON_ERROR_OK;
     480             : }
     481             : 
     482          12 : int dlt_daemon_client_process_control(int sock,
     483             :                                       DltDaemon *daemon,
     484             :                                       DltDaemonLocal *daemon_local,
     485             :                                       DltMessage *msg,
     486             :                                       int verbose)
     487             : {
     488             :     uint32_t id, id_tmp = 0;
     489             :     DltStandardHeaderExtra extra;
     490             : 
     491          12 :     PRINT_FUNCTION_VERBOSE(verbose);
     492             : 
     493          12 :     if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL))
     494             :         return -1;
     495             : 
     496          12 :     if (msg->datasize < (int32_t)sizeof(uint32_t))
     497             :         return -1;
     498             : 
     499          12 :     extra = msg->headerextra;
     500             : 
     501             :     /* check if the message needs to be forwarded */
     502          12 :     if (daemon_local->flags.gatewayMode == 1) {
     503           0 :         if (strncmp(daemon_local->flags.evalue, extra.ecu, DLT_ID_SIZE) != 0)
     504           0 :             return dlt_gateway_forward_control_message(&daemon_local->pGateway,
     505             :                                                        daemon_local,
     506             :                                                        msg,
     507             :                                                        extra.ecu,
     508             :                                                        verbose);
     509             :     }
     510             : 
     511          12 :     id_tmp = *((uint32_t *)(msg->databuffer));
     512          12 :     id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
     513             : 
     514          12 :     if ((id > DLT_SERVICE_ID) && (id < DLT_SERVICE_ID_CALLSW_CINJECTION)) {
     515             :         /* Control message handling */
     516          12 :         switch (id) {
     517           1 :         case DLT_SERVICE_ID_SET_LOG_LEVEL:
     518             :         {
     519           1 :             dlt_daemon_control_set_log_level(sock, daemon, daemon_local, msg, verbose);
     520           1 :             break;
     521             :         }
     522           0 :         case DLT_SERVICE_ID_SET_TRACE_STATUS:
     523             :         {
     524           0 :             dlt_daemon_control_set_trace_status(sock, daemon, daemon_local, msg, verbose);
     525           0 :             break;
     526             :         }
     527           4 :         case DLT_SERVICE_ID_GET_LOG_INFO:
     528             :         {
     529           4 :             dlt_daemon_control_get_log_info(sock, daemon, daemon_local, msg, verbose);
     530           4 :             break;
     531             :         }
     532           1 :         case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
     533             :         {
     534           1 :             dlt_daemon_control_get_default_log_level(sock, daemon, daemon_local, verbose);
     535           1 :             break;
     536             :         }
     537           0 :         case DLT_SERVICE_ID_STORE_CONFIG:
     538             :         {
     539           0 :             if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose) == 0) {
     540           0 :                 if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose) == 0) {
     541           0 :                     dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK,
     542             :                                                         verbose);
     543             :                 }
     544             :                 else {
     545             :                     /* Delete saved files */
     546           0 :                     dlt_daemon_control_reset_to_factory_default(daemon,
     547             :                                                                 daemon->runtime_application_cfg,
     548             :                                                                 daemon->runtime_context_cfg,
     549             :                                                                 daemon_local->flags.contextLogLevel,
     550             :                                                                 daemon_local->flags.contextTraceStatus,
     551             :                                                                 daemon_local->flags.enforceContextLLAndTS,
     552             :                                                                 verbose);
     553           0 :                     dlt_daemon_control_service_response(sock,
     554             :                                                         daemon,
     555             :                                                         daemon_local,
     556             :                                                         id,
     557             :                                                         DLT_SERVICE_RESPONSE_ERROR,
     558             :                                                         verbose);
     559             :                 }
     560             :             }
     561             :             else {
     562           0 :                 dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR,
     563             :                                                     verbose);
     564             :             }
     565             : 
     566             :             break;
     567             :         }
     568           0 :         case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
     569             :         {
     570           0 :             dlt_daemon_control_reset_to_factory_default(daemon,
     571           0 :                                                         daemon->runtime_application_cfg,
     572           0 :                                                         daemon->runtime_context_cfg,
     573             :                                                         daemon_local->flags.contextLogLevel,
     574             :                                                         daemon_local->flags.contextTraceStatus,
     575             :                                                         daemon_local->flags.enforceContextLLAndTS,
     576             :                                                         verbose);
     577           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
     578           0 :             break;
     579             :         }
     580           0 :         case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
     581             :         {
     582           0 :             dlt_daemon_control_service_response(sock,
     583             :                                                 daemon,
     584             :                                                 daemon_local,
     585             :                                                 id,
     586             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     587             :                                                 verbose);
     588           0 :             break;
     589             :         }
     590           0 :         case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
     591             :         {
     592           0 :             dlt_daemon_control_service_response(sock,
     593             :                                                 daemon,
     594             :                                                 daemon_local,
     595             :                                                 id,
     596             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     597             :                                                 verbose);
     598           0 :             break;
     599             :         }
     600           0 :         case DLT_SERVICE_ID_SET_VERBOSE_MODE:
     601             :         {
     602           0 :             dlt_daemon_control_service_response(sock,
     603             :                                                 daemon,
     604             :                                                 daemon_local,
     605             :                                                 id,
     606             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     607             :                                                 verbose);
     608           0 :             break;
     609             :         }
     610           0 :         case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
     611             :         {
     612           0 :             dlt_daemon_control_service_response(sock,
     613             :                                                 daemon,
     614             :                                                 daemon_local,
     615             :                                                 id,
     616             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     617             :                                                 verbose);
     618           0 :             break;
     619             :         }
     620           0 :         case DLT_SERVICE_ID_SET_TIMING_PACKETS:
     621             :         {
     622           0 :             dlt_daemon_control_set_timing_packets(sock, daemon, daemon_local, msg, verbose);
     623           0 :             break;
     624             :         }
     625           0 :         case DLT_SERVICE_ID_GET_LOCAL_TIME:
     626             :         {
     627             :             /* Send response with valid timestamp (TMSP) field */
     628           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
     629           0 :             break;
     630             :         }
     631           0 :         case DLT_SERVICE_ID_USE_ECU_ID:
     632             :         {
     633           0 :             dlt_daemon_control_service_response(sock,
     634             :                                                 daemon,
     635             :                                                 daemon_local,
     636             :                                                 id,
     637             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     638             :                                                 verbose);
     639           0 :             break;
     640             :         }
     641           0 :         case DLT_SERVICE_ID_USE_SESSION_ID:
     642             :         {
     643           0 :             dlt_daemon_control_service_response(sock,
     644             :                                                 daemon,
     645             :                                                 daemon_local,
     646             :                                                 id,
     647             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     648             :                                                 verbose);
     649           0 :             break;
     650             :         }
     651           0 :         case DLT_SERVICE_ID_USE_TIMESTAMP:
     652             :         {
     653           0 :             dlt_daemon_control_service_response(sock,
     654             :                                                 daemon,
     655             :                                                 daemon_local,
     656             :                                                 id,
     657             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     658             :                                                 verbose);
     659           0 :             break;
     660             :         }
     661           0 :         case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
     662             :         {
     663           0 :             dlt_daemon_control_service_response(sock,
     664             :                                                 daemon,
     665             :                                                 daemon_local,
     666             :                                                 id,
     667             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     668             :                                                 verbose);
     669           0 :             break;
     670             :         }
     671           0 :         case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
     672             :         {
     673           0 :             dlt_daemon_control_set_default_log_level(sock, daemon, daemon_local, msg, verbose);
     674           0 :             break;
     675             :         }
     676           0 :         case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
     677             :         {
     678           0 :             dlt_daemon_control_set_default_trace_status(sock, daemon, daemon_local, msg, verbose);
     679           0 :             break;
     680             :         }
     681           4 :         case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
     682             :         {
     683           4 :             dlt_daemon_control_get_software_version(sock, daemon, daemon_local, verbose);
     684           4 :             break;
     685             :         }
     686           0 :         case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
     687             :         {
     688           0 :             dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon_local, daemon->overflow_counter, "",
     689             :                                                        verbose);
     690           0 :             break;
     691             :         }
     692           2 :         case DLT_SERVICE_ID_OFFLINE_LOGSTORAGE:
     693             :         {
     694           2 :             dlt_daemon_control_service_logstorage(sock, daemon, daemon_local, msg, verbose);
     695           2 :             break;
     696             :         }
     697           0 :         case DLT_SERVICE_ID_PASSIVE_NODE_CONNECT:
     698             :         {
     699           0 :             dlt_daemon_control_passive_node_connect(sock,
     700             :                                                     daemon,
     701             :                                                     daemon_local,
     702             :                                                     msg,
     703             :                                                     verbose);
     704           0 :             break;
     705             :         }
     706           0 :         case DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS:
     707             :         {
     708           0 :             dlt_daemon_control_passive_node_connect_status(sock,
     709             :                                                            daemon,
     710             :                                                            daemon_local,
     711             :                                                            verbose);
     712           0 :             break;
     713             :         }
     714           0 :         case DLT_SERVICE_ID_SET_ALL_LOG_LEVEL:
     715             :         {
     716           0 :             dlt_daemon_control_set_all_log_level(sock, daemon, daemon_local, msg, verbose);
     717           0 :             break;
     718             :         }
     719           0 :         case DLT_SERVICE_ID_SET_ALL_TRACE_STATUS:
     720             :         {
     721           0 :             dlt_daemon_control_set_all_trace_status(sock, daemon, daemon_local, msg, verbose);
     722           0 :             break;
     723             :         }
     724           0 :         default:
     725             :         {
     726           0 :             dlt_daemon_control_service_response(sock,
     727             :                                                 daemon,
     728             :                                                 daemon_local,
     729             :                                                 id,
     730             :                                                 DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
     731             :                                                 verbose);
     732           0 :             break;
     733             :         }
     734             :         }
     735             :     }
     736             :     else {
     737             :         /* Injection handling */
     738           0 :         dlt_daemon_control_callsw_cinjection(sock, daemon, daemon_local, msg, verbose);
     739             :     }
     740             : 
     741             :     return 0;
     742             : }
     743             : 
     744           4 : void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
     745             : {
     746             :     DltMessage msg;
     747             :     uint32_t len;
     748             :     DltServiceGetSoftwareVersionResponse *resp;
     749             : 
     750           4 :     PRINT_FUNCTION_VERBOSE(verbose);
     751             : 
     752           4 :     if (daemon == 0)
     753           0 :         return;
     754             : 
     755             :     /* initialise new message */
     756           4 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) {
     757           0 :         dlt_daemon_control_service_response(sock,
     758             :                                             daemon,
     759             :                                             daemon_local,
     760             :                                             DLT_SERVICE_ID_GET_SOFTWARE_VERSION,
     761             :                                             DLT_SERVICE_RESPONSE_ERROR,
     762             :                                             verbose);
     763           0 :         return;
     764             :     }
     765             : 
     766             :     /* prepare payload of data */
     767           4 :     len = (uint32_t) strlen(daemon->ECUVersionString);
     768             : 
     769             :     /* msg.datasize = sizeof(serviceID) + sizeof(status) + sizeof(length) + len */
     770           4 :     msg.datasize = (uint32_t) (sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t) + len);
     771             : 
     772           4 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
     773           0 :         free(msg.databuffer);
     774           0 :         msg.databuffer = 0;
     775             :     }
     776             : 
     777           4 :     if (msg.databuffer == 0) {
     778           4 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
     779           4 :         msg.databuffersize = msg.datasize;
     780             :     }
     781             : 
     782           4 :     if (msg.databuffer == 0) {
     783           0 :         dlt_daemon_control_service_response(sock,
     784             :                                             daemon,
     785             :                                             daemon_local,
     786             :                                             DLT_SERVICE_ID_GET_SOFTWARE_VERSION,
     787             :                                             DLT_SERVICE_RESPONSE_ERROR,
     788             :                                             verbose);
     789           0 :         return;
     790             :     }
     791             : 
     792             :     resp = (DltServiceGetSoftwareVersionResponse *)msg.databuffer;
     793           4 :     resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
     794           4 :     resp->status = DLT_SERVICE_RESPONSE_OK;
     795           4 :     resp->length = len;
     796           4 :     memcpy(msg.databuffer + msg.datasize - len, daemon->ECUVersionString, len);
     797             : 
     798             :     /* send message */
     799           4 :     dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose);
     800             : 
     801             :     /* free message */
     802           4 :     dlt_message_free(&msg, 0);
     803             : }
     804             : 
     805           1 : void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
     806             : {
     807             :     DltMessage msg;
     808             :     DltServiceGetDefaultLogLevelResponse *resp;
     809             : 
     810           1 :     PRINT_FUNCTION_VERBOSE(verbose);
     811             : 
     812           1 :     if (daemon == 0)
     813           0 :         return;
     814             : 
     815             :     /* initialise new message */
     816           1 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) {
     817           0 :         dlt_daemon_control_service_response(sock,
     818             :                                             daemon,
     819             :                                             daemon_local,
     820             :                                             DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL,
     821             :                                             DLT_SERVICE_RESPONSE_ERROR,
     822             :                                             verbose);
     823           0 :         return;
     824             :     }
     825             : 
     826           1 :     msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
     827             : 
     828           1 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
     829           0 :         free(msg.databuffer);
     830           0 :         msg.databuffer = 0;
     831             :     }
     832             : 
     833           1 :     if (msg.databuffer == 0) {
     834           1 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
     835           1 :         msg.databuffersize = msg.datasize;
     836             :     }
     837             : 
     838           1 :     if (msg.databuffer == 0) {
     839           0 :         dlt_daemon_control_service_response(sock,
     840             :                                             daemon,
     841             :                                             daemon_local,
     842             :                                             DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL,
     843             :                                             DLT_SERVICE_RESPONSE_ERROR,
     844             :                                             verbose);
     845           0 :         return;
     846             :     }
     847             : 
     848             :     resp = (DltServiceGetDefaultLogLevelResponse *)msg.databuffer;
     849           1 :     resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
     850           1 :     resp->status = DLT_SERVICE_RESPONSE_OK;
     851           1 :     resp->log_level = (uint8_t) daemon->default_log_level;
     852             : 
     853             :     /* send message */
     854           1 :     dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose);
     855             : 
     856             :     /* free message */
     857           1 :     dlt_message_free(&msg, 0);
     858             : }
     859             : 
     860           4 : void dlt_daemon_control_get_log_info(int sock,
     861             :                                      DltDaemon *daemon,
     862             :                                      DltDaemonLocal *daemon_local,
     863             :                                      DltMessage *msg,
     864             :                                      int verbose)
     865             : {
     866             :     DltServiceGetLogInfoRequest *req;
     867             :     DltMessage resp;
     868             :     DltDaemonContext *context = 0;
     869             :     DltDaemonApplication *application = 0;
     870             : 
     871             :     int num_applications = 0, num_contexts = 0;
     872           4 :     uint16_t count_app_ids = 0, count_con_ids = 0;
     873             : 
     874             : #if (DLT_DEBUG_GETLOGINFO == 1)
     875             :     char buf[255];
     876             : #endif
     877             : 
     878             :     int32_t i, j;
     879             :     size_t offset = 0;
     880             :     char *apid = 0;
     881             :     int8_t ll, ts;
     882             :     uint16_t len;
     883             :     int8_t value;
     884             :     size_t sizecont = 0;
     885             :     int offset_base;
     886             : 
     887             :     uint32_t sid;
     888             : 
     889             :     DltDaemonRegisteredUsers *user_list = NULL;
     890             : 
     891           4 :     PRINT_FUNCTION_VERBOSE(verbose);
     892             : 
     893           4 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
     894           0 :         return;
     895             : 
     896           4 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceGetLogInfoRequest)) < 0)
     897             :         return;
     898             : 
     899           4 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
     900             : 
     901           4 :     if (user_list == NULL)
     902             :         return;
     903             : 
     904             :     /* prepare pointer to message request */
     905           4 :     req = (DltServiceGetLogInfoRequest *)(msg->databuffer);
     906             : 
     907             :     /* initialise new message */
     908           4 :     if (dlt_message_init(&resp, 0) == DLT_RETURN_ERROR) {
     909           0 :         dlt_daemon_control_service_response(sock,
     910             :                                             daemon,
     911             :                                             daemon_local,
     912             :                                             DLT_SERVICE_ID_GET_LOG_INFO,
     913             :                                             DLT_SERVICE_RESPONSE_ERROR,
     914             :                                             verbose);
     915           0 :         return;
     916             :     }
     917             : 
     918             :     /* check request */
     919           4 :     if ((req->options < 3) || (req->options > 7)) {
     920           0 :         dlt_daemon_control_service_response(sock,
     921             :                                             daemon,
     922             :                                             daemon_local,
     923             :                                             DLT_SERVICE_ID_GET_LOG_INFO,
     924             :                                             DLT_SERVICE_RESPONSE_ERROR,
     925             :                                             verbose);
     926           0 :         return;
     927             :     }
     928             : 
     929           4 :     if (req->apid[0] != '\0') {
     930           0 :         application = dlt_daemon_application_find(daemon,
     931           0 :                                                   req->apid,
     932             :                                                   daemon->ecuid,
     933             :                                                   verbose);
     934             : 
     935           0 :         if (application) {
     936             :             num_applications = 1;
     937             : 
     938           0 :             if (req->ctid[0] != '\0') {
     939           0 :                 context = dlt_daemon_context_find(daemon,
     940             :                                                   req->apid,
     941           0 :                                                   req->ctid,
     942             :                                                   daemon->ecuid,
     943             :                                                   verbose);
     944             : 
     945           0 :                 num_contexts = ((context) ? 1 : 0);
     946             :             }
     947             :             else {
     948           0 :                 num_contexts = application->num_contexts;
     949             :             }
     950             :         }
     951             :         else {
     952             :             num_applications = 0;
     953             :             num_contexts = 0;
     954             :         }
     955             :     }
     956             :     else {
     957             :         /* Request all applications and contexts */
     958           4 :         num_applications = user_list->num_applications;
     959           4 :         num_contexts = user_list->num_contexts;
     960             :     }
     961             : 
     962             :     /* prepare payload of data */
     963             : 
     964             :     /* Calculate maximum size for a response */
     965             :     resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
     966             : 
     967             :     sizecont = sizeof(uint32_t) /* context_id */;
     968             : 
     969             :     /* Add additional size for response of Mode 4, 6, 7 */
     970           4 :     if ((req->options == 4) || (req->options == 6) || (req->options == 7))
     971             :         sizecont += sizeof(int8_t); /* log level */
     972             : 
     973             :     /* Add additional size for response of Mode 5, 6, 7 */
     974           4 :     if ((req->options == 5) || (req->options == 6) || (req->options == 7))
     975           4 :         sizecont += sizeof(int8_t); /* trace status */
     976             : 
     977           4 :     resp.datasize += (uint32_t) (((uint32_t) num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) +
     978           4 :         ((size_t) num_contexts * sizecont));
     979             : 
     980           4 :     resp.datasize += (uint32_t) sizeof(uint16_t) /* count_app_ids */;
     981             : 
     982             :     /* Add additional size for response of Mode 7 */
     983           4 :     if (req->options == 7) {
     984           4 :         if (req->apid[0] != '\0') {
     985           0 :             if (req->ctid[0] != '\0') {
     986             :                 /* One application, one context */
     987             :                 /* context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose); */
     988           0 :                 if (context) {
     989           0 :                     resp.datasize += (uint32_t) sizeof(uint16_t) /* len_context_description */;
     990             : 
     991           0 :                     if (context->context_description != 0)
     992           0 :                         resp.datasize += (uint32_t) strlen(context->context_description); /* context_description */
     993             :                 }
     994             :             }
     995             :             else
     996             :             /* One application, all contexts */
     997           0 :             if ((user_list->applications) && (application)) {
     998             :                 /* Calculate start offset within contexts[] */
     999             :                 offset_base = 0;
    1000             : 
    1001           0 :                 for (i = 0; i < (application - (user_list->applications)); i++)
    1002           0 :                     offset_base += user_list->applications[i].num_contexts;
    1003             : 
    1004             :                 /* Iterate over all contexts belonging to this application */
    1005           0 :                 for (j = 0; j < application->num_contexts; j++) {
    1006             : 
    1007           0 :                     context = &(user_list->contexts[offset_base + j]);
    1008             : 
    1009           0 :                     if (context) {
    1010           0 :                         resp.datasize += (uint32_t) sizeof(uint16_t) /* len_context_description */;
    1011             : 
    1012           0 :                         if (context->context_description != 0)
    1013           0 :                             resp.datasize += (uint32_t) strlen(context->context_description);   /* context_description */
    1014             :                     }
    1015             :                 }
    1016             :             }
    1017             : 
    1018             :             /* Space for application description */
    1019           0 :             if (application) {
    1020           0 :                 resp.datasize += (uint32_t) sizeof(uint16_t) /* len_app_description */;
    1021             : 
    1022           0 :                 if (application->application_description != 0)
    1023           0 :                     resp.datasize += (uint32_t) strlen(application->application_description); /* app_description */
    1024             :             }
    1025             :         }
    1026             :         else {
    1027             :             /* All applications, all contexts */
    1028           4 :             for (i = 0; i < user_list->num_contexts; i++) {
    1029           0 :                 resp.datasize += (uint32_t) sizeof(uint16_t) /* len_context_description */;
    1030             : 
    1031           0 :                 if (user_list->contexts[i].context_description != 0)
    1032           0 :                     resp.datasize +=
    1033           0 :                         (uint32_t) strlen(user_list->contexts[i].context_description);
    1034             :             }
    1035             : 
    1036           4 :             for (i = 0; i < user_list->num_applications; i++) {
    1037           0 :                 resp.datasize += (uint32_t) sizeof(uint16_t) /* len_app_description */;
    1038             : 
    1039           0 :                 if (user_list->applications[i].application_description != 0)
    1040           0 :                     resp.datasize += (uint32_t) strlen(user_list->applications[i].application_description); /* app_description */
    1041             :             }
    1042             :         }
    1043             :     }
    1044             : 
    1045           4 :     if (verbose)
    1046           0 :         dlt_vlog(LOG_DEBUG,
    1047             :                  "Allocate %u bytes for response msg databuffer\n",
    1048             :                  resp.datasize);
    1049             : 
    1050             :     /* Allocate buffer for response message */
    1051           4 :     resp.databuffer = (uint8_t *)malloc(resp.datasize);
    1052           4 :     resp.databuffersize = resp.datasize;
    1053             : 
    1054           4 :     if (resp.databuffer == 0) {
    1055           0 :         dlt_daemon_control_service_response(sock,
    1056             :                                             daemon,
    1057             :                                             daemon_local,
    1058             :                                             DLT_SERVICE_ID_GET_LOG_INFO,
    1059             :                                             DLT_SERVICE_RESPONSE_ERROR,
    1060             :                                             verbose);
    1061           0 :         return;
    1062             :     }
    1063             : 
    1064             :     memset(resp.databuffer, 0, resp.datasize);
    1065             :     /* Preparation finished */
    1066             : 
    1067             :     /* Prepare response */
    1068           4 :     sid = DLT_SERVICE_ID_GET_LOG_INFO;
    1069             :     memcpy(resp.databuffer, &sid, sizeof(uint32_t));
    1070             :     offset += sizeof(uint32_t);
    1071             : 
    1072           4 :     value = (int8_t) (((num_applications != 0) && (num_contexts != 0)) ? req->options : 8); /* 8 = no matching context found */
    1073             : 
    1074           4 :     memcpy(resp.databuffer + offset, &value, sizeof(int8_t));
    1075             :     offset += sizeof(int8_t);
    1076             : 
    1077           4 :     count_app_ids = (uint16_t) num_applications;
    1078             : 
    1079           4 :     if (count_app_ids != 0) {
    1080           0 :         memcpy(resp.databuffer + offset, &count_app_ids, sizeof(uint16_t));
    1081             :         offset += sizeof(uint16_t);
    1082             : 
    1083             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1084             :         dlt_vlog(LOG_DEBUG, "#apid: %d \n", count_app_ids);
    1085             : #endif
    1086             : 
    1087           0 :         for (i = 0; i < count_app_ids; i++) {
    1088           0 :             if (req->apid[0] != '\0') {
    1089           0 :                 apid = req->apid;
    1090             :             }
    1091             :             else {
    1092           0 :                 if (user_list->applications)
    1093           0 :                     apid = user_list->applications[i].apid;
    1094             :                 else
    1095             :                     /* This should never occur! */
    1096             :                     apid = 0;
    1097             :             }
    1098             : 
    1099           0 :             application = dlt_daemon_application_find(daemon,
    1100             :                                                       apid,
    1101             :                                                       daemon->ecuid,
    1102             :                                                       verbose);
    1103             : 
    1104           0 :             if ((user_list->applications) && (application)) {
    1105             :                 /* Calculate start offset within contexts[] */
    1106             :                 offset_base = 0;
    1107             : 
    1108           0 :                 for (j = 0; j < (application - (user_list->applications)); j++)
    1109           0 :                     offset_base += user_list->applications[j].num_contexts;
    1110             : 
    1111           0 :                 dlt_set_id((char *)(resp.databuffer + offset), apid);
    1112           0 :                 offset += sizeof(ID4);
    1113             : 
    1114             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1115             :                 dlt_print_id(buf, apid);
    1116             :                 dlt_vlog(LOG_DEBUG, "apid: %s\n", buf);
    1117             : #endif
    1118             : 
    1119           0 :                 if (req->apid[0] != '\0')
    1120           0 :                     count_con_ids = (uint16_t) num_contexts;
    1121             :                 else
    1122           0 :                     count_con_ids = (uint16_t) application->num_contexts;
    1123             : 
    1124           0 :                 memcpy(resp.databuffer + offset, &count_con_ids, sizeof(uint16_t));
    1125           0 :                 offset += sizeof(uint16_t);
    1126             : 
    1127             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1128             :                 dlt_vlog(LOG_DEBUG, "#ctid: %d \n", count_con_ids);
    1129             : #endif
    1130             : 
    1131           0 :                 for (j = 0; j < count_con_ids; j++) {
    1132             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1133             :                     dlt_vlog(LOG_DEBUG, "j: %d \n", j);
    1134             : #endif
    1135             : 
    1136           0 :                     if (!((count_con_ids == 1) && (req->apid[0] != '\0') &&
    1137           0 :                           (req->ctid[0] != '\0')))
    1138           0 :                         context = &(user_list->contexts[offset_base + j]);
    1139             : 
    1140             :                     /* else: context was already searched and found
    1141             :                      *       (one application (found) with one context (found))*/
    1142             : 
    1143           0 :                     if ((context) &&
    1144           0 :                         ((req->ctid[0] == '\0') || ((req->ctid[0] != '\0') &&
    1145           0 :                                                     (memcmp(context->ctid, req->ctid, DLT_ID_SIZE) == 0)))
    1146             :                         ) {
    1147           0 :                         dlt_set_id((char *)(resp.databuffer + offset), context->ctid);
    1148           0 :                         offset += sizeof(ID4);
    1149             : 
    1150             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1151             :                         dlt_print_id(buf, context->ctid);
    1152             :                         dlt_vlog(LOG_DEBUG, "ctid: %s \n", buf);
    1153             : #endif
    1154             : 
    1155             :                         /* Mode 4, 6, 7 */
    1156           0 :                         if ((req->options == 4) || (req->options == 6) || (req->options == 7)) {
    1157           0 :                             ll = context->log_level;
    1158           0 :                             memcpy(resp.databuffer + offset, &ll, sizeof(int8_t));
    1159           0 :                             offset += sizeof(int8_t);
    1160             :                         }
    1161             : 
    1162             :                         /* Mode 5, 6, 7 */
    1163           0 :                         if ((req->options == 5) || (req->options == 6) || (req->options == 7)) {
    1164           0 :                             ts = context->trace_status;
    1165           0 :                             memcpy(resp.databuffer + offset, &ts, sizeof(int8_t));
    1166           0 :                             offset += sizeof(int8_t);
    1167             :                         }
    1168             : 
    1169             :                         /* Mode 7 */
    1170           0 :                         if (req->options == 7) {
    1171           0 :                             if (context->context_description) {
    1172           0 :                                 len = (uint16_t) strlen(context->context_description);
    1173           0 :                                 memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
    1174           0 :                                 offset += sizeof(uint16_t);
    1175           0 :                                 memcpy(resp.databuffer + offset, context->context_description,
    1176           0 :                                        strlen(context->context_description));
    1177           0 :                                 offset += strlen(context->context_description);
    1178             :                             }
    1179             :                             else {
    1180           0 :                                 len = 0;
    1181           0 :                                 memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
    1182           0 :                                 offset += sizeof(uint16_t);
    1183             :                             }
    1184             :                         }
    1185             : 
    1186             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1187             :                         dlt_vlog(LOG_DEBUG, "ll=%d ts=%d \n", (int32_t)ll,
    1188             :                                  (int32_t)ts);
    1189             : #endif
    1190             :                     }
    1191             : 
    1192             : #if (DLT_DEBUG_GETLOGINFO == 1)
    1193             :                     dlt_log(LOG_DEBUG, "\n");
    1194             : #endif
    1195             :                 }
    1196             : 
    1197             :                 /* Mode 7 */
    1198           0 :                 if (req->options == 7) {
    1199           0 :                     if (application->application_description) {
    1200           0 :                         len = (uint16_t) strlen(application->application_description);
    1201           0 :                         memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
    1202           0 :                         offset += sizeof(uint16_t);
    1203           0 :                         memcpy(resp.databuffer + offset, application->application_description,
    1204           0 :                                strlen(application->application_description));
    1205           0 :                         offset += strlen(application->application_description);
    1206             :                     }
    1207             :                     else {
    1208           0 :                         len = 0;
    1209           0 :                         memcpy(resp.databuffer + offset, &len, sizeof(uint16_t));
    1210           0 :                         offset += sizeof(uint16_t);
    1211             :                     }
    1212             :                 }
    1213             :             } /* if (application) */
    1214             : 
    1215             :         } /* for (i=0;i<count_app_ids;i++) */
    1216             : 
    1217             :     } /* if (count_app_ids!=0) */
    1218             : 
    1219           4 :     dlt_set_id((char *)(resp.databuffer + offset), DLT_DAEMON_REMO_STRING);
    1220             : 
    1221             :     /* send message */
    1222           4 :     dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &resp, "", "", verbose);
    1223             : 
    1224             :     /* free message */
    1225           4 :     dlt_message_free(&resp, 0);
    1226             : }
    1227             : 
    1228           0 : int dlt_daemon_control_message_buffer_overflow(int sock,
    1229             :                                                DltDaemon *daemon,
    1230             :                                                DltDaemonLocal *daemon_local,
    1231             :                                                unsigned int overflow_counter,
    1232             :                                                char *apid,
    1233             :                                                int verbose)
    1234             : {
    1235             :     int ret;
    1236             :     DltMessage msg;
    1237             :     DltServiceMessageBufferOverflowResponse *resp;
    1238             : 
    1239           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1240             : 
    1241           0 :     if (daemon == 0)
    1242             :         return DLT_DAEMON_ERROR_UNKNOWN;
    1243             : 
    1244             :     /* initialise new message */
    1245           0 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR) {
    1246           0 :         dlt_daemon_control_service_response(sock,
    1247             :                                             daemon,
    1248             :                                             daemon_local,
    1249             :                                             DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW,
    1250             :                                             DLT_SERVICE_RESPONSE_ERROR,
    1251             :                                             verbose);
    1252           0 :         return DLT_DAEMON_ERROR_UNKNOWN;
    1253             :     }
    1254             : 
    1255             :     /* prepare payload of data */
    1256           0 :     msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
    1257             : 
    1258           0 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
    1259           0 :         free(msg.databuffer);
    1260           0 :         msg.databuffer = 0;
    1261             :     }
    1262             : 
    1263           0 :     if (msg.databuffer == 0) {
    1264           0 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    1265           0 :         msg.databuffersize = msg.datasize;
    1266             :     }
    1267             : 
    1268           0 :     if (msg.databuffer == 0)
    1269             :         return DLT_DAEMON_ERROR_UNKNOWN;
    1270             : 
    1271             :     resp = (DltServiceMessageBufferOverflowResponse *)msg.databuffer;
    1272           0 :     resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
    1273           0 :     resp->status = DLT_SERVICE_RESPONSE_OK;
    1274           0 :     resp->overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
    1275           0 :     resp->overflow_counter = overflow_counter;
    1276             : 
    1277             :     /* send message */
    1278           0 :     if ((ret = dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, apid, "", verbose))) {
    1279           0 :         dlt_message_free(&msg, 0);
    1280           0 :         return ret;
    1281             :     }
    1282             : 
    1283             :     /* free message */
    1284           0 :     dlt_message_free(&msg, 0);
    1285             : 
    1286           0 :     return DLT_DAEMON_ERROR_OK;
    1287             : }
    1288             : 
    1289           3 : void dlt_daemon_control_service_response(int sock,
    1290             :                                          DltDaemon *daemon,
    1291             :                                          DltDaemonLocal *daemon_local,
    1292             :                                          uint32_t service_id,
    1293             :                                          int8_t status,
    1294             :                                          int verbose)
    1295             : {
    1296             :     DltMessage msg;
    1297             :     DltServiceResponse *resp;
    1298             : 
    1299           3 :     PRINT_FUNCTION_VERBOSE(verbose);
    1300             : 
    1301           3 :     if (daemon == 0)
    1302           0 :         return;
    1303             : 
    1304             :     /* initialise new message */
    1305           3 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
    1306             :         return;
    1307             : 
    1308             :     /* prepare payload of data */
    1309           3 :     msg.datasize = sizeof(DltServiceResponse);
    1310             : 
    1311           3 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
    1312           0 :         free(msg.databuffer);
    1313           0 :         msg.databuffer = 0;
    1314             :     }
    1315             : 
    1316           3 :     if (msg.databuffer == 0) {
    1317           3 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    1318           3 :         msg.databuffersize = msg.datasize;
    1319             :     }
    1320             : 
    1321           3 :     if (msg.databuffer == 0)
    1322             :         return;
    1323             : 
    1324             :     resp = (DltServiceResponse *)msg.databuffer;
    1325           3 :     resp->service_id = service_id;
    1326           3 :     resp->status = (uint8_t) status;
    1327             : 
    1328             :     /* send message */
    1329           3 :     dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose);
    1330             : 
    1331             :     /* free message */
    1332           3 :     dlt_message_free(&msg, 0);
    1333             : }
    1334             : 
    1335           0 : int dlt_daemon_control_message_unregister_context(int sock,
    1336             :                                                   DltDaemon *daemon,
    1337             :                                                   DltDaemonLocal *daemon_local,
    1338             :                                                   char *apid,
    1339             :                                                   char *ctid,
    1340             :                                                   char *comid,
    1341             :                                                   int verbose)
    1342             : {
    1343             :     DltMessage msg;
    1344             :     DltServiceUnregisterContext *resp;
    1345             : 
    1346           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1347             : 
    1348           0 :     if (daemon == 0)
    1349             :         return -1;
    1350             : 
    1351             :     /* initialise new message */
    1352           0 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
    1353             :         return -1;
    1354             : 
    1355             :     /* prepare payload of data */
    1356           0 :     msg.datasize = sizeof(DltServiceUnregisterContext);
    1357             : 
    1358           0 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
    1359           0 :         free(msg.databuffer);
    1360           0 :         msg.databuffer = 0;
    1361             :     }
    1362             : 
    1363           0 :     if (msg.databuffer == 0) {
    1364           0 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    1365           0 :         msg.databuffersize = msg.datasize;
    1366             :     }
    1367             : 
    1368           0 :     if (msg.databuffer == 0)
    1369             :         return -1;
    1370             : 
    1371             :     resp = (DltServiceUnregisterContext *)msg.databuffer;
    1372           0 :     resp->service_id = DLT_SERVICE_ID_UNREGISTER_CONTEXT;
    1373           0 :     resp->status = DLT_SERVICE_RESPONSE_OK;
    1374           0 :     dlt_set_id(resp->apid, apid);
    1375           0 :     dlt_set_id(resp->ctid, ctid);
    1376           0 :     dlt_set_id(resp->comid, comid);
    1377             : 
    1378             :     /* send message */
    1379           0 :     if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
    1380           0 :         dlt_message_free(&msg, 0);
    1381           0 :         return -1;
    1382             :     }
    1383             : 
    1384             :     /* free message */
    1385           0 :     dlt_message_free(&msg, 0);
    1386             : 
    1387           0 :     return 0;
    1388             : }
    1389             : 
    1390           9 : int dlt_daemon_control_message_connection_info(int sock,
    1391             :                                                DltDaemon *daemon,
    1392             :                                                DltDaemonLocal *daemon_local,
    1393             :                                                uint8_t state,
    1394             :                                                char *comid,
    1395             :                                                int verbose)
    1396             : {
    1397             :     DltMessage msg;
    1398             :     DltServiceConnectionInfo *resp;
    1399             : 
    1400           9 :     PRINT_FUNCTION_VERBOSE(verbose);
    1401             : 
    1402           9 :     if (daemon == 0)
    1403             :         return -1;
    1404             : 
    1405             :     /* initialise new message */
    1406           9 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
    1407             :         return -1;
    1408             : 
    1409             :     /* prepare payload of data */
    1410           9 :     msg.datasize = sizeof(DltServiceConnectionInfo);
    1411             : 
    1412           9 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
    1413           0 :         free(msg.databuffer);
    1414           0 :         msg.databuffer = 0;
    1415             :     }
    1416             : 
    1417           9 :     if (msg.databuffer == 0) {
    1418           9 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    1419           9 :         msg.databuffersize = msg.datasize;
    1420             :     }
    1421             : 
    1422           9 :     if (msg.databuffer == 0)
    1423             :         return -1;
    1424             : 
    1425             :     resp = (DltServiceConnectionInfo *)msg.databuffer;
    1426           9 :     resp->service_id = DLT_SERVICE_ID_CONNECTION_INFO;
    1427           9 :     resp->status = DLT_SERVICE_RESPONSE_OK;
    1428           9 :     resp->state = state;
    1429           9 :     dlt_set_id(resp->comid, comid);
    1430             : 
    1431             :     /* send message */
    1432           9 :     if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
    1433           0 :         dlt_message_free(&msg, 0);
    1434           0 :         return -1;
    1435             :     }
    1436             : 
    1437             :     /* free message */
    1438           9 :     dlt_message_free(&msg, 0);
    1439             : 
    1440           9 :     return 0;
    1441             : }
    1442             : 
    1443           0 : int dlt_daemon_control_message_timezone(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
    1444             : {
    1445             :     DltMessage msg;
    1446             :     DltServiceTimezone *resp;
    1447             : 
    1448           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1449             : 
    1450           0 :     if (daemon == 0)
    1451             :         return -1;
    1452             : 
    1453             :     /* initialise new message */
    1454           0 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
    1455             :         return -1;
    1456             : 
    1457             :     /* prepare payload of data */
    1458           0 :     msg.datasize = sizeof(DltServiceTimezone);
    1459             : 
    1460           0 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
    1461           0 :         free(msg.databuffer);
    1462           0 :         msg.databuffer = 0;
    1463             :     }
    1464             : 
    1465           0 :     if (msg.databuffer == 0) {
    1466           0 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    1467           0 :         msg.databuffersize = msg.datasize;
    1468             :     }
    1469             : 
    1470           0 :     if (msg.databuffer == 0)
    1471             :         return -1;
    1472             : 
    1473             :     resp = (DltServiceTimezone *)msg.databuffer;
    1474           0 :     resp->service_id = DLT_SERVICE_ID_TIMEZONE;
    1475           0 :     resp->status = DLT_SERVICE_RESPONSE_OK;
    1476             : 
    1477           0 :     time_t t = time(NULL);
    1478             :     struct tm lt;
    1479           0 :     tzset();
    1480           0 :     localtime_r(&t, &lt);
    1481             : #if !defined(__CYGWIN__)
    1482           0 :     resp->timezone = (int32_t)lt.tm_gmtoff;
    1483             : #endif
    1484           0 :     resp->isdst = (uint8_t)lt.tm_isdst;
    1485             : 
    1486             :     /* send message */
    1487           0 :     if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
    1488           0 :         dlt_message_free(&msg, 0);
    1489           0 :         return -1;
    1490             :     }
    1491             : 
    1492             :     /* free message */
    1493           0 :     dlt_message_free(&msg, 0);
    1494             : 
    1495           0 :     return 0;
    1496             : }
    1497             : 
    1498           0 : int dlt_daemon_control_message_marker(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
    1499             : {
    1500             :     DltMessage msg;
    1501             :     DltServiceMarker *resp;
    1502             : 
    1503           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1504             : 
    1505           0 :     if (daemon == 0)
    1506             :         return -1;
    1507             : 
    1508             :     /* initialise new message */
    1509           0 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
    1510             :         return -1;
    1511             : 
    1512             :     /* prepare payload of data */
    1513           0 :     msg.datasize = sizeof(DltServiceMarker);
    1514             : 
    1515           0 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
    1516           0 :         free(msg.databuffer);
    1517           0 :         msg.databuffer = 0;
    1518             :     }
    1519             : 
    1520           0 :     if (msg.databuffer == 0) {
    1521           0 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    1522           0 :         msg.databuffersize = msg.datasize;
    1523             :     }
    1524             : 
    1525           0 :     if (msg.databuffer == 0)
    1526             :         return -1;
    1527             : 
    1528             :     resp = (DltServiceMarker *)msg.databuffer;
    1529           0 :     resp->service_id = DLT_SERVICE_ID_MARKER;
    1530           0 :     resp->status = DLT_SERVICE_RESPONSE_OK;
    1531             : 
    1532             :     /* send message */
    1533           0 :     if (dlt_daemon_client_send_control_message(sock, daemon, daemon_local, &msg, "", "", verbose)) {
    1534           0 :         dlt_message_free(&msg, 0);
    1535           0 :         return -1;
    1536             :     }
    1537             : 
    1538             :     /* free message */
    1539           0 :     dlt_message_free(&msg, 0);
    1540             : 
    1541           0 :     return 0;
    1542             : }
    1543             : 
    1544           0 : void dlt_daemon_control_callsw_cinjection(int sock,
    1545             :                                           DltDaemon *daemon,
    1546             :                                           DltDaemonLocal *daemon_local,
    1547             :                                           DltMessage *msg,
    1548             :                                           int verbose)
    1549             : {
    1550             :     char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE];
    1551             :     uint32_t id = 0, id_tmp = 0;
    1552             :     uint8_t *ptr;
    1553             :     DltDaemonContext *context;
    1554             :     uint32_t data_length_inject = 0;
    1555             :     uint32_t data_length_inject_tmp = 0;
    1556             : 
    1557             :     int32_t datalength;
    1558             : 
    1559             :     DltUserHeader userheader;
    1560             :     DltUserControlMsgInjection usercontext;
    1561             :     uint8_t *userbuffer;
    1562             : 
    1563           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1564             : 
    1565           0 :     if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) || (msg->databuffer == NULL))
    1566           0 :         return;
    1567             : 
    1568           0 :     datalength = (int32_t) msg->datasize;
    1569             :     ptr = msg->databuffer;
    1570             : 
    1571           0 :     DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t); /* Get service id */
    1572           0 :     id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
    1573             : 
    1574             :     /* injectionMode is disabled */
    1575           0 :     if (daemon_local->flags.injectionMode == 0) {
    1576           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_PERM_DENIED, verbose);
    1577           0 :         return;
    1578             :     }
    1579             : 
    1580             :     /* id is always less than DLT_DAEMON_INJECTION_MAX since its type is uinit32_t */
    1581           0 :     if (id >= DLT_DAEMON_INJECTION_MIN) {
    1582             :         /* This a a real SW-C injection call */
    1583             :         data_length_inject = 0;
    1584             :         data_length_inject_tmp = 0;
    1585             : 
    1586           0 :         DLT_MSG_READ_VALUE(data_length_inject_tmp, ptr, datalength, uint32_t); /* Get data length */
    1587           0 :         data_length_inject = DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
    1588             : 
    1589             :         /* Get context handle for apid, ctid (and seid) */
    1590             :         /* Warning: seid is ignored in this implementation! */
    1591           0 :         if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
    1592           0 :             dlt_set_id(apid, msg->extendedheader->apid);
    1593           0 :             dlt_set_id(ctid, msg->extendedheader->ctid);
    1594             :         }
    1595             :         else {
    1596             :             /* No extended header, and therefore no apid and ctid available */
    1597           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1598           0 :             return;
    1599             :         }
    1600             : 
    1601             :         /* At this point, apid and ctid is available */
    1602           0 :         context = dlt_daemon_context_find(daemon,
    1603             :                                           apid,
    1604             :                                           ctid,
    1605           0 :                                           daemon->ecuid,
    1606             :                                           verbose);
    1607             : 
    1608           0 :         if (context == 0) {
    1609             :             /* dlt_log(LOG_INFO,"No context found!\n"); */
    1610           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1611           0 :             return;
    1612             :         }
    1613             : 
    1614             :         /* Send user message to handle, specified in context */
    1615           0 :         if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION) < DLT_RETURN_OK) {
    1616           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1617           0 :             return;
    1618             :         }
    1619             : 
    1620           0 :         usercontext.log_level_pos = context->log_level_pos;
    1621             : 
    1622           0 :         if (data_length_inject > (uint32_t) msg->databuffersize) {
    1623           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1624           0 :             return;
    1625             :         }
    1626             : 
    1627           0 :         userbuffer = malloc(data_length_inject);
    1628             : 
    1629           0 :         if (userbuffer == 0) {
    1630           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1631           0 :             return;
    1632             :         }
    1633             : 
    1634           0 :         usercontext.data_length_inject = (uint32_t) data_length_inject;
    1635           0 :         usercontext.service_id = id;
    1636             : 
    1637             :         memcpy(userbuffer, ptr, (size_t) data_length_inject);  /* Copy received injection to send buffer */
    1638             : 
    1639             :         /* write to FIFO */
    1640             :         DltReturnValue ret =
    1641           0 :             dlt_user_log_out3_with_timeout(context->user_handle, &(userheader), sizeof(DltUserHeader),
    1642             :                               &(usercontext), sizeof(DltUserControlMsgInjection),
    1643             :                               userbuffer, (size_t) data_length_inject);
    1644             : 
    1645           0 :         if (ret < DLT_RETURN_OK) {
    1646           0 :             if (ret == DLT_RETURN_PIPE_ERROR) {
    1647             :                 /* Close connection */
    1648           0 :                 close(context->user_handle);
    1649           0 :                 context->user_handle = DLT_FD_INIT;
    1650             :             }
    1651             : 
    1652           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1653             :         }
    1654             :         else {
    1655           0 :             dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
    1656             :         }
    1657             : 
    1658           0 :         free(userbuffer);
    1659             :         userbuffer = 0;
    1660             : 
    1661             :     }
    1662             :     else {
    1663             :         /* Invalid ID */
    1664           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,
    1665             :                                             verbose);
    1666             :     }
    1667             : }
    1668             : 
    1669           0 : void dlt_daemon_send_log_level(int sock,
    1670             :                                DltDaemon *daemon,
    1671             :                                DltDaemonLocal *daemon_local,
    1672             :                                DltDaemonContext *context,
    1673             :                                int8_t loglevel,
    1674             :                                int verbose)
    1675             : {
    1676           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1677             : 
    1678             :     int32_t id = DLT_SERVICE_ID_SET_LOG_LEVEL;
    1679             :     int8_t old_log_level = 0;
    1680             : 
    1681           0 :     old_log_level = context->log_level;
    1682           0 :     context->log_level = loglevel; /* No endianess conversion necessary*/
    1683             : 
    1684           0 :     if ((context->user_handle >= DLT_FD_MINIMUM) &&
    1685           0 :         (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) {
    1686           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_OK, verbose);
    1687             :     }
    1688             :     else {
    1689           0 :         dlt_log(LOG_ERR, "Log level could not be sent!\n");
    1690           0 :         context->log_level = old_log_level;
    1691           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1692             :     }
    1693           0 : }
    1694             : 
    1695           0 : void dlt_daemon_find_multiple_context_and_send_log_level(int sock,
    1696             :                                                          DltDaemon *daemon,
    1697             :                                                          DltDaemonLocal *daemon_local,
    1698             :                                                          int8_t app_flag,
    1699             :                                                          char *str,
    1700             :                                                          int8_t len,
    1701             :                                                          int8_t loglevel,
    1702             :                                                          int verbose)
    1703             : {
    1704           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1705             : 
    1706             :     int count = 0;
    1707             :     DltDaemonContext *context = NULL;
    1708           0 :     char src_str[DLT_ID_SIZE + 1] = { 0 };
    1709             :     int ret = 0;
    1710             :     DltDaemonRegisteredUsers *user_list = NULL;
    1711             : 
    1712           0 :     if (daemon == 0) {
    1713           0 :         dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
    1714           0 :         return;
    1715             :     }
    1716             : 
    1717           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1718             : 
    1719           0 :     if (user_list == NULL)
    1720             :         return;
    1721             : 
    1722           0 :     for (count = 0; count < user_list->num_contexts; count++) {
    1723           0 :         context = &(user_list->contexts[count]);
    1724             : 
    1725           0 :         if (context) {
    1726           0 :             if (app_flag == 1)
    1727           0 :                 strncpy(src_str, context->apid, DLT_ID_SIZE);
    1728             :             else
    1729           0 :                 strncpy(src_str, context->ctid, DLT_ID_SIZE);
    1730             : 
    1731           0 :             ret = strncmp(src_str, str, len);
    1732             : 
    1733           0 :             if (ret == 0)
    1734           0 :                 dlt_daemon_send_log_level(sock, daemon, daemon_local, context, loglevel, verbose);
    1735           0 :             else if ((ret > 0) && (app_flag == 1))
    1736             :                 break;
    1737             :             else
    1738           0 :                 continue;
    1739             :         }
    1740             :     }
    1741             : }
    1742             : 
    1743           1 : void dlt_daemon_control_set_log_level(int sock,
    1744             :                                       DltDaemon *daemon,
    1745             :                                       DltDaemonLocal *daemon_local,
    1746             :                                       DltMessage *msg,
    1747             :                                       int verbose)
    1748             : {
    1749           1 :     PRINT_FUNCTION_VERBOSE(verbose);
    1750             : 
    1751           1 :     char apid[DLT_ID_SIZE + 1] = { 0 };
    1752           1 :     char ctid[DLT_ID_SIZE + 1] = { 0 };
    1753             :     DltServiceSetLogLevel *req = NULL;
    1754             :     DltDaemonContext *context = NULL;
    1755             :     int8_t apid_length = 0;
    1756             :     int8_t ctid_length = 0;
    1757             : 
    1758           1 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
    1759           0 :         return;
    1760             : 
    1761           1 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
    1762             :         return;
    1763             : 
    1764           1 :     req = (DltServiceSetLogLevel *)(msg->databuffer);
    1765             : 
    1766           1 :     if (daemon_local->flags.enforceContextLLAndTS)
    1767           0 :         req->log_level = (uint8_t) getStatus(req->log_level, daemon_local->flags.contextLogLevel);
    1768             : 
    1769           1 :     dlt_set_id(apid, req->apid);
    1770           1 :     dlt_set_id(ctid, req->ctid);
    1771           1 :     apid_length = (int8_t) strlen(apid);
    1772           1 :     ctid_length = (int8_t) strlen(ctid);
    1773             : 
    1774           1 :     if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/
    1775           0 :         dlt_daemon_find_multiple_context_and_send_log_level(sock,
    1776             :                                                             daemon,
    1777             :                                                             daemon_local,
    1778             :                                                             1,
    1779             :                                                             apid,
    1780           0 :                                                             (int8_t) (apid_length - 1),
    1781           0 :                                                             (int8_t) req->log_level,
    1782             :                                                             verbose);
    1783             :     }
    1784           1 :     else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/
    1785             :     {
    1786           0 :         dlt_daemon_find_multiple_context_and_send_log_level(sock,
    1787             :                                                             daemon,
    1788             :                                                             daemon_local,
    1789             :                                                             0,
    1790             :                                                             ctid,
    1791           0 :                                                             (int8_t) (ctid_length - 1),
    1792           0 :                                                             (int8_t) req->log_level,
    1793             :                                                             verbose);
    1794             :     }
    1795           1 :     else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/
    1796             :     {
    1797           0 :         dlt_daemon_find_multiple_context_and_send_log_level(sock,
    1798             :                                                             daemon,
    1799             :                                                             daemon_local,
    1800             :                                                             1,
    1801             :                                                             apid,
    1802             :                                                             DLT_ID_SIZE,
    1803           0 :                                                             (int8_t) req->log_level,
    1804             :                                                             verbose);
    1805             :     }
    1806           1 :     else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/
    1807             :     {
    1808           0 :         dlt_daemon_find_multiple_context_and_send_log_level(sock,
    1809             :                                                             daemon,
    1810             :                                                             daemon_local,
    1811             :                                                             0,
    1812             :                                                             ctid,
    1813             :                                                             DLT_ID_SIZE,
    1814           0 :                                                             (int8_t) req->log_level,
    1815             :                                                             verbose);
    1816             :     }
    1817             :     else {
    1818           1 :         context = dlt_daemon_context_find(daemon,
    1819             :                                           apid,
    1820             :                                           ctid,
    1821           1 :                                           daemon->ecuid,
    1822             :                                           verbose);
    1823             : 
    1824             :         /* Set log level */
    1825           1 :         if (context != 0) {
    1826           0 :             dlt_daemon_send_log_level(sock, daemon, daemon_local, context, (int8_t) req->log_level, verbose);
    1827             :         }
    1828             :         else {
    1829           1 :             dlt_vlog(LOG_ERR, "Could not set log level: %d. Context [%.4s:%.4s] not found:", req->log_level, apid,
    1830             :                      ctid);
    1831           1 :             dlt_daemon_control_service_response(sock,
    1832             :                                                 daemon,
    1833             :                                                 daemon_local,
    1834             :                                                 DLT_SERVICE_ID_SET_LOG_LEVEL,
    1835             :                                                 DLT_SERVICE_RESPONSE_ERROR,
    1836             :                                                 verbose);
    1837             :         }
    1838             :     }
    1839             : }
    1840             : 
    1841             : 
    1842           0 : void dlt_daemon_send_trace_status(int sock,
    1843             :                                   DltDaemon *daemon,
    1844             :                                   DltDaemonLocal *daemon_local,
    1845             :                                   DltDaemonContext *context,
    1846             :                                   int8_t tracestatus,
    1847             :                                   int verbose)
    1848             : {
    1849           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1850             : 
    1851             :     int32_t id = DLT_SERVICE_ID_SET_TRACE_STATUS;
    1852             :     int8_t old_trace_status = 0;
    1853             : 
    1854           0 :     old_trace_status = context->trace_status;
    1855           0 :     context->trace_status = tracestatus; /* No endianess conversion necessary*/
    1856             : 
    1857           0 :     if ((context->user_handle >= DLT_FD_MINIMUM) &&
    1858           0 :         (dlt_daemon_user_send_log_level(daemon, context, verbose) == 0)) {
    1859           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_OK, verbose);
    1860             :     }
    1861             :     else {
    1862           0 :         dlt_log(LOG_ERR, "Trace status could not be sent!\n");
    1863           0 :         context->trace_status = old_trace_status;
    1864           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, (uint32_t) id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    1865             :     }
    1866           0 : }
    1867             : 
    1868           0 : void dlt_daemon_find_multiple_context_and_send_trace_status(int sock,
    1869             :                                                             DltDaemon *daemon,
    1870             :                                                             DltDaemonLocal *daemon_local,
    1871             :                                                             int8_t app_flag,
    1872             :                                                             char *str,
    1873             :                                                             int8_t len,
    1874             :                                                             int8_t tracestatus,
    1875             :                                                             int verbose)
    1876             : {
    1877           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1878             : 
    1879             :     int count = 0;
    1880             :     DltDaemonContext *context = NULL;
    1881           0 :     char src_str[DLT_ID_SIZE + 1] = { 0 };
    1882             :     int ret = 0;
    1883             :     DltDaemonRegisteredUsers *user_list = NULL;
    1884             : 
    1885           0 :     if (daemon == 0) {
    1886           0 :         dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
    1887           0 :         return;
    1888             :     }
    1889             : 
    1890           0 :     user_list = dlt_daemon_find_users_list(daemon, daemon->ecuid, verbose);
    1891             : 
    1892           0 :     if (user_list == NULL)
    1893             :         return;
    1894             : 
    1895           0 :     for (count = 0; count < user_list->num_contexts; count++) {
    1896           0 :         context = &(user_list->contexts[count]);
    1897             : 
    1898           0 :         if (context) {
    1899           0 :             if (app_flag == 1)
    1900           0 :                 strncpy(src_str, context->apid, DLT_ID_SIZE);
    1901             :             else
    1902           0 :                 strncpy(src_str, context->ctid, DLT_ID_SIZE);
    1903             : 
    1904           0 :             ret = strncmp(src_str, str, len);
    1905             : 
    1906           0 :             if (ret == 0)
    1907           0 :                 dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, tracestatus, verbose);
    1908           0 :             else if ((ret > 0) && (app_flag == 1))
    1909             :                 break;
    1910             :             else
    1911           0 :                 continue;
    1912             :         }
    1913             :     }
    1914             : }
    1915             : 
    1916           0 : void dlt_daemon_control_set_trace_status(int sock,
    1917             :                                          DltDaemon *daemon,
    1918             :                                          DltDaemonLocal *daemon_local,
    1919             :                                          DltMessage *msg,
    1920             :                                          int verbose)
    1921             : {
    1922           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1923             : 
    1924           0 :     char apid[DLT_ID_SIZE + 1] = { 0 };
    1925           0 :     char ctid[DLT_ID_SIZE + 1] = { 0 };
    1926             :     DltServiceSetLogLevel *req = NULL;
    1927             :     DltDaemonContext *context = NULL;
    1928             :     int8_t apid_length = 0;
    1929             :     int8_t ctid_length = 0;
    1930             : 
    1931           0 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
    1932           0 :         return;
    1933             : 
    1934           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetLogLevel)) < 0)
    1935             :         return;
    1936             : 
    1937           0 :     req = (DltServiceSetLogLevel *)(msg->databuffer);
    1938             : 
    1939           0 :     if (daemon_local->flags.enforceContextLLAndTS)
    1940           0 :         req->log_level = (uint8_t) getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
    1941             : 
    1942           0 :     dlt_set_id(apid, req->apid);
    1943           0 :     dlt_set_id(ctid, req->ctid);
    1944           0 :     apid_length = (int8_t) strlen(apid);
    1945           0 :     ctid_length = (int8_t) strlen(ctid);
    1946             : 
    1947           0 :     if ((apid_length != 0) && (apid[apid_length - 1] == '*') && (ctid[0] == 0)) { /*apid provided having '*' in it and ctid is null*/
    1948           0 :         dlt_daemon_find_multiple_context_and_send_trace_status(sock,
    1949             :                                                                daemon,
    1950             :                                                                daemon_local,
    1951             :                                                                1,
    1952             :                                                                apid,
    1953           0 :                                                                (int8_t) (apid_length - 1),
    1954           0 :                                                                (int8_t) req->log_level,
    1955             :                                                                verbose);
    1956             :     }
    1957           0 :     else if ((ctid_length != 0) && (ctid[ctid_length - 1] == '*') && (apid[0] == 0)) /*ctid provided is having '*' in it and apid is null*/
    1958             : 
    1959             :     {
    1960           0 :         dlt_daemon_find_multiple_context_and_send_trace_status(sock,
    1961             :                                                                daemon,
    1962             :                                                                daemon_local,
    1963             :                                                                0,
    1964             :                                                                ctid,
    1965           0 :                                                                (int8_t) (ctid_length - 1),
    1966           0 :                                                                (int8_t) req->log_level,
    1967             :                                                                verbose);
    1968             :     }
    1969           0 :     else if ((apid_length != 0) && (apid[apid_length - 1] != '*') && (ctid[0] == 0)) /*only app id case*/
    1970             :     {
    1971           0 :         dlt_daemon_find_multiple_context_and_send_trace_status(sock,
    1972             :                                                                daemon,
    1973             :                                                                daemon_local,
    1974             :                                                                1,
    1975             :                                                                apid,
    1976             :                                                                DLT_ID_SIZE,
    1977           0 :                                                                (int8_t) req->log_level,
    1978             :                                                                verbose);
    1979             :     }
    1980           0 :     else if ((ctid_length != 0) && (ctid[ctid_length - 1] != '*') && (apid[0] == 0)) /*only context id case*/
    1981             :     {
    1982           0 :         dlt_daemon_find_multiple_context_and_send_trace_status(sock,
    1983             :                                                                daemon,
    1984             :                                                                daemon_local,
    1985             :                                                                0,
    1986             :                                                                ctid,
    1987             :                                                                DLT_ID_SIZE,
    1988           0 :                                                                (int8_t) req->log_level,
    1989             :                                                                verbose);
    1990             :     }
    1991             :     else {
    1992           0 :         context = dlt_daemon_context_find(daemon, apid, ctid, daemon->ecuid, verbose);
    1993             : 
    1994             :         /* Set trace status */
    1995           0 :         if (context != 0) {
    1996           0 :             dlt_daemon_send_trace_status(sock, daemon, daemon_local, context, (int8_t) req->log_level, verbose);
    1997             :         }
    1998             :         else {
    1999           0 :             dlt_vlog(LOG_ERR,
    2000             :                      "Could not set trace status: %d. Context [%.4s:%.4s] not found:",
    2001           0 :                      req->log_level,
    2002             :                      apid,
    2003             :                      ctid);
    2004           0 :             dlt_daemon_control_service_response(sock,
    2005             :                                                 daemon,
    2006             :                                                 daemon_local,
    2007             :                                                 DLT_SERVICE_ID_SET_LOG_LEVEL,
    2008             :                                                 DLT_SERVICE_RESPONSE_ERROR,
    2009             :                                                 verbose);
    2010             :         }
    2011             :     }
    2012             : }
    2013             : 
    2014           0 : void dlt_daemon_control_set_default_log_level(int sock,
    2015             :                                               DltDaemon *daemon,
    2016             :                                               DltDaemonLocal *daemon_local,
    2017             :                                               DltMessage *msg,
    2018             :                                               int verbose)
    2019             : {
    2020           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2021             : 
    2022             :     DltServiceSetDefaultLogLevel *req;
    2023             :     uint32_t id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
    2024             : 
    2025           0 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
    2026             :         return;
    2027             : 
    2028           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
    2029             :         return;
    2030             : 
    2031           0 :     req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
    2032             : 
    2033             :     /* No endianess conversion necessary */
    2034           0 :     if (/*(req->log_level>=0) &&*/
    2035           0 :         (req->log_level <= DLT_LOG_VERBOSE)) {
    2036           0 :         if (daemon_local->flags.enforceContextLLAndTS)
    2037           0 :             daemon->default_log_level = getStatus(req->log_level, daemon_local->flags.contextLogLevel);
    2038             :         else
    2039           0 :             daemon->default_log_level = (int8_t) req->log_level; /* No endianess conversion necessary */
    2040             : 
    2041             :         /* Send Update to all contexts using the default log level */
    2042           0 :         dlt_daemon_user_send_default_update(daemon, verbose);
    2043             : 
    2044           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
    2045             :     }
    2046             :     else {
    2047           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    2048             :     }
    2049             : }
    2050             : 
    2051           0 : void dlt_daemon_control_set_all_log_level(int sock,
    2052             :                                           DltDaemon *daemon,
    2053             :                                           DltDaemonLocal *daemon_local,
    2054             :                                           DltMessage *msg,
    2055             :                                           int verbose)
    2056             : {
    2057           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2058             : 
    2059             :     DltServiceSetDefaultLogLevel *req = NULL;
    2060             :     uint32_t id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL;
    2061             :     int8_t loglevel = 0;
    2062             : 
    2063           0 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) {
    2064           0 :         dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
    2065           0 :         return;
    2066             :     }
    2067             : 
    2068           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
    2069             :         return;
    2070             : 
    2071           0 :     req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
    2072             : 
    2073             :     /* No endianess conversion necessary */
    2074           0 :     if ((req != NULL) && ((req->log_level <= DLT_LOG_VERBOSE) || (req->log_level == (uint8_t)DLT_LOG_DEFAULT))) {
    2075           0 :         loglevel = (int8_t) req->log_level;
    2076             : 
    2077             :         /* Send Update to all contexts using the new log level */
    2078           0 :         dlt_daemon_user_send_all_log_level_update(
    2079             :             daemon,
    2080             :             daemon_local->flags.enforceContextLLAndTS,
    2081           0 :             (int8_t)daemon_local->flags.contextLogLevel,
    2082             :             loglevel,
    2083             :             verbose);
    2084             : 
    2085           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
    2086             :     }
    2087             :     else {
    2088           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    2089             :     }
    2090             : }
    2091             : 
    2092           0 : void dlt_daemon_control_set_default_trace_status(int sock,
    2093             :                                                  DltDaemon *daemon,
    2094             :                                                  DltDaemonLocal *daemon_local,
    2095             :                                                  DltMessage *msg,
    2096             :                                                  int verbose)
    2097             : {
    2098           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2099             : 
    2100             :     /* Payload of request message */
    2101             :     DltServiceSetDefaultLogLevel *req;
    2102             :     uint32_t id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
    2103             : 
    2104           0 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
    2105             :         return;
    2106             : 
    2107           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
    2108             :         return;
    2109             : 
    2110           0 :     req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
    2111             : 
    2112             :     /* No endianess conversion necessary */
    2113           0 :     if ((req->log_level == DLT_TRACE_STATUS_OFF) ||
    2114             :         (req->log_level == DLT_TRACE_STATUS_ON)) {
    2115           0 :         if (daemon_local->flags.enforceContextLLAndTS)
    2116           0 :             daemon->default_trace_status = getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
    2117             :         else
    2118           0 :             daemon->default_trace_status = (int8_t) req->log_level; /* No endianess conversion necessary*/
    2119             : 
    2120             :         /* Send Update to all contexts using the default trace status */
    2121           0 :         dlt_daemon_user_send_default_update(daemon, verbose);
    2122             : 
    2123           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
    2124             :     }
    2125             :     else {
    2126           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    2127             :     }
    2128             : }
    2129             : 
    2130           0 : void dlt_daemon_control_set_all_trace_status(int sock,
    2131             :                                              DltDaemon *daemon,
    2132             :                                              DltDaemonLocal *daemon_local,
    2133             :                                              DltMessage *msg,
    2134             :                                              int verbose)
    2135             : {
    2136           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2137             : 
    2138             :     DltServiceSetDefaultLogLevel *req = NULL;
    2139             :     uint32_t id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS;
    2140             :     int8_t tracestatus = 0;
    2141             : 
    2142           0 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL)) {
    2143           0 :         dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
    2144           0 :         return;
    2145             :     }
    2146             : 
    2147           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetDefaultLogLevel)) < 0)
    2148             :         return;
    2149             : 
    2150           0 :     req = (DltServiceSetDefaultLogLevel *)(msg->databuffer);
    2151             : 
    2152             :     /* No endianess conversion necessary */
    2153           0 :     if ((req != NULL) &&
    2154           0 :         ((req->log_level <= DLT_TRACE_STATUS_ON) || (req->log_level == (uint8_t)DLT_TRACE_STATUS_DEFAULT))) {
    2155           0 :         if (daemon_local->flags.enforceContextLLAndTS)
    2156           0 :             tracestatus = getStatus(req->log_level, daemon_local->flags.contextTraceStatus);
    2157             :         else
    2158           0 :             tracestatus = (int8_t) req->log_level; /* No endianess conversion necessary */
    2159             : 
    2160             :         /* Send Update to all contexts using the new log level */
    2161           0 :         dlt_daemon_user_send_all_trace_status_update(daemon, tracestatus, verbose);
    2162             : 
    2163           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
    2164             :     }
    2165             :     else {
    2166           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    2167             :     }
    2168             : }
    2169             : 
    2170           0 : void dlt_daemon_control_set_timing_packets(int sock,
    2171             :                                            DltDaemon *daemon,
    2172             :                                            DltDaemonLocal *daemon_local,
    2173             :                                            DltMessage *msg,
    2174             :                                            int verbose)
    2175             : {
    2176           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2177             : 
    2178             :     DltServiceSetVerboseMode *req;  /* request uses same struct as set verbose mode */
    2179             :     uint32_t id = DLT_SERVICE_ID_SET_TIMING_PACKETS;
    2180             : 
    2181           0 :     if ((daemon == NULL) || (msg == NULL) || (msg->databuffer == NULL))
    2182             :         return;
    2183             : 
    2184           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceSetVerboseMode)) < 0)
    2185             :         return;
    2186             : 
    2187           0 :     req = (DltServiceSetVerboseMode *)(msg->databuffer);
    2188             : 
    2189           0 :     if ((req->new_status == 0) || (req->new_status == 1)) {
    2190           0 :         daemon->timingpackets = req->new_status;
    2191             : 
    2192           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_OK, verbose);
    2193             :     }
    2194             :     else {
    2195           0 :         dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
    2196             :     }
    2197             : }
    2198             : 
    2199           0 : void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
    2200             : {
    2201             :     DltMessage msg;
    2202             :     int32_t len;
    2203             : 
    2204           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2205             : 
    2206           0 :     if (daemon == 0)
    2207           0 :         return;
    2208             : 
    2209             :     /* initialise new message */
    2210           0 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
    2211             :         return;
    2212             : 
    2213             :     /* send message */
    2214             : 
    2215             :     /* prepare storage header */
    2216           0 :     msg.storageheader = (DltStorageHeader *)msg.headerbuffer;
    2217           0 :     dlt_set_storageheader(msg.storageheader, daemon->ecuid);
    2218             : 
    2219             :     /* prepare standard header */
    2220           0 :     msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader));
    2221           0 :     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
    2222             : 
    2223             : #if (BYTE_ORDER == BIG_ENDIAN)
    2224             :     msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
    2225             : #endif
    2226             : 
    2227           0 :     msg.standardheader->mcnt = 0;
    2228             : 
    2229             :     /* Set header extra parameters */
    2230           0 :     dlt_set_id(msg.headerextra.ecu, daemon->ecuid);
    2231           0 :     msg.headerextra.tmsp = dlt_uptime();
    2232             : 
    2233           0 :     dlt_message_set_extraparameters(&msg, verbose);
    2234             : 
    2235             :     /* prepare extended header */
    2236           0 :     msg.extendedheader =
    2237           0 :         (DltExtendedHeader *)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    2238           0 :                               DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
    2239           0 :     msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
    2240             : 
    2241           0 :     msg.extendedheader->noar = 0;                  /* number of arguments */
    2242           0 :     dlt_set_id(msg.extendedheader->apid, "");       /* application id */
    2243           0 :     dlt_set_id(msg.extendedheader->ctid, "");       /* context id */
    2244             : 
    2245             :     /* prepare length information */
    2246           0 :     msg.headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) +
    2247           0 :         DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
    2248             : 
    2249           0 :     len = (int32_t) (msg.headersize - sizeof(DltStorageHeader) + msg.datasize);
    2250             : 
    2251           0 :     if (len > UINT16_MAX) {
    2252           0 :         dlt_log(LOG_WARNING, "Huge control message discarded!\n");
    2253             : 
    2254             :         /* free message */
    2255           0 :         dlt_message_free(&msg, 0);
    2256             : 
    2257           0 :         return;
    2258             :     }
    2259             : 
    2260           0 :     msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
    2261             : 
    2262             :     /* Send message, ignore return value */
    2263           0 :     dlt_daemon_client_send(sock, daemon, daemon_local, msg.headerbuffer,
    2264             :                            sizeof(DltStorageHeader),
    2265             :                            msg.headerbuffer + sizeof(DltStorageHeader),
    2266             :                            (int) msg.headersize - (int) sizeof(DltStorageHeader),
    2267           0 :                            msg.databuffer, (int) msg.datasize, verbose);
    2268             : 
    2269             :     /* free message */
    2270           0 :     dlt_message_free(&msg, 0);
    2271             : }
    2272             : 
    2273          11 : int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
    2274             :                                    DltDaemonLocal *daemon_local,
    2275             :                                    DltReceiver *receiver,
    2276             :                                    int verbose)
    2277             : {
    2278          11 :     uint64_t expir = 0;
    2279             :     ssize_t res = 0;
    2280             : 
    2281          11 :     PRINT_FUNCTION_VERBOSE(verbose);
    2282             : 
    2283          11 :     if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
    2284           0 :         dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
    2285           0 :         return -1;
    2286             :     }
    2287             : 
    2288          11 :     res = read(receiver->fd, &expir, sizeof(expir));
    2289             : 
    2290          11 :     if (res < 0) {
    2291           0 :         dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__,
    2292           0 :                  strerror(errno));
    2293             :         /* Activity received on timer_wd, but unable to read the fd:
    2294             :          * let's go on sending notification */
    2295             :     }
    2296             : 
    2297          11 :     if ((daemon->state == DLT_DAEMON_STATE_SEND_BUFFER) ||
    2298             :         (daemon->state == DLT_DAEMON_STATE_BUFFER_FULL)) {
    2299           0 :         if (dlt_daemon_send_ringbuffer_to_client(daemon,
    2300             :                                                  daemon_local,
    2301             :                                                  daemon_local->flags.vflag))
    2302           0 :             dlt_log(LOG_DEBUG,
    2303             :                     "Can't send contents of ring buffer to clients\n");
    2304             :     }
    2305             : 
    2306          11 :     if ((daemon->timingpackets) &&
    2307           0 :         (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT))
    2308           0 :         dlt_daemon_control_message_time(DLT_DAEMON_SEND_TO_ALL,
    2309             :                                         daemon,
    2310             :                                         daemon_local,
    2311             :                                         daemon_local->flags.vflag);
    2312             : 
    2313          11 :     dlt_log(LOG_DEBUG, "Timer timingpacket\n");
    2314             : 
    2315          11 :     return 0;
    2316             : }
    2317             : 
    2318           0 : int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
    2319             :                                      DltDaemonLocal *daemon_local,
    2320             :                                      DltReceiver *receiver,
    2321             :                                      int verbose)
    2322             : {
    2323           0 :     uint64_t expir = 0;
    2324             :     ssize_t res = 0;
    2325             : 
    2326           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2327             : 
    2328           0 :     if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
    2329           0 :         dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
    2330           0 :         return -1;
    2331             :     }
    2332             : 
    2333           0 :     res = read(receiver->fd, &expir, sizeof(expir));
    2334             : 
    2335           0 :     if (res < 0) {
    2336           0 :         dlt_vlog(LOG_WARNING, "%s: Fail to read timer (%s)\n", __func__,
    2337           0 :                  strerror(errno));
    2338             :         /* Activity received on timer_wd, but unable to read the fd:
    2339             :          * let's go on sending notification */
    2340             :     }
    2341             : 
    2342           0 :     if (daemon_local->flags.sendECUSoftwareVersion > 0)
    2343           0 :         dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL,
    2344             :                                                 daemon,
    2345             :                                                 daemon_local,
    2346             :                                                 daemon_local->flags.vflag);
    2347             : 
    2348           0 :     if (daemon_local->flags.sendTimezone > 0) {
    2349             :         /* send timezone information */
    2350           0 :         time_t t = time(NULL);
    2351             :         struct tm lt;
    2352             : 
    2353             :         /*Added memset to avoid compiler warning for near initialization */
    2354             :         memset((void *)&lt, 0, sizeof(lt));
    2355           0 :         tzset();
    2356           0 :         localtime_r(&t, &lt);
    2357             : 
    2358           0 :         dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,
    2359             :                                             daemon,
    2360             :                                             daemon_local,
    2361             :                                             daemon_local->flags.vflag);
    2362             :     }
    2363             : 
    2364           0 :     dlt_log(LOG_DEBUG, "Timer ecuversion\n");
    2365             : 
    2366           0 :     return 0;
    2367             : }
    2368             : 
    2369             : #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
    2370             : int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
    2371             :                                      DltDaemonLocal *daemon_local,
    2372             :                                      DltReceiver *receiver,
    2373             :                                      int verbose)
    2374             : {
    2375             :     uint64_t expir = 0;
    2376             :     ssize_t res = -1;
    2377             : 
    2378             :     PRINT_FUNCTION_VERBOSE(verbose);
    2379             : 
    2380             :     if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
    2381             :         dlt_vlog(LOG_ERR, "%s: invalid parameters", __func__);
    2382             :         return res;
    2383             :     }
    2384             : 
    2385             :     res = read(receiver->fd, &expir, sizeof(expir));
    2386             : 
    2387             :     if (res < 0) {
    2388             :         dlt_vlog(LOG_WARNING, "Failed to read timer_wd; %s\n", strerror(errno));
    2389             :         /* Activity received on timer_wd, but unable to read the fd:
    2390             :          * let's go on sending notification */
    2391             :     }
    2392             : 
    2393             : #ifdef DLT_SYSTEMD_WATCHDOG_ENFORCE_MSG_RX_ENABLE
    2394             :     if (!daemon->received_message_since_last_watchdog_interval) {
    2395             :       dlt_log(LOG_WARNING, "No new messages received since last watchdog timer run\n");
    2396             :       return 0;
    2397             :     }
    2398             :     daemon->received_message_since_last_watchdog_interval = 0;
    2399             : #endif
    2400             : 
    2401             :     if (sd_notify(0, "WATCHDOG=1") < 0)
    2402             :         dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
    2403             : 
    2404             :     dlt_log(LOG_DEBUG, "Timer watchdog\n");
    2405             : 
    2406             :     return 0;
    2407             : }
    2408             : #else
    2409           0 : int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
    2410             :                                      DltDaemonLocal *daemon_local,
    2411             :                                      DltReceiver *receiver,
    2412             :                                      int verbose)
    2413             : {
    2414             :     (void)daemon;
    2415             :     (void)daemon_local;
    2416             :     (void)receiver;
    2417             :     (void)verbose;
    2418             : 
    2419           0 :     dlt_log(LOG_DEBUG, "Timer watchdog not enabled\n");
    2420             : 
    2421           0 :     return -1;
    2422             : }
    2423             : #endif
    2424             : 
    2425           2 : void dlt_daemon_control_service_logstorage(int sock,
    2426             :                                            DltDaemon *daemon,
    2427             :                                            DltDaemonLocal *daemon_local,
    2428             :                                            DltMessage *msg,
    2429             :                                            int verbose)
    2430             : {
    2431             :     DltServiceOfflineLogstorage *req = NULL;
    2432             :     int ret = 0;
    2433             :     unsigned int connection_type = 0;
    2434             :     DltLogStorage *device = NULL;
    2435             :     int device_index = -1;
    2436             :     uint32_t i = 0;
    2437             : 
    2438             :     int tmp_errno = 0;
    2439             : 
    2440           2 :     struct stat daemon_mpoint_st = {0};
    2441             :     int daemon_st_status = 0;
    2442             : 
    2443           2 :     struct stat req_mpoint_st = {0};
    2444             :     int req_st_status = 0;
    2445             : 
    2446           2 :     PRINT_FUNCTION_VERBOSE(verbose);
    2447             : 
    2448           2 :     if ((daemon == NULL) || (msg == NULL) || (daemon_local == NULL)) {
    2449           0 :         dlt_vlog(LOG_ERR,
    2450             :                  "%s: Invalid function parameters\n",
    2451             :                  __func__);
    2452           0 :         return;
    2453             :     }
    2454             : 
    2455           2 :     if ((daemon_local->flags.offlineLogstorageMaxDevices <= 0) || (msg->databuffer == NULL)) {
    2456           0 :         dlt_daemon_control_service_response(sock,
    2457             :                                             daemon,
    2458             :                                             daemon_local,
    2459             :                                             DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2460             :                                             DLT_SERVICE_RESPONSE_ERROR,
    2461             :                                             verbose);
    2462             : 
    2463           0 :         dlt_log(LOG_INFO,
    2464             :                 "Logstorage functionality not enabled or MAX device set is 0\n");
    2465           0 :         return;
    2466             :     }
    2467             : 
    2468           2 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceOfflineLogstorage)) < 0)
    2469             :         return;
    2470             : 
    2471           2 :     req = (DltServiceOfflineLogstorage *)(msg->databuffer);
    2472             : 
    2473           2 :     if(req->connection_type != DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) {
    2474           0 :         req_st_status = stat(req->mount_point, &req_mpoint_st);
    2475           0 :         tmp_errno = errno;
    2476           0 :         if (req_st_status < 0) {
    2477           0 :             dlt_daemon_control_service_response(sock,
    2478             :                                                 daemon,
    2479             :                                                 daemon_local,
    2480             :                                                 DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2481             :                                                 DLT_SERVICE_RESPONSE_ERROR,
    2482             :                                                 verbose);
    2483             : 
    2484           0 :             dlt_vlog(LOG_WARNING,
    2485             :                      "%s: Failed to stat requested mount point [%s] with error [%s]\n",
    2486             :                      __func__, req->mount_point, strerror(tmp_errno));
    2487           0 :             return;
    2488             :         }
    2489             :     }
    2490             : 
    2491           4 :     for (i = 0; i < (uint32_t) daemon_local->flags.offlineLogstorageMaxDevices; i++) {
    2492           2 :         connection_type = daemon->storage_handle[i].connection_type;
    2493             : 
    2494             :         memset(&daemon_mpoint_st, 0, sizeof(struct stat));
    2495           2 :         if (strlen(daemon->storage_handle[i].device_mount_point) > 1) {
    2496           0 :             daemon_st_status = stat(daemon->storage_handle[i].device_mount_point,
    2497             :                     &daemon_mpoint_st);
    2498           0 :             tmp_errno = errno;
    2499             : 
    2500           0 :             if (daemon_st_status < 0) {
    2501           0 :                 dlt_daemon_control_service_response(sock,
    2502             :                                                     daemon,
    2503             :                                                     daemon_local,
    2504             :                                                     DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2505             :                                                     DLT_SERVICE_RESPONSE_ERROR,
    2506             :                                                     verbose);
    2507           0 :                 dlt_vlog(LOG_WARNING,
    2508             :                         "%s: Failed to stat daemon mount point [%s] with error [%s]\n",
    2509           0 :                         __func__, daemon->storage_handle[i].device_mount_point,
    2510             :                         strerror(tmp_errno));
    2511           0 :                 return;
    2512             :             }
    2513             : 
    2514             :             /* Check if the requested device path is already used as log storage device */
    2515           0 :             if (req_mpoint_st.st_dev == daemon_mpoint_st.st_dev &&
    2516           0 :                     req_mpoint_st.st_ino == daemon_mpoint_st.st_ino) {
    2517           0 :                 device_index = (int) i;
    2518           0 :                 break;
    2519             :             }
    2520             :         }
    2521             : 
    2522             :         /* Get first available device index here */
    2523           2 :         if ((connection_type != DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) &&
    2524           2 :             (device_index == -1))
    2525           0 :             device_index = (int) i;
    2526             :     }
    2527             : 
    2528             :     /* It might be possible to sync all caches of all devices */
    2529           2 :     if ((req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES) &&
    2530           2 :         (strlen(req->mount_point) == 0)) {
    2531             :         /* It is expected to receive an empty mount point to sync all Logstorage
    2532             :          * devices in this case. */
    2533             :     }
    2534           0 :     else if (device_index == -1) {
    2535           0 :         dlt_daemon_control_service_response(sock,
    2536             :                                             daemon,
    2537             :                                             daemon_local,
    2538             :                                             DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2539             :                                             DLT_SERVICE_RESPONSE_ERROR,
    2540             :                                             verbose);
    2541           0 :         dlt_log(LOG_WARNING, "MAX devices already in use  \n");
    2542           0 :         return;
    2543             :     }
    2544             : 
    2545             :     /* Check for device connection request from log storage ctrl app  */
    2546           2 :     device = &daemon->storage_handle[device_index];
    2547             : 
    2548           2 :     if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED) {
    2549           0 :         ret = dlt_logstorage_device_connected(device, req->mount_point);
    2550             : 
    2551           0 :         if (ret == 1) {
    2552           0 :             dlt_daemon_control_service_response(sock,
    2553             :                                                 daemon,
    2554             :                                                 daemon_local,
    2555             :                                                 DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2556             :                                                 DLT_SERVICE_RESPONSE_WARNING,
    2557             :                                                 verbose);
    2558           0 :             return;
    2559             :         }
    2560           0 :         else if (ret != 0)
    2561             :         {
    2562           0 :             dlt_daemon_control_service_response(sock,
    2563             :                                                 daemon,
    2564             :                                                 daemon_local,
    2565             :                                                 DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2566             :                                                 DLT_SERVICE_RESPONSE_ERROR,
    2567             :                                                 verbose);
    2568           0 :             return;
    2569             :         }
    2570             : 
    2571           0 :         dlt_daemon_control_service_response(sock,
    2572             :                                             daemon,
    2573             :                                             daemon_local,
    2574             :                                             DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2575             :                                             DLT_SERVICE_RESPONSE_OK,
    2576             :                                             verbose);
    2577             : 
    2578             :         /* Update maintain logstorage loglevel if necessary */
    2579           0 :         if (daemon->storage_handle[device_index].maintain_logstorage_loglevel != DLT_MAINTAIN_LOGSTORAGE_LOGLEVEL_UNDEF)
    2580             :         {
    2581           0 :             daemon->maintain_logstorage_loglevel = daemon->storage_handle[device_index].maintain_logstorage_loglevel;
    2582             :         }
    2583             : 
    2584             :         /* Check if log level of running application needs an update */
    2585           0 :         dlt_daemon_logstorage_update_application_loglevel(daemon,
    2586             :                                                           daemon_local,
    2587             :                                                           device_index,
    2588             :                                                           verbose);
    2589             : 
    2590             :     }
    2591             :     /* Check for device disconnection request from log storage ctrl app  */
    2592           2 :     else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_DISCONNECTED)
    2593             :     {
    2594             :         /* Check if log level of running application needs to be reset */
    2595           0 :         dlt_daemon_logstorage_reset_application_loglevel(
    2596             :             daemon,
    2597             :             daemon_local,
    2598             :             device_index,
    2599             :             (int) daemon_local->flags.offlineLogstorageMaxDevices,
    2600             :             verbose);
    2601             : 
    2602           0 :         dlt_logstorage_device_disconnected(&(daemon->storage_handle[device_index]),
    2603             :                                            DLT_LOGSTORAGE_SYNC_ON_DEVICE_DISCONNECT);
    2604             : 
    2605           0 :         dlt_daemon_control_service_response(sock,
    2606             :                                             daemon,
    2607             :                                             daemon_local,
    2608             :                                             DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2609             :                                             DLT_SERVICE_RESPONSE_OK,
    2610             :                                             verbose);
    2611             : 
    2612             :     }
    2613             :     /* Check for cache synchronization request from log storage ctrl app */
    2614           2 :     else if (req->connection_type == DLT_OFFLINE_LOGSTORAGE_SYNC_CACHES)
    2615             :     {
    2616             :         ret = 0;
    2617             : 
    2618           2 :         if (device_index == -1) { /* sync all Logstorage devices */
    2619             : 
    2620           4 :             for (i = 0; i < (uint32_t) daemon_local->flags.offlineLogstorageMaxDevices; i++)
    2621           2 :                 if (daemon->storage_handle[i].connection_type ==
    2622             :                     DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
    2623           2 :                     ret = dlt_daemon_logstorage_sync_cache(
    2624             :                         daemon,
    2625             :                         daemon_local,
    2626           2 :                         daemon->storage_handle[i].device_mount_point,
    2627             :                         verbose);
    2628             :         }
    2629             :         else {
    2630             :             /* trigger logstorage to sync caches */
    2631           0 :             ret = dlt_daemon_logstorage_sync_cache(daemon,
    2632             :                                                    daemon_local,
    2633           0 :                                                    req->mount_point,
    2634             :                                                    verbose);
    2635             :         }
    2636             : 
    2637           2 :         if (ret == 0)
    2638           2 :             dlt_daemon_control_service_response(sock,
    2639             :                                                 daemon,
    2640             :                                                 daemon_local,
    2641             :                                                 DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2642             :                                                 DLT_SERVICE_RESPONSE_OK,
    2643             :                                                 verbose);
    2644             :         else
    2645           0 :             dlt_daemon_control_service_response(sock,
    2646             :                                                 daemon,
    2647             :                                                 daemon_local,
    2648             :                                                 DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2649             :                                                 DLT_SERVICE_RESPONSE_ERROR,
    2650             :                                                 verbose);
    2651             :     }
    2652             :     else {
    2653           0 :         dlt_daemon_control_service_response(sock,
    2654             :                                             daemon,
    2655             :                                             daemon_local,
    2656             :                                             DLT_SERVICE_ID_OFFLINE_LOGSTORAGE,
    2657             :                                             DLT_SERVICE_RESPONSE_ERROR,
    2658             :                                             verbose);
    2659             :     }
    2660             : }
    2661             : 
    2662           0 : void dlt_daemon_control_passive_node_connect(int sock,
    2663             :                                              DltDaemon *daemon,
    2664             :                                              DltDaemonLocal *daemon_local,
    2665             :                                              DltMessage *msg,
    2666             :                                              int verbose)
    2667             : {
    2668           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2669             : 
    2670             :     DltServicePassiveNodeConnect *req;
    2671             :     uint32_t id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
    2672             : 
    2673           0 :     if ((daemon == NULL) || (daemon_local == NULL) || (msg == NULL) ||
    2674           0 :         (msg->databuffer == NULL))
    2675             :         return;
    2676             : 
    2677             :     /* return error, if gateway mode not enabled*/
    2678           0 :     if (daemon_local->flags.gatewayMode == 0) {
    2679           0 :         dlt_log(LOG_WARNING,
    2680             :                 "Received passive node connection status request, "
    2681             :                 "but GatewayMode is disabled\n");
    2682             : 
    2683           0 :         dlt_daemon_control_service_response(
    2684             :             sock,
    2685             :             daemon,
    2686             :             daemon_local,
    2687             :             DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
    2688             :             DLT_SERVICE_RESPONSE_ERROR,
    2689             :             verbose);
    2690             : 
    2691           0 :         return;
    2692             :     }
    2693             : 
    2694           0 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServicePassiveNodeConnect)) < 0)
    2695             :         return;
    2696             : 
    2697           0 :     req = (DltServicePassiveNodeConnect *)msg->databuffer;
    2698             : 
    2699           0 :     if (dlt_gateway_process_on_demand_request(&daemon_local->pGateway,
    2700             :                                               daemon_local,
    2701           0 :                                               req->node_id,
    2702           0 :                                               (int) req->connection_status,
    2703             :                                               verbose) < 0)
    2704           0 :         dlt_daemon_control_service_response(sock,
    2705             :                                             daemon,
    2706             :                                             daemon_local,
    2707             :                                             id,
    2708             :                                             DLT_SERVICE_RESPONSE_ERROR,
    2709             :                                             verbose);
    2710             :     else
    2711           0 :         dlt_daemon_control_service_response(sock,
    2712             :                                             daemon,
    2713             :                                             daemon_local,
    2714             :                                             id,
    2715             :                                             DLT_SERVICE_RESPONSE_OK,
    2716             :                                             verbose);
    2717             : }
    2718             : 
    2719           0 : void dlt_daemon_control_passive_node_connect_status(int sock,
    2720             :                                                     DltDaemon *daemon,
    2721             :                                                     DltDaemonLocal *daemon_local,
    2722             :                                                     int verbose)
    2723             : {
    2724             :     DltMessage msg;
    2725             :     DltServicePassiveNodeConnectionInfo *resp;
    2726             :     DltGatewayConnection *con = NULL;
    2727             :     unsigned int i = 0;
    2728             : 
    2729           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2730             : 
    2731           0 :     if ((daemon == NULL) || (daemon_local == NULL))
    2732           0 :         return;
    2733             : 
    2734           0 :     if (dlt_message_init(&msg, verbose) == -1)
    2735             :         return;
    2736             : 
    2737             :     /* return error, if gateway mode not enabled*/
    2738           0 :     if (daemon_local->flags.gatewayMode == 0) {
    2739           0 :         dlt_log(LOG_WARNING,
    2740             :                 "Received passive node connection status request, "
    2741             :                 "but GatewayMode is disabled\n");
    2742             : 
    2743           0 :         dlt_daemon_control_service_response(
    2744             :             sock,
    2745             :             daemon,
    2746             :             daemon_local,
    2747             :             DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
    2748             :             DLT_SERVICE_RESPONSE_ERROR,
    2749             :             verbose);
    2750             : 
    2751           0 :         return;
    2752             :     }
    2753             : 
    2754             :     /* prepare payload of data */
    2755           0 :     msg.datasize = sizeof(DltServicePassiveNodeConnectionInfo);
    2756             : 
    2757           0 :     if (msg.databuffer && (msg.databuffersize < msg.datasize))
    2758           0 :         msg.databuffer = NULL;
    2759             : 
    2760           0 :     if (msg.databuffer == NULL) {
    2761           0 :         msg.databuffer = (uint8_t *)malloc(msg.datasize);
    2762             : 
    2763           0 :         if (msg.databuffer == NULL) {
    2764           0 :             dlt_log(LOG_CRIT, "Cannot allocate memory for message response\n");
    2765           0 :             return;
    2766             :         }
    2767             : 
    2768           0 :         msg.databuffersize = msg.datasize;
    2769             :     }
    2770             : 
    2771           0 :     resp = (DltServicePassiveNodeConnectionInfo *)msg.databuffer;
    2772             :     memset(resp, 0, msg.datasize);
    2773           0 :     resp->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS;
    2774             :     resp->status = DLT_SERVICE_RESPONSE_OK;
    2775           0 :     resp->num_connections = (uint32_t) daemon_local->pGateway.num_connections;
    2776             : 
    2777           0 :     for (i = 0; i < resp->num_connections; i++) {
    2778           0 :         if ((i * DLT_ID_SIZE) > DLT_ENTRY_MAX) {
    2779           0 :             dlt_log(LOG_ERR,
    2780             :                     "Maximal message size reached. Skip further information\n");
    2781           0 :             break;
    2782             :         }
    2783             : 
    2784           0 :         con = &daemon_local->pGateway.connections[i];
    2785             : 
    2786           0 :         resp->connection_status[i] = con->status;
    2787           0 :         memcpy(&resp->node_id[i * DLT_ID_SIZE], con->ecuid, DLT_ID_SIZE);
    2788             :     }
    2789             : 
    2790           0 :     dlt_daemon_client_send_control_message(sock,
    2791             :                                            daemon,
    2792             :                                            daemon_local,
    2793             :                                            &msg,
    2794             :                                            "",
    2795             :                                            "",
    2796             :                                            verbose);
    2797             :     /* free message */
    2798           0 :     dlt_message_free(&msg, verbose);
    2799             : }

Generated by: LCOV version 1.14