LCOV - code coverage report
Current view: top level - lib - dlt_client.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 45.0 % 531 239
Test Date: 2025-03-25 20:53:42 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              : #   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          414 :     while (fetch_next_message) {
     531              :         /* wait for data from socket or serial connection */
     532          414 :         ret = dlt_receiver_receive(&(client->receiver));
     533              : 
     534          414 :         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              :             return DLT_RETURN_TRUE;
     540              :         }
     541              : 
     542          619 :         while (dlt_message_read(&msg, (unsigned char *)(client->receiver.buf),
     543          619 :                                 client->receiver.bytesRcvd,
     544              :                                 client->resync_serial_header,
     545          619 :                                 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          411 :         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          411 :         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              :         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              :         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 2.0-1