LCOV - code coverage report
Current view: top level - lib - dlt_client.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 240 534 44.9 %
Date: 2024-11-20 10:17:27 Functions: 15 31 48.4 %

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

Generated by: LCOV version 1.14