LCOV - code coverage report
Current view: top level - daemon - dlt_daemon_client.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 26.9 % 965 260
Test Date: 2025-03-25 20:53:42 Functions: 39.4 % 33 13

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

Generated by: LCOV version 2.0-1