LCOV - code coverage report
Current view: top level - lib - dlt_client.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 44.9 % 523 235
Test Date: 2025-12-12 09:13:23 Functions: 48.4 % 31 15

            Line data    Source code
       1              : /*
       2              :  * SPDX license identifier: MPL-2.0
       3              :  *
       4              :  * Copyright (C) 2011-2015, BMW AG
       5              :  *
       6              :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       7              :  *
       8              :  * This Source Code Form is subject to the terms of the
       9              :  * Mozilla Public License (MPL), v. 2.0.
      10              :  * If a copy of the MPL was not distributed with this file,
      11              :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      12              :  *
      13              :  * For further information see http://www.covesa.org/.
      14              :  */
      15              : 
      16              : /*!
      17              :  * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de>
      18              :  *
      19              :  * \copyright Copyright © 2011-2015 BMW AG. \n
      20              :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      21              :  *
      22              :  * \file dlt_client.c
      23              :  */
      24              : 
      25              : /*******************************************************************************
      26              : **                                                                            **
      27              : **  SRC-MODULE: dlt_client.c                                                  **
      28              : **                                                                            **
      29              : **  TARGET    : linux                                                         **
      30              : **                                                                            **
      31              : **  PROJECT   : DLT                                                           **
      32              : **                                                                            **
      33              : **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
      34              : **              Markus Klein                                                  **
      35              : **                                                                            **
      36              : **  PURPOSE   :                                                               **
      37              : **                                                                            **
      38              : **  REMARKS   :                                                               **
      39              : **                                                                            **
      40              : **  PLATFORM DEPENDANT [yes/no]: yes                                          **
      41              : **                                                                            **
      42              : **  TO BE CHANGED BY USER [yes/no]: no                                        **
      43              : **                                                                            **
      44              : *******************************************************************************/
      45              : 
      46              : /*******************************************************************************
      47              : **                      Author Identity                                       **
      48              : ********************************************************************************
      49              : **                                                                            **
      50              : ** Initials     Name                       Company                            **
      51              : ** --------     -------------------------  ---------------------------------- **
      52              : **  aw          Alexander Wenzel           BMW                                **
      53              : **  mk          Markus Klein               Fraunhofer ESK                     **
      54              : *******************************************************************************/
      55              : 
      56              : /*******************************************************************************
      57              : **                      Revision Control History                              **
      58              : *******************************************************************************/
      59              : 
      60              : /*
      61              :  * $LastChangedRevision$
      62              :  * $LastChangedDate$
      63              :  * $LastChangedBy$
      64              :  * Initials    Date         Comment
      65              :  * aw          12.07.2010   initial
      66              :  */
      67              : 
      68              : #include <stdio.h>
      69              : 
      70              : #if defined (__WIN32__) || defined (_MSC_VER)
      71              : #   pragma warning(disable : 4996) /* Switch off C4996 warnings */
      72              : #   include <winsock2.h> /* for socket(), connect(), send(), and recv() */
      73              : #else
      74              : #   include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
      75              : 
      76              : #pragma GCC diagnostic ignored "-Wconversion"
      77              : #   include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
      78              : #pragma GCC diagnostic push
      79              : #pragma GCC diagnostic pop
      80              : 
      81              : #   include <netdb.h>
      82              : #   include <sys/stat.h>
      83              : #   include <sys/un.h>
      84              : #endif
      85              : 
      86              : #if defined(_MSC_VER)
      87              : #   include <io.h>
      88              : #else
      89              : #   include <unistd.h>
      90              : #   include <syslog.h>
      91              : #endif
      92              : 
      93              : #include <fcntl.h>
      94              : 
      95              : #include <stdlib.h> /* for malloc(), free() */
      96              : #include <string.h> /* for strlen(), memcmp(), memmove() */
      97              : #include <errno.h>
      98              : #include <limits.h>
      99              : #include <poll.h>
     100              : 
     101              : #include "dlt_types.h"
     102              : #include "dlt_log.h"
     103              : #include "dlt_client.h"
     104              : #include "dlt_client_cfg.h"
     105              : 
     106              : static int (*message_callback_function)(DltMessage *message, void *data) = NULL;
     107              : static bool (*fetch_next_message_callback_function)(void *data) = NULL;
     108              : 
     109            3 : void dlt_client_register_message_callback(int (*registerd_callback)(DltMessage *message, void *data))
     110              : {
     111            3 :     message_callback_function = registerd_callback;
     112            3 : }
     113              : 
     114            0 : void dlt_client_register_fetch_next_message_callback(bool (*registerd_callback)(void *data))
     115              : {
     116            0 :     fetch_next_message_callback_function = registerd_callback;
     117            0 : }
     118              : 
     119            8 : DltReturnValue dlt_client_init_port(DltClient *client, int port, int verbose)
     120              : {
     121            8 :     if (verbose && (port != DLT_DAEMON_TCP_PORT))
     122            0 :         dlt_vlog(LOG_INFO,
     123              :                  "%s: Init dlt client struct with port %d\n",
     124              :                  __func__,
     125              :                  port);
     126              : 
     127            8 :     if (client == NULL)
     128              :         return DLT_RETURN_ERROR;
     129              : 
     130            8 :     client->sock = -1;
     131            8 :     client->servIP = NULL;
     132            8 :     client->serialDevice = NULL;
     133            8 :     client->baudrate = DLT_CLIENT_INITIAL_BAUDRATE;
     134            8 :     client->port = (uint16_t)port;
     135            8 :     client->socketPath = NULL;
     136            8 :     client->mode = DLT_CLIENT_MODE_TCP;
     137            8 :     client->receiver.buffer = NULL;
     138            8 :     client->receiver.buf = NULL;
     139            8 :     client->receiver.backup_buf = NULL;
     140            8 :     client->hostip = NULL;
     141              : 
     142            8 :     return DLT_RETURN_OK;
     143              : }
     144              : 
     145            3 : DltReturnValue dlt_client_init(DltClient *client, int verbose)
     146              : {
     147              :     char *env_daemon_port;
     148              :     int tmp_port;
     149              :     /* the port may be specified by an environment variable, defaults to DLT_DAEMON_TCP_PORT */
     150              :     unsigned short servPort = DLT_DAEMON_TCP_PORT;
     151              : 
     152              :     /* the port may be specified by an environment variable */
     153            3 :     env_daemon_port = getenv(DLT_CLIENT_ENV_DAEMON_TCP_PORT);
     154              : 
     155            3 :     if (env_daemon_port != NULL) {
     156              :         tmp_port = atoi(env_daemon_port);
     157              : 
     158            0 :         if ((tmp_port < IPPORT_RESERVED) || ((unsigned)tmp_port > USHRT_MAX)) {
     159            0 :             dlt_vlog(LOG_ERR,
     160              :                      "%s: Specified port is out of possible range: %d.\n",
     161              :                      __func__,
     162              :                      tmp_port);
     163            0 :             return DLT_RETURN_ERROR;
     164              :         }
     165              :         else {
     166            0 :             servPort = (unsigned short)tmp_port;
     167              :         }
     168              :     }
     169              : 
     170            3 :     if (verbose)
     171            0 :         dlt_vlog(LOG_INFO,
     172              :                  "%s: Init dlt client struct with default port: %hu.\n",
     173              :                  __func__,
     174              :                  servPort);
     175            3 :     return dlt_client_init_port(client, servPort, verbose);
     176              : }
     177              : 
     178            9 : DltReturnValue dlt_client_connect(DltClient *client, int verbose)
     179              : {
     180            9 :     const int yes = 1;
     181            9 :     char portnumbuffer[33] = {0};
     182              :     struct addrinfo hints, *servinfo, *p;
     183              :     struct sockaddr_un addr;
     184              :     int rv;
     185              :     struct ip_mreq mreq;
     186              :     DltReceiverType receiver_type = DLT_RECEIVE_FD;
     187              : 
     188              :     struct pollfd pfds[1];
     189              :     int ret;
     190              :     int n;
     191            9 :     socklen_t m = sizeof(n);
     192              :     int connect_errno = 0;
     193              : 
     194              :     memset(&hints, 0, sizeof(hints));
     195            9 :     hints.ai_socktype = SOCK_STREAM;
     196              : 
     197            9 :     if (client == 0)
     198              :         return DLT_RETURN_ERROR;
     199              : 
     200            9 :     switch (client->mode) {
     201            7 :     case DLT_CLIENT_MODE_TCP:
     202            7 :         snprintf(portnumbuffer, 32, "%d", client->port);
     203              : 
     204            7 :         if ((rv = getaddrinfo(client->servIP, portnumbuffer, &hints, &servinfo)) != 0) {
     205            0 :             dlt_vlog(LOG_ERR,
     206              :                     "%s: getaddrinfo: %s\n",
     207              :                      __func__,
     208              :                      gai_strerror(rv));
     209            3 :             return DLT_RETURN_ERROR;
     210              :         }
     211              : 
     212           11 :         for (p = servinfo; p != NULL; p = p->ai_next) {
     213            8 :             if ((client->sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
     214            0 :                 dlt_vlog(LOG_WARNING,
     215              :                          "%s: socket() failed! %s\n",
     216              :                          __func__,
     217            0 :                          strerror(errno));
     218            0 :                 continue;
     219              :             }
     220              : 
     221              :             /* Set socket to Non-blocking mode */
     222            8 :             if(fcntl(client->sock, F_SETFL, fcntl(client->sock,F_GETFL,0) | O_NONBLOCK) < 0)
     223              :             {
     224            0 :                 dlt_vlog(LOG_WARNING,
     225              :                  "%s: Socket cannot be changed to NON BLOCK: %s\n",
     226            0 :                  __func__, strerror(errno));
     227            0 :                 close(client->sock);
     228            0 :                 continue;
     229              :             }
     230              : 
     231            8 :             if (connect(client->sock, p->ai_addr, p->ai_addrlen) < 0) {
     232            8 :                 if (errno == EINPROGRESS) {
     233            8 :                     pfds[0].fd = client->sock;
     234            8 :                     pfds[0].events = POLLOUT;
     235              :                     ret = poll(pfds, 1, 500);
     236            8 :                     if (ret < 0) {
     237            0 :                         dlt_vlog(LOG_ERR, "%s: Failed to poll with err [%s]\n",
     238              :                         __func__, strerror(errno));
     239            0 :                         close(client->sock);
     240            0 :                         continue;
     241              :                     }
     242           16 :                     else if ((pfds[0].revents & POLLOUT) &&
     243            8 :                             getsockopt(client->sock, SOL_SOCKET,
     244              :                                     SO_ERROR, (void*)&n, &m) == 0) {
     245            8 :                         if (n == 0) {
     246            4 :                             dlt_vlog(LOG_DEBUG, "%s: Already connect\n", __func__);
     247            4 :                             if(fcntl(client->sock, F_SETFL,
     248            4 :                                     fcntl(client->sock,F_GETFL,0) & ~O_NONBLOCK) < 0) {
     249            0 :                                 dlt_vlog(LOG_WARNING,
     250              :                                 "%s: Socket cannot be changed to BLOCK with err [%s]\n",
     251              :                                 __func__, strerror(errno));
     252            0 :                                 close(client->sock);
     253            0 :                                 continue;
     254              :                             }
     255              :                         }
     256              :                         else {
     257              :                             connect_errno = n;
     258            4 :                             close(client->sock);
     259            4 :                             continue;
     260              :                         }
     261              :                     }
     262              :                     else {
     263            0 :                         connect_errno = errno;
     264            0 :                         close(client->sock);
     265            0 :                         continue;
     266              :                     }
     267              :                 }
     268              :                 else {
     269              :                     connect_errno = errno;
     270            0 :                     close(client->sock);
     271            0 :                     continue;
     272              :                 }
     273              :             }
     274              : 
     275              :             break;
     276              :         }
     277              : 
     278            7 :         freeaddrinfo(servinfo);
     279              : 
     280            7 :         if (p == NULL) {
     281            3 :             dlt_vlog(LOG_ERR,
     282              :                      "%s: ERROR: failed to connect! %s\n",
     283              :                      __func__,
     284              :                      strerror(connect_errno));
     285            3 :             return DLT_RETURN_ERROR;
     286              :         }
     287              : 
     288            4 :         if (verbose) {
     289            1 :             dlt_vlog(LOG_INFO,
     290              :                      "%s: Connected to DLT daemon (%s)\n",
     291              :                      __func__,
     292              :                      client->servIP);
     293              :         }
     294              : 
     295              :         receiver_type = DLT_RECEIVE_SOCKET;
     296              : 
     297            6 :         break;
     298            0 :     case DLT_CLIENT_MODE_SERIAL:
     299              :         /* open serial connection */
     300            0 :         client->sock = open(client->serialDevice, O_RDWR);
     301              : 
     302            0 :         if (client->sock < 0) {
     303            0 :             dlt_vlog(LOG_ERR,
     304              :                      "%s: ERROR: Failed to open device %s\n",
     305              :                      __func__,
     306              :                      client->serialDevice);
     307            0 :             return DLT_RETURN_ERROR;
     308              :         }
     309              : 
     310            0 :         if (isatty(client->sock)) {
     311              :             #if !defined (__WIN32__)
     312              : 
     313            0 :             if (dlt_setup_serial(client->sock, client->baudrate) < DLT_RETURN_OK) {
     314            0 :                 dlt_vlog(LOG_ERR,
     315              :                          "%s: ERROR: Failed to configure serial device %s (%s) \n",
     316              :                          __func__,
     317              :                          client->serialDevice,
     318            0 :                          strerror(errno));
     319            0 :                 return DLT_RETURN_ERROR;
     320              :             }
     321              : 
     322              :             #else
     323              :             return DLT_RETURN_ERROR;
     324              :             #endif
     325              :         }
     326              :         else {
     327            0 :             if (verbose)
     328            0 :                 dlt_vlog(LOG_ERR,
     329              :                          "%s: ERROR: Device is not a serial device, device = %s (%s) \n",
     330              :                          __func__,
     331              :                          client->serialDevice,
     332            0 :                          strerror(errno));
     333              : 
     334            0 :             return DLT_RETURN_ERROR;
     335              :         }
     336              : 
     337            0 :         if (verbose)
     338            0 :             dlt_vlog(LOG_INFO,
     339              :                          "%s: Connected to %s\n",
     340              :                          __func__,
     341              :                          client->serialDevice);
     342              : 
     343              :         receiver_type = DLT_RECEIVE_FD;
     344              : 
     345              :         break;
     346            2 :     case DLT_CLIENT_MODE_UNIX:
     347              : 
     348            2 :         if ((client->sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
     349            0 :             dlt_vlog(LOG_ERR,
     350              :                      "%s: ERROR: (unix) socket error: %s\n",
     351              :                      __func__,
     352            0 :                      strerror(errno));
     353              : 
     354            0 :             return DLT_RETURN_ERROR;
     355              :         }
     356              : 
     357              :         memset(&addr, 0, sizeof(addr));
     358            2 :         addr.sun_family = AF_UNIX;
     359            2 :         strncpy(addr.sun_path, client->socketPath, sizeof(addr.sun_path) - 1);
     360              : 
     361            2 :         if (connect(client->sock,
     362              :                     (struct sockaddr *) &addr,
     363              :                     sizeof(addr)) == -1) {
     364            0 :             dlt_vlog(LOG_ERR,
     365              :                      "%s: ERROR: (unix) connect error: %s\n",
     366              :                      __func__,
     367            0 :                      strerror(errno));
     368              : 
     369            0 :             return DLT_RETURN_ERROR;
     370              :         }
     371              : 
     372            2 :         if (client->sock < 0) {
     373            0 :             dlt_vlog(LOG_ERR,
     374              :                      "%s: ERROR: Failed to open device %s\n",
     375              :                      __func__,
     376              :                      client->socketPath);
     377              : 
     378            0 :             return DLT_RETURN_ERROR;
     379              :         }
     380              : 
     381              :         receiver_type = DLT_RECEIVE_SOCKET;
     382              : 
     383              :         break;
     384            0 :     case DLT_CLIENT_MODE_UDP_MULTICAST:
     385              : 
     386            0 :         if ((client->sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
     387              :         {
     388            0 :             dlt_vlog(LOG_ERR,
     389              :                      "%s: ERROR: socket error: %s\n",
     390              :                      __func__,
     391            0 :                      strerror(errno));
     392              : 
     393            0 :             return DLT_RETURN_ERROR;
     394              :         }
     395              : 
     396              :         /* allow multiple sockets to use the same PORT number */
     397            0 :         if (setsockopt(client->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
     398              :         {
     399            0 :             dlt_vlog(LOG_ERR,
     400              :                      "%s: ERROR: Reusing address failed: %s\n",
     401              :                      __func__,
     402            0 :                      strerror(errno));
     403              : 
     404            0 :             return DLT_RETURN_ERROR;
     405              :         }
     406              : 
     407            0 :         memset(&client->receiver.addr, 0, sizeof(client->receiver.addr));
     408            0 :         client->receiver.addr.sin_family = AF_INET;
     409              :         client->receiver.addr.sin_addr.s_addr = htonl(INADDR_ANY);
     410            0 :         client->receiver.addr.sin_port = htons(client->port);
     411              : 
     412              :         /* bind to receive address */
     413            0 :         if (bind(client->sock, (struct sockaddr*) &client->receiver.addr, sizeof(client->receiver.addr)) < 0)
     414              :         {
     415            0 :             dlt_vlog(LOG_ERR,
     416              :                      "%s: ERROR: bind failed: %s\n",
     417              :                      __func__,
     418            0 :                      strerror(errno));
     419              : 
     420            0 :             return DLT_RETURN_ERROR;
     421              :         }
     422              : 
     423            0 :         mreq.imr_interface.s_addr = htonl(INADDR_ANY);
     424            0 :         if (client->hostip)
     425              :         {
     426            0 :             mreq.imr_interface.s_addr = inet_addr(client->hostip);
     427              :         }
     428            0 :         if (client->servIP == NULL)
     429              :         {
     430            0 :             dlt_vlog(LOG_ERR,
     431              :                      "%s: ERROR: server address not set\n",
     432              :                      __func__);
     433              : 
     434            0 :             return DLT_RETURN_ERROR;
     435              :         }
     436              : 
     437            0 :         char delimiter[] = ",";
     438            0 :         char* servIP = strtok(client->servIP, delimiter);
     439              : 
     440            0 :         while(servIP != NULL) {
     441            0 :             mreq.imr_multiaddr.s_addr = inet_addr(servIP);
     442            0 :             if (mreq.imr_multiaddr.s_addr == (in_addr_t)-1)
     443              :             {
     444            0 :                 dlt_vlog(LOG_ERR,
     445              :                          "%s: ERROR: server address not not valid %s\n",
     446              :                          __func__,
     447              :                          servIP);
     448              : 
     449            0 :                 return DLT_RETURN_ERROR;
     450              :             }
     451              : 
     452            0 :             if (setsockopt(client->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0)
     453              :             {
     454            0 :                 dlt_vlog(LOG_ERR,
     455              :                          "%s: ERROR: setsockopt add membership failed: %s\n",
     456              :                          __func__,
     457            0 :                          strerror(errno));
     458              : 
     459            0 :                 return DLT_RETURN_ERROR;
     460              :             }
     461            0 :             servIP = strtok(NULL, delimiter);
     462              :         }
     463              :         receiver_type = DLT_RECEIVE_UDP_SOCKET;
     464              : 
     465              :         break;
     466            0 :     default:
     467            0 :         dlt_vlog(LOG_ERR,
     468              :                  "%s: ERROR: Mode not supported: %d\n",
     469              :                  __func__,
     470              :                  client->mode);
     471              : 
     472            0 :         return DLT_RETURN_ERROR;
     473              :     }
     474              : 
     475            6 :     if (dlt_receiver_init(&(client->receiver), client->sock, receiver_type, DLT_RECEIVE_BUFSIZE) != DLT_RETURN_OK) {
     476            0 :         dlt_vlog(LOG_ERR, "%s: ERROR initializing receiver\n", __func__);
     477            0 :         return DLT_RETURN_ERROR;
     478              :     }
     479              : 
     480              :     return DLT_RETURN_OK;
     481              : }
     482              : 
     483            5 : DltReturnValue dlt_client_cleanup(DltClient *client, int verbose)
     484              : {
     485              :     int ret = DLT_RETURN_OK;
     486              : 
     487            5 :     if (verbose)
     488            0 :         dlt_vlog(LOG_INFO, "%s: Cleanup dlt client\n", __func__);
     489              : 
     490            5 :     if (client == NULL)
     491              :         return DLT_RETURN_WRONG_PARAMETER;
     492              : 
     493            5 :     if (client->sock != -1)
     494            5 :         close(client->sock);
     495              : 
     496            5 :     if (dlt_receiver_free(&(client->receiver)) != DLT_RETURN_OK) {
     497            0 :         dlt_vlog(LOG_WARNING, "%s: Failed to free receiver\n", __func__);
     498              :                 ret = DLT_RETURN_ERROR;
     499              :     }
     500              : 
     501            5 :     if (client->serialDevice) {
     502            0 :         free(client->serialDevice);
     503            0 :         client->serialDevice = NULL;
     504              :     }
     505              : 
     506            5 :     if (client->servIP) {
     507            3 :         free(client->servIP);
     508            3 :         client->servIP = NULL;
     509              :     }
     510              : 
     511            5 :     if (client->socketPath) {
     512            2 :         free(client->socketPath);
     513            2 :         client->socketPath = NULL;
     514              :     }
     515              : 
     516            5 :     if (client->hostip) {
     517            0 :         free(client->hostip);
     518            0 :         client->hostip = NULL;
     519              :     }
     520              :     return ret;
     521              : }
     522              : 
     523            3 : DltReturnValue dlt_client_main_loop(DltClient *client, void *data, int verbose)
     524              : {
     525              :     DltMessage msg;
     526              :     int ret;
     527              : 
     528            3 :     if (client == 0)
     529              :         return DLT_RETURN_ERROR;
     530              : 
     531            3 :     if (dlt_message_init(&msg, verbose) == DLT_RETURN_ERROR)
     532              :         return DLT_RETURN_ERROR;
     533              : 
     534              :     bool fetch_next_message = true;
     535          415 :     while (fetch_next_message) {
     536              :         /* wait for data from socket or serial connection */
     537          415 :         ret = dlt_receiver_receive(&(client->receiver));
     538              : 
     539          415 :         if (ret <= 0) {
     540              :             /* No more data to be received */
     541            3 :             if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR)
     542              :                 return DLT_RETURN_ERROR;
     543              : 
     544              :             return DLT_RETURN_TRUE;
     545              :         }
     546              : 
     547          620 :         while (dlt_message_read(&msg, (unsigned char *)(client->receiver.buf),
     548          620 :                                 (unsigned int)client->receiver.bytesRcvd,
     549              :                                 client->resync_serial_header,
     550          620 :                                 verbose) == DLT_MESSAGE_ERROR_OK)
     551              :         {
     552              :             /* Call callback function */
     553          208 :             if (message_callback_function)
     554          208 :                 (*message_callback_function)(&msg, data);
     555              : 
     556          208 :             int total_size = (int)((size_t)msg.headersize
     557          208 :                             + (size_t)msg.datasize
     558          208 :                             - sizeof(DltStorageHeader));
     559              : 
     560          208 :             if (msg.found_serialheader) {
     561              :                 total_size += (int)sizeof(dltSerialHeader);
     562              :             }
     563              : 
     564          208 :             if (dlt_receiver_remove(&(client->receiver),
     565              :                                     total_size) == DLT_RETURN_ERROR) {
     566              :                 /* Return value ignored */
     567            0 :                 dlt_message_free(&msg, verbose);
     568            0 :                 return DLT_RETURN_ERROR;
     569              :             }
     570              :         }
     571              : 
     572          412 :         if (dlt_receiver_move_to_begin(&(client->receiver)) == DLT_RETURN_ERROR) {
     573              :             /* Return value ignored */
     574            0 :             dlt_message_free(&msg, verbose);
     575            0 :             return DLT_RETURN_ERROR;
     576              :         }
     577          412 :         if (fetch_next_message_callback_function)
     578            0 :           fetch_next_message = (*fetch_next_message_callback_function)(data);
     579              :     }
     580              : 
     581            0 :     if (dlt_message_free(&msg, verbose) == DLT_RETURN_ERROR)
     582              :         return DLT_RETURN_ERROR;
     583              : 
     584              :     return DLT_RETURN_OK;
     585              : }
     586              : 
     587            2 : DltReturnValue dlt_client_send_message_to_socket(DltClient *client, DltMessage *msg)
     588              : {
     589              :     int ret = 0;
     590              : 
     591            2 :     if ((client == NULL) || (client->sock < 0)
     592            2 :         || (msg == NULL) || (msg->databuffer == NULL))
     593              :     {
     594            0 :         dlt_log(LOG_ERR, "Invalid parameters\n");
     595            0 :         return DLT_RETURN_ERROR;
     596              :     }
     597              : 
     598            2 :     if (client->send_serial_header)
     599              :     {
     600            0 :         ret = (int)send(client->sock, (const char *)dltSerialHeader,
     601              :                    sizeof(dltSerialHeader), 0);
     602            0 :         if (ret < 0)
     603              :         {
     604            0 :             dlt_vlog(LOG_ERR, "Sending serial header failed: %s\n",
     605            0 :                         strerror(errno));
     606            0 :             return DLT_RETURN_ERROR;
     607              :         }
     608              :     }
     609              : 
     610            4 :     ret = (int)send(client->sock,
     611              :                (const char *)(msg->headerbuffer + sizeof(DltStorageHeader)),
     612            2 :                (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader)), 0);
     613            2 :     if (ret < 0)
     614              :     {
     615            0 :         dlt_vlog(LOG_ERR, "Sending message header failed: %s\n", strerror(errno));
     616            0 :         return DLT_RETURN_ERROR;
     617              :     }
     618              : 
     619            2 :     ret = (int)send(client->sock, (const char *)msg->databuffer, (size_t)msg->datasize, 0);
     620            2 :     if ( ret < 0)
     621              :     {
     622            0 :         dlt_vlog(LOG_ERR, "Sending message failed: %s\n", strerror(errno));
     623            0 :         return DLT_RETURN_ERROR;
     624              :     }
     625              : 
     626              :     return DLT_RETURN_OK;
     627              : }
     628              : 
     629           10 : DltReturnValue dlt_client_send_ctrl_msg(DltClient *client, char *apid, char *ctid, uint8_t *payload, uint32_t size)
     630              : {
     631              :     DltMessage msg;
     632              :     int ret;
     633              : 
     634              :     int32_t len;
     635              :     uint32_t id_tmp;
     636              :     uint32_t id;
     637              : 
     638           10 :     if ((client == 0) || (client->sock < 0) || (apid == 0) || (ctid == 0))
     639              :         return DLT_RETURN_ERROR;
     640              : 
     641              :     /* initialise new message */
     642           10 :     if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
     643              :         return DLT_RETURN_ERROR;
     644              : 
     645              :     /* prepare payload of data */
     646           10 :     msg.datasize = (int32_t)size;
     647              : 
     648           10 :     if (msg.databuffer && (msg.databuffersize < msg.datasize)) {
     649            0 :         free(msg.databuffer);
     650            0 :         msg.databuffer = 0;
     651              :     }
     652              : 
     653           10 :     if (msg.databuffer == 0) {
     654           10 :         msg.databuffer = (uint8_t *)malloc((size_t)msg.datasize);
     655           10 :         msg.databuffersize = msg.datasize;
     656              :     }
     657              : 
     658           10 :     if (msg.databuffer == 0) {
     659            0 :         dlt_message_free(&msg, 0);
     660            0 :         return DLT_RETURN_ERROR;
     661              :     }
     662              : 
     663              :     /* copy data */
     664           10 :     memcpy(msg.databuffer, payload, size);
     665              : 
     666              :     /* prepare storage header */
     667           10 :     msg.storageheader = (DltStorageHeader *)msg.headerbuffer;
     668              : 
     669           10 :     if (dlt_set_storageheader(msg.storageheader, "") == DLT_RETURN_ERROR) {
     670            0 :         dlt_message_free(&msg, 0);
     671            0 :         return DLT_RETURN_ERROR;
     672              :     }
     673              : 
     674              :     /* prepare standard header */
     675           10 :     msg.standardheader = (DltStandardHeader *)(msg.headerbuffer + sizeof(DltStorageHeader));
     676           10 :     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1;
     677              : 
     678              :     #if (BYTE_ORDER == BIG_ENDIAN)
     679              :     msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
     680              :     #endif
     681              : 
     682           10 :     msg.standardheader->mcnt = 0;
     683              : 
     684              :     /* Set header extra parameters */
     685           10 :     dlt_set_id(msg.headerextra.ecu, client->ecuid);
     686              :     /*msg.headerextra.seid = 0; */
     687           10 :     msg.headerextra.tmsp = dlt_uptime();
     688              : 
     689              :     /* Copy header extra parameters to headerbuffer */
     690           10 :     if (dlt_message_set_extraparameters(&msg, 0) == DLT_RETURN_ERROR) {
     691            0 :         dlt_message_free(&msg, 0);
     692            0 :         return DLT_RETURN_ERROR;
     693              :     }
     694              : 
     695              :     /* prepare extended header */
     696           10 :     msg.extendedheader = (DltExtendedHeader *)(msg.headerbuffer +
     697              :                                                sizeof(DltStorageHeader) +
     698           10 :                                                sizeof(DltStandardHeader) +
     699           10 :                                                DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
     700              : 
     701           10 :     msg.extendedheader->msin = DLT_MSIN_CONTROL_REQUEST;
     702              : 
     703           10 :     msg.extendedheader->noar = 1; /* number of arguments */
     704              : 
     705           19 :     dlt_set_id(msg.extendedheader->apid, (apid[0] == '\0') ? DLT_CLIENT_DUMMY_APP_ID : apid);
     706           19 :     dlt_set_id(msg.extendedheader->ctid, (ctid[0] == '\0') ? DLT_CLIENT_DUMMY_CON_ID : ctid);
     707              : 
     708              :     /* prepare length information */
     709           10 :     msg.headersize = (int32_t)(sizeof(DltStorageHeader) +
     710              :         sizeof(DltStandardHeader) +
     711           10 :         sizeof(DltExtendedHeader) +
     712           10 :         DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
     713              : 
     714           10 :     len = (int32_t)((size_t)msg.headersize - sizeof(DltStorageHeader) + (size_t)msg.datasize);
     715              : 
     716              : 
     717           10 :     if (len > UINT16_MAX) {
     718            0 :         dlt_vlog(LOG_ERR,
     719              :                  "%s: Critical: Huge injection message discarded!\n",
     720              :                  __func__);
     721              : 
     722            0 :                 dlt_message_free(&msg, 0);
     723              : 
     724            0 :         return DLT_RETURN_ERROR;
     725              :     }
     726              : 
     727           10 :     msg.standardheader->len = (uint16_t)DLT_HTOBE_16((uint16_t)len);
     728              : 
     729              :     /* Send data (without storage header) */
     730           10 :     if ((client->mode == DLT_CLIENT_MODE_TCP) || (client->mode == DLT_CLIENT_MODE_SERIAL)) {
     731              :         /* via FileDescriptor */
     732           10 :         if (client->send_serial_header)
     733              :         {
     734            0 :             ret = write(client->sock, dltSerialHeader, sizeof(dltSerialHeader));
     735            0 :             if (ret < 0)
     736              :             {
     737            0 :                 dlt_log(LOG_ERR, "Sending message failed\n");
     738            0 :                 dlt_message_free(&msg, 0);
     739            0 :                 return DLT_RETURN_ERROR;
     740              :             }
     741              :         }
     742              : 
     743           10 :         ret = (int) write(client->sock, msg.headerbuffer + sizeof(DltStorageHeader), (size_t)((int32_t)msg.headersize - (int32_t)sizeof(DltStorageHeader)));
     744              : 
     745           10 :         if (0 > ret) {
     746            0 :             dlt_vlog(LOG_ERR, "%s: Sending message failed\n", __func__);
     747            0 :             dlt_message_free(&msg, 0);
     748            0 :             return DLT_RETURN_ERROR;
     749              :         }
     750              : 
     751           10 :         ret = (int) write(client->sock, msg.databuffer, (size_t)msg.datasize);
     752              : 
     753           10 :         if (0 > ret) {
     754            0 :             dlt_vlog(LOG_ERR, "%s: Sending message failed\n", __func__);
     755            0 :             dlt_message_free(&msg, 0);
     756            0 :             return DLT_RETURN_ERROR;
     757              :         }
     758              : 
     759           10 :         id_tmp = *((uint32_t *)(msg.databuffer));
     760           10 :         id = DLT_ENDIAN_GET_32(msg.standardheader->htyp, id_tmp);
     761              : 
     762           10 :         dlt_vlog(LOG_INFO,
     763              :                  "%s: Control message forwarded : %s\n",
     764              :                  __func__,
     765              :                  dlt_get_service_name(id));
     766              :     }
     767              :     else {
     768              :         /* via Socket */
     769            0 :         if (dlt_client_send_message_to_socket(client, &msg) == DLT_RETURN_ERROR)
     770              :         {
     771            0 :             dlt_log(LOG_ERR, "Sending message to socket failed\n");
     772            0 :             dlt_message_free(&msg, 0);
     773            0 :             return DLT_RETURN_ERROR;
     774              :         }
     775              :     }
     776              : 
     777              :     /* free message */
     778           10 :     if (dlt_message_free(&msg, 0) == DLT_RETURN_ERROR)
     779              :         return DLT_RETURN_ERROR;
     780              : 
     781              :     return DLT_RETURN_OK;
     782              : }
     783              : 
     784            0 : DltReturnValue dlt_client_send_inject_msg(DltClient *client,
     785              :                                           char *apid,
     786              :                                           char *ctid,
     787              :                                           uint32_t serviceID,
     788              :                                           uint8_t *buffer,
     789              :                                           uint32_t size)
     790              : {
     791              :     uint8_t *payload;
     792              :     int offset;
     793              : 
     794            0 :     payload = (uint8_t *)malloc(sizeof(uint32_t) + sizeof(uint32_t) + size);
     795              : 
     796            0 :     if (payload == 0)
     797              :         return DLT_RETURN_ERROR;
     798              : 
     799              :     offset = 0;
     800              :     memcpy(payload, &serviceID, sizeof(serviceID));
     801              :     offset += (int) sizeof(uint32_t);
     802            0 :     memcpy(payload + offset, &size, sizeof(size));
     803              :     offset += (int) sizeof(uint32_t);
     804            0 :     memcpy(payload + offset, buffer, size);
     805              : 
     806              :     /* free message */
     807            0 :     if (dlt_client_send_ctrl_msg(client, apid, ctid, payload,
     808              :                                  (uint32_t) (sizeof(uint32_t) + sizeof(uint32_t) + size)) == DLT_RETURN_ERROR) {
     809            0 :         free(payload);
     810            0 :         return DLT_RETURN_ERROR;
     811              :     }
     812              : 
     813            0 :     free(payload);
     814              : 
     815            0 :     return DLT_RETURN_OK;
     816              : 
     817              : }
     818              : 
     819            1 : DltReturnValue dlt_client_send_log_level(DltClient *client, char *apid, char *ctid, uint8_t logLevel)
     820              : {
     821              :     DltServiceSetLogLevel *req;
     822              :     int ret = DLT_RETURN_ERROR;
     823              : 
     824            1 :     if (client == NULL)
     825              :         return ret;
     826              : 
     827            1 :     req = calloc(1, sizeof(DltServiceSetLogLevel));
     828              : 
     829            1 :     if (req == NULL)
     830              :         return ret;
     831              : 
     832            1 :     req->service_id = DLT_SERVICE_ID_SET_LOG_LEVEL;
     833            1 :     dlt_set_id(req->apid, apid);
     834            1 :     dlt_set_id(req->ctid, ctid);
     835            1 :     req->log_level = logLevel;
     836            1 :     dlt_set_id(req->com, "remo");
     837              : 
     838              :     /* free message */
     839            1 :     ret = dlt_client_send_ctrl_msg(client,
     840              :                                    "APP",
     841              :                                    "CON",
     842              :                                    (uint8_t *)req,
     843              :                                    sizeof(DltServiceSetLogLevel));
     844              : 
     845              : 
     846            1 :     free(req);
     847              : 
     848            1 :     return ret;
     849              : }
     850              : 
     851            4 : DltReturnValue dlt_client_get_log_info(DltClient *client)
     852              : {
     853              :     DltServiceGetLogInfoRequest *req;
     854              :     int ret = DLT_RETURN_ERROR;
     855              : 
     856            4 :     if (client == NULL)
     857              :         return ret;
     858              : 
     859            4 :     req = (DltServiceGetLogInfoRequest *)malloc(sizeof(DltServiceGetLogInfoRequest));
     860              : 
     861            4 :     if (req == NULL)
     862              :         return ret;
     863              : 
     864            4 :     req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
     865            4 :     req->options = 7;
     866            4 :     dlt_set_id(req->apid, "");
     867            4 :     dlt_set_id(req->ctid, "");
     868            4 :     dlt_set_id(req->com, "remo");
     869              : 
     870              :     /* send control message to daemon*/
     871            4 :     ret = dlt_client_send_ctrl_msg(client,
     872              :                                    "",
     873              :                                    "",
     874              :                                    (uint8_t *)req,
     875              :                                    sizeof(DltServiceGetLogInfoRequest));
     876              : 
     877            4 :     free(req);
     878              : 
     879            4 :     return ret;
     880              : }
     881              : 
     882            1 : DltReturnValue dlt_client_get_default_log_level(DltClient *client)
     883              : {
     884              :     DltServiceGetDefaultLogLevelRequest *req;
     885              :     int ret = DLT_RETURN_ERROR;
     886              : 
     887            1 :     if (client == NULL)
     888              :         return ret;
     889              : 
     890              :     req = (DltServiceGetDefaultLogLevelRequest *)
     891            1 :         malloc(sizeof(DltServiceGetDefaultLogLevelRequest));
     892              : 
     893            1 :     if (req == NULL)
     894              :         return ret;
     895              : 
     896            1 :     req->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
     897              : 
     898              :     /* send control message to daemon*/
     899            1 :     ret = dlt_client_send_ctrl_msg(client,
     900              :                                    "",
     901              :                                    "",
     902              :                                    (uint8_t *)req,
     903              :                                    sizeof(DltServiceGetDefaultLogLevelRequest));
     904              : 
     905            1 :     free(req);
     906              : 
     907            1 :     return ret;
     908              : }
     909              : 
     910            4 : DltReturnValue dlt_client_get_software_version(DltClient *client)
     911              : {
     912              :     DltServiceGetSoftwareVersion *req;
     913              :     int ret = DLT_RETURN_ERROR;
     914              : 
     915            4 :     if (client == NULL)
     916              :         return ret;
     917              : 
     918            4 :     req = (DltServiceGetSoftwareVersion *)malloc(sizeof(DltServiceGetSoftwareVersion));
     919              : 
     920            4 :     req->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
     921              : 
     922              :     /* send control message to daemon*/
     923            4 :     ret = dlt_client_send_ctrl_msg(client,
     924              :                                    "",
     925              :                                    "",
     926              :                                    (uint8_t *)req,
     927              :                                    sizeof(DltServiceGetSoftwareVersion));
     928              : 
     929            4 :     free(req);
     930              : 
     931            4 :     return ret;
     932              : }
     933              : 
     934            0 : DltReturnValue dlt_client_send_trace_status(DltClient *client, char *apid, char *ctid, uint8_t traceStatus)
     935              : {
     936              :     DltServiceSetLogLevel *req;
     937              : 
     938            0 :     req = calloc(1,sizeof(DltServiceSetLogLevel));
     939              : 
     940            0 :     if (req == 0)
     941              :         return DLT_RETURN_ERROR;
     942              : 
     943            0 :     req->service_id = DLT_SERVICE_ID_SET_TRACE_STATUS;
     944            0 :     dlt_set_id(req->apid, apid);
     945            0 :     dlt_set_id(req->ctid, ctid);
     946            0 :     req->log_level = traceStatus;
     947            0 :     dlt_set_id(req->com, "remo");
     948              : 
     949              :     /* free message */
     950            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
     951              :                                  sizeof(DltServiceSetLogLevel)) == DLT_RETURN_ERROR) {
     952            0 :         free(req);
     953            0 :         return DLT_RETURN_ERROR;
     954              :     }
     955              : 
     956            0 :     free(req);
     957              : 
     958            0 :     return DLT_RETURN_OK;
     959              : }
     960              : 
     961            0 : DltReturnValue dlt_client_send_default_log_level(DltClient *client, uint8_t defaultLogLevel)
     962              : {
     963              :     DltServiceSetDefaultLogLevel *req;
     964              : 
     965            0 :     req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
     966              : 
     967            0 :     if (req == 0)
     968              :         return DLT_RETURN_ERROR;
     969              : 
     970            0 :     req->service_id = DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
     971            0 :     req->log_level = defaultLogLevel;
     972            0 :     dlt_set_id(req->com, "remo");
     973              : 
     974              :     /* free message */
     975            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
     976              :                                  sizeof(DltServiceSetDefaultLogLevel)) == DLT_RETURN_ERROR) {
     977            0 :         free(req);
     978            0 :         return DLT_RETURN_ERROR;
     979              :     }
     980              : 
     981            0 :     free(req);
     982              : 
     983            0 :     return DLT_RETURN_OK;
     984              : }
     985              : 
     986            0 : DltReturnValue dlt_client_send_all_log_level(DltClient *client, uint8_t LogLevel)
     987              : {
     988              :     DltServiceSetDefaultLogLevel *req;
     989              : 
     990            0 :     req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
     991              : 
     992            0 :     if (req == 0)
     993              :         return DLT_RETURN_ERROR;
     994              : 
     995            0 :     req->service_id = DLT_SERVICE_ID_SET_ALL_LOG_LEVEL;
     996            0 :     req->log_level = LogLevel;
     997            0 :     dlt_set_id(req->com, "remo");
     998              : 
     999              :     /* free message */
    1000            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
    1001              :                                  sizeof(DltServiceSetDefaultLogLevel)) == -1) {
    1002            0 :         free(req);
    1003            0 :         return DLT_RETURN_ERROR;
    1004              :     }
    1005              : 
    1006            0 :     free(req);
    1007              : 
    1008            0 :     return DLT_RETURN_OK;
    1009              : }
    1010              : 
    1011            0 : DltReturnValue dlt_client_send_default_trace_status(DltClient *client, uint8_t defaultTraceStatus)
    1012              : {
    1013              :     DltServiceSetDefaultLogLevel *req;
    1014              : 
    1015            0 :     req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
    1016              : 
    1017            0 :     if (req == 0)
    1018              :         return DLT_RETURN_ERROR;
    1019              : 
    1020            0 :     req->service_id = DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
    1021            0 :     req->log_level = defaultTraceStatus;
    1022            0 :     dlt_set_id(req->com, "remo");
    1023              : 
    1024              :     /* free message */
    1025            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
    1026              :                                  sizeof(DltServiceSetDefaultLogLevel)) == DLT_RETURN_ERROR) {
    1027            0 :         free(req);
    1028            0 :         return DLT_RETURN_ERROR;
    1029              :     }
    1030              : 
    1031            0 :     free(req);
    1032              : 
    1033            0 :     return DLT_RETURN_OK;
    1034              : }
    1035              : 
    1036            0 : DltReturnValue dlt_client_send_all_trace_status(DltClient *client, uint8_t traceStatus)
    1037              : {
    1038              :     DltServiceSetDefaultLogLevel *req;
    1039              : 
    1040            0 :     if (client == NULL) {
    1041            0 :         dlt_vlog(LOG_ERR, "%s: Invalid parameters\n", __func__);
    1042            0 :         return DLT_RETURN_ERROR;
    1043              :     }
    1044              : 
    1045            0 :     req = calloc(1, sizeof(DltServiceSetDefaultLogLevel));
    1046              : 
    1047            0 :     if (req == 0) {
    1048            0 :         dlt_vlog(LOG_ERR, "%s: Could not allocate memory %zu\n", __func__, sizeof(DltServiceSetDefaultLogLevel));
    1049            0 :         return DLT_RETURN_ERROR;
    1050              :     }
    1051              : 
    1052            0 :     req->service_id = DLT_SERVICE_ID_SET_ALL_TRACE_STATUS;
    1053            0 :     req->log_level = traceStatus;
    1054            0 :     dlt_set_id(req->com, "remo");
    1055              : 
    1056              :     /* free message */
    1057            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
    1058              :                                  sizeof(DltServiceSetDefaultLogLevel)) == -1) {
    1059            0 :         free(req);;
    1060            0 :         return DLT_RETURN_ERROR;
    1061              :     }
    1062              : 
    1063            0 :     free(req);
    1064              : 
    1065            0 :     return DLT_RETURN_OK;
    1066              : }
    1067              : 
    1068            0 : DltReturnValue dlt_client_send_timing_pakets(DltClient *client, uint8_t timingPakets)
    1069              : {
    1070              :     DltServiceSetVerboseMode *req;
    1071              : 
    1072            0 :     req = calloc(1, sizeof(DltServiceSetVerboseMode));
    1073              : 
    1074            0 :     if (req == 0)
    1075              :         return DLT_RETURN_ERROR;
    1076              : 
    1077            0 :     req->service_id = DLT_SERVICE_ID_SET_TIMING_PACKETS;
    1078            0 :     req->new_status = timingPakets;
    1079              : 
    1080              :     /* free message */
    1081            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t*) req,
    1082              :                                  sizeof(DltServiceSetVerboseMode)) == DLT_RETURN_ERROR) {
    1083            0 :         free(req);
    1084            0 :         return DLT_RETURN_ERROR;
    1085              :     }
    1086              : 
    1087            0 :     free(req);
    1088              : 
    1089            0 :     return DLT_RETURN_OK;
    1090              : }
    1091              : 
    1092            0 : DltReturnValue dlt_client_send_store_config(DltClient *client)
    1093              : {
    1094              :     uint32_t service_id;
    1095              : 
    1096            0 :     service_id = DLT_SERVICE_ID_STORE_CONFIG;
    1097              : 
    1098              :     /* free message */
    1099            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)&service_id, sizeof(uint32_t)) == DLT_RETURN_ERROR)
    1100            0 :         return DLT_RETURN_ERROR;
    1101              : 
    1102              :     return DLT_RETURN_OK;
    1103              : }
    1104              : 
    1105            0 : DltReturnValue dlt_client_send_reset_to_factory_default(DltClient *client)
    1106              : {
    1107              :     uint32_t service_id;
    1108              : 
    1109            0 :     service_id = DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT;
    1110              : 
    1111              :     /* free message */
    1112            0 :     if (dlt_client_send_ctrl_msg(client, "APP", "CON", (uint8_t *)&service_id, sizeof(uint32_t)) == DLT_RETURN_ERROR)
    1113            0 :         return DLT_RETURN_ERROR;
    1114              : 
    1115              :     return DLT_RETURN_OK;
    1116              : }
    1117              : 
    1118            0 : DltReturnValue dlt_client_setbaudrate(DltClient *client, int baudrate)
    1119              : {
    1120            0 :     if (client == 0)
    1121              :         return DLT_RETURN_ERROR;
    1122              : 
    1123            0 :     client->baudrate = dlt_convert_serial_speed(baudrate);
    1124              : 
    1125            0 :     return DLT_RETURN_OK;
    1126              : }
    1127              : 
    1128            0 : DltReturnValue dlt_client_set_mode(DltClient *client, DltClientMode mode)
    1129              : {
    1130            0 :     if (client == 0)
    1131              :         return DLT_RETURN_ERROR;
    1132              : 
    1133            0 :     client->mode = mode;
    1134            0 :     return DLT_RETURN_OK;
    1135              : 
    1136              : }
    1137              : 
    1138            6 : int dlt_client_set_server_ip(DltClient *client, char *ipaddr)
    1139              : {
    1140            6 :     client->servIP = strdup(ipaddr);
    1141              : 
    1142            6 :     if (client->servIP == NULL) {
    1143            0 :         dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate server IP\n", __func__);
    1144            0 :         return DLT_RETURN_ERROR;
    1145              :     }
    1146              : 
    1147              :     return DLT_RETURN_OK;
    1148              : }
    1149              : 
    1150            0 : int dlt_client_set_host_if_address(DltClient *client, char *hostip)
    1151              : {
    1152            0 :     client->hostip = strdup(hostip);
    1153              : 
    1154            0 :     if (client->hostip == NULL) {
    1155            0 :         dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate UDP interface address\n", __func__);
    1156            0 :         return DLT_RETURN_ERROR;
    1157              :     }
    1158              : 
    1159              :     return DLT_RETURN_OK;
    1160              : }
    1161              : 
    1162            0 : int dlt_client_set_serial_device(DltClient *client, char *serial_device)
    1163              : {
    1164            0 :     client->serialDevice = strdup(serial_device);
    1165              : 
    1166            0 :     if (client->serialDevice == NULL) {
    1167            0 :         dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate serial device\n", __func__);
    1168            0 :         return DLT_RETURN_ERROR;
    1169              :     }
    1170              : 
    1171              :     return DLT_RETURN_OK;
    1172              : }
    1173              : 
    1174            0 : int dlt_client_set_socket_path(DltClient *client, char *socket_path)
    1175              : {
    1176            0 :     client->socketPath = strdup(socket_path);
    1177              : 
    1178            0 :     if (client->socketPath == NULL) {
    1179            0 :         dlt_vlog(LOG_ERR, "%s: ERROR: failed to duplicate socket path\n", __func__);
    1180            0 :         return DLT_RETURN_ERROR;
    1181              :     }
    1182              : 
    1183              :     return DLT_RETURN_OK;
    1184              : }
    1185              : /**
    1186              :  * free allocation when calloc failed
    1187              :  *
    1188              :  * @param resp          DltServiceGetLogInfoResponse
    1189              :  * @param count_app_ids number of app_ids which needs to be freed
    1190              :  */
    1191            0 : DLT_STATIC void dlt_client_free_calloc_failed_get_log_info(DltServiceGetLogInfoResponse *resp,
    1192              :                                                            int count_app_ids)
    1193              : {
    1194              :     AppIDsType *app = NULL;
    1195              :     ContextIDsInfoType *con = NULL;
    1196              :     int i = 0;
    1197              :     int j = 0;
    1198              : 
    1199            0 :     for (i = 0; i < count_app_ids; i++) {
    1200            0 :         app = &(resp->log_info_type.app_ids[i]);
    1201              : 
    1202            0 :         for (j = 0; j < app->count_context_ids; j++) {
    1203            0 :             con = &(app->context_id_info[j]);
    1204              : 
    1205            0 :             free(con->context_description);
    1206            0 :             con->context_description = NULL;
    1207              :         }
    1208              : 
    1209            0 :         free(app->app_description);
    1210            0 :         app->app_description = NULL;
    1211              : 
    1212            0 :         free(app->context_id_info);
    1213            0 :         app->context_id_info = NULL;
    1214              :     }
    1215              : 
    1216            0 :     free(resp->log_info_type.app_ids);
    1217            0 :     resp->log_info_type.app_ids = NULL;
    1218            0 :     resp->log_info_type.count_app_ids = 0;
    1219              : 
    1220            0 :     return;
    1221              : }
    1222              : 
    1223            2 : DltReturnValue dlt_client_parse_get_log_info_resp_text(DltServiceGetLogInfoResponse *resp,
    1224              :                                                        char *resp_text)
    1225              : {
    1226              :     AppIDsType *app = NULL;
    1227              :     ContextIDsInfoType *con = NULL;
    1228              :     int i = 0;
    1229              :     int j = 0;
    1230              :     char *rp = NULL;
    1231            2 :     int rp_count = 0;
    1232              : 
    1233            2 :     if ((resp == NULL) || (resp_text == NULL))
    1234              :         return DLT_RETURN_WRONG_PARAMETER;
    1235              : 
    1236              :     /* ------------------------------------------------------
    1237              :     *  get_log_info data structure(all data is ascii)
    1238              :     *
    1239              :     *  get_log_info, aa, bb bb cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. ..
    1240              :     *                ~~  ~~~~~ ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~
    1241              :     *                          cc cc cc cc dd dd ee ee ee ee ff gg hh hh ii ii ii .. ..
    1242              :     *                    jj jj kk kk kk .. ..
    1243              :     *                          ~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~
    1244              :     *  aa         : get mode (fix value at 0x07)
    1245              :     *  bb bb      : list num of apid (little endian)
    1246              :     *  cc cc cc cc: apid
    1247              :     *  dd dd      : list num of ctid (little endian)
    1248              :     *  ee ee ee ee: ctid
    1249              :     *  ff         : log level
    1250              :     *  gg         : trace status
    1251              :     *  hh hh      : description length of ctid
    1252              :     *  ii ii ..   : description text of ctid
    1253              :     *  jj jj      : description length of apid
    1254              :     *  kk kk ..   : description text of apid
    1255              :     *  ------------------------------------------------------ */
    1256              : 
    1257            2 :     rp = resp_text + DLT_GET_LOG_INFO_HEADER;
    1258              :     rp_count = 0;
    1259              : 
    1260              :     /* check if status is acceptable */
    1261            2 :     if ((resp->status < GET_LOG_INFO_STATUS_MIN) ||
    1262              :         (resp->status > GET_LOG_INFO_STATUS_MAX)) {
    1263            0 :         if (resp->status == GET_LOG_INFO_STATUS_NO_MATCHING_CTX)
    1264            0 :             dlt_vlog(LOG_WARNING,
    1265              :                      "%s: The status(%d) is invalid: NO matching Context IDs\n",
    1266              :                      __func__,
    1267              :                      resp->status);
    1268            0 :         else if (resp->status == GET_LOG_INFO_STATUS_RESP_DATA_OVERFLOW)
    1269            0 :             dlt_vlog(LOG_WARNING,
    1270              :                      "%s: The status(%d) is invalid: Response data over flow\n",
    1271              :                      __func__,
    1272              :                      resp->status);
    1273              :         else
    1274            0 :             dlt_vlog(LOG_WARNING,
    1275              :                      "%s: The status(%d) is invalid\n",
    1276              :                      __func__,
    1277              :                      resp->status);
    1278              : 
    1279            0 :         return DLT_RETURN_ERROR;
    1280              :     }
    1281              : 
    1282              :     /* count_app_ids */
    1283            2 :     resp->log_info_type.count_app_ids = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
    1284              :                                                                               &rp_count);
    1285              : 
    1286            2 :     resp->log_info_type.app_ids = (AppIDsType *)calloc
    1287              :             (resp->log_info_type.count_app_ids, sizeof(AppIDsType));
    1288              : 
    1289            2 :     if (resp->log_info_type.app_ids == NULL) {
    1290            0 :         dlt_vlog(LOG_ERR, "%s: calloc failed for app_ids\n", __func__);
    1291            0 :         dlt_client_free_calloc_failed_get_log_info(resp, 0);
    1292            0 :         return DLT_RETURN_ERROR;
    1293              :     }
    1294              : 
    1295            5 :     for (i = 0; i < resp->log_info_type.count_app_ids; i++) {
    1296            3 :         app = &(resp->log_info_type.app_ids[i]);
    1297              :         /* get app id */
    1298            3 :         dlt_getloginfo_conv_ascii_to_id(rp, &rp_count, app->app_id, DLT_ID_SIZE);
    1299              : 
    1300              :         /* count_con_ids */
    1301            3 :         app->count_context_ids = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
    1302              :                                                                        &rp_count);
    1303              : 
    1304            3 :         app->context_id_info = (ContextIDsInfoType *)calloc
    1305              :                 (app->count_context_ids, sizeof(ContextIDsInfoType));
    1306              : 
    1307            3 :         if (app->context_id_info == NULL) {
    1308            0 :             dlt_vlog(LOG_ERR,
    1309              :                      "%s: calloc failed for context_id_info\n", __func__);
    1310            0 :             dlt_client_free_calloc_failed_get_log_info(resp, i);
    1311            0 :             return DLT_RETURN_ERROR;
    1312              :         }
    1313              : 
    1314            9 :         for (j = 0; j < app->count_context_ids; j++) {
    1315            6 :             con = &(app->context_id_info[j]);
    1316              :             /* get con id */
    1317            6 :             dlt_getloginfo_conv_ascii_to_id(rp,
    1318              :                                             &rp_count,
    1319            6 :                                             con->context_id,
    1320              :                                             DLT_ID_SIZE);
    1321              : 
    1322              :             /* log_level */
    1323            6 :             if ((resp->status == 4) || (resp->status == 6) || (resp->status == 7))
    1324            6 :                 con->log_level = dlt_getloginfo_conv_ascii_to_int16_t(rp,
    1325              :                                                                       &rp_count);
    1326              : 
    1327              :             /* trace status */
    1328            6 :             if ((resp->status == 5) || (resp->status == 6) || (resp->status == 7))
    1329            6 :                 con->trace_status = dlt_getloginfo_conv_ascii_to_int16_t(rp,
    1330              :                                                                          &rp_count);
    1331              : 
    1332              :             /* context desc */
    1333            6 :             if (resp->status == 7) {
    1334            6 :                 con->len_context_description = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
    1335              :                                                                                      &rp_count);
    1336            6 :                 con->context_description = (char *)calloc
    1337            6 :                         ((size_t) (con->len_context_description + 1), sizeof(char));
    1338              : 
    1339            6 :                 if (con->context_description == NULL) {
    1340            0 :                     dlt_vlog(LOG_ERR, "%s: calloc failed for context description\n", __func__);
    1341            0 :                     dlt_client_free_calloc_failed_get_log_info(resp, i);
    1342            0 :                     return DLT_RETURN_ERROR;
    1343              :                 }
    1344              : 
    1345            6 :                 dlt_getloginfo_conv_ascii_to_string(rp,
    1346              :                                                 &rp_count,
    1347              :                                                 con->context_description,
    1348              :                                                 con->len_context_description);
    1349              :             }
    1350              :         }
    1351              : 
    1352              :         /* application desc */
    1353            3 :         if (resp->status == 7) {
    1354            3 :             app->len_app_description = (uint16_t) dlt_getloginfo_conv_ascii_to_uint16_t(rp,
    1355              :                                                                              &rp_count);
    1356            3 :             app->app_description = (char *)calloc
    1357            3 :                     ((size_t) (app->len_app_description + 1), sizeof(char));
    1358              : 
    1359            3 :             if (app->app_description == NULL) {
    1360            0 :                 dlt_vlog(LOG_ERR, "%s: calloc failed for application description\n", __func__);
    1361            0 :                 dlt_client_free_calloc_failed_get_log_info(resp, i);
    1362            0 :                 return DLT_RETURN_ERROR;
    1363              :             }
    1364              : 
    1365            3 :             dlt_getloginfo_conv_ascii_to_string(rp,
    1366              :                                             &rp_count,
    1367              :                                             app->app_description,
    1368              :                                             app->len_app_description);
    1369              :         }
    1370              :     }
    1371              : 
    1372              :     return DLT_RETURN_OK;
    1373              : }
    1374              : 
    1375            2 : int dlt_client_cleanup_get_log_info(DltServiceGetLogInfoResponse *resp)
    1376              : {
    1377              :     AppIDsType app;
    1378              :     int i = 0;
    1379              :     int j = 0;
    1380              : 
    1381            2 :     if (resp == NULL)
    1382              :         return DLT_RETURN_OK;
    1383              : 
    1384            5 :     for (i = 0; i < resp->log_info_type.count_app_ids; i++) {
    1385            3 :         app = resp->log_info_type.app_ids[i];
    1386              : 
    1387            9 :         for (j = 0; j < app.count_context_ids; j++) {
    1388            6 :             free(app.context_id_info[j].context_description);
    1389            6 :             app.context_id_info[j].context_description = NULL;
    1390              :         }
    1391              : 
    1392            3 :         free(app.context_id_info);
    1393              :         app.context_id_info = NULL;
    1394            3 :         free(app.app_description);
    1395              :         app.app_description = NULL;
    1396              :     }
    1397              : 
    1398            2 :     free(resp->log_info_type.app_ids);
    1399              :     resp->log_info_type.app_ids = NULL;
    1400              : 
    1401            2 :     free(resp);
    1402              :     resp = NULL;
    1403              : 
    1404            2 :     return DLT_RETURN_OK;
    1405              : }
        

Generated by: LCOV version 2.0-1