LCOV - code coverage report
Current view: top level - gateway - dlt_gateway.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 385 633 60.8 %
Date: 2024-11-20 10:17:27 Functions: 23 28 82.1 %

          Line data    Source code
       1             : /*
       2             :  * SPDX license identifier: MPL-2.0
       3             :  *
       4             :  * Copyright (C) 2015 Advanced Driver Information Technology.
       5             :  * This code is developed by Advanced Driver Information Technology.
       6             :  * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
       7             :  *
       8             :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       9             :  *
      10             :  * This Source Code Form is subject to the terms of the
      11             :  * Mozilla Public License (MPL), v. 2.0.
      12             :  * If a copy of the MPL was not distributed with this file,
      13             :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      14             :  *
      15             :  * For further information see http://www.covesa.org/.
      16             :  */
      17             : 
      18             : /*!
      19             :  * \author
      20             :  * Christoph Lipka <clipka@jp.adit-jv.com>
      21             :  * Saya Sugiura <ssugiura@jp.adit-jv.com>
      22             :  *
      23             :  * \copyright Copyright © 2015-2018 Advanced Driver Information Technology. \n
      24             :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      25             :  *
      26             :  * \file dlt_gateway.c
      27             :  */
      28             : 
      29             : #include <stdlib.h>
      30             : #include <stdio.h>
      31             : #include <string.h>
      32             : #include <syslog.h>
      33             : #include <arpa/inet.h>
      34             : #include <sys/socket.h>
      35             : #include <netinet/in.h>
      36             : #include <netdb.h>
      37             : #include <limits.h>
      38             : #include <errno.h>
      39             : #include "dlt_gateway.h"
      40             : #include "dlt_gateway_internal.h"
      41             : #include "dlt_config_file_parser.h"
      42             : #include "dlt_common.h"
      43             : #include "dlt_log.h"
      44             : #include "dlt-daemon_cfg.h"
      45             : #include "dlt_daemon_common_cfg.h"
      46             : #include "dlt_daemon_event_handler.h"
      47             : #include "dlt_daemon_connection.h"
      48             : #include "dlt_daemon_client.h"
      49             : #include "dlt_daemon_offline_logstorage.h"
      50             : 
      51             : /**
      52             :  * Check if given string is a valid IP address
      53             :  *
      54             :  * @param con   DltGatewayConnection to be updated
      55             :  * @param value string to be tested
      56             :  * @return Value from DltReturnValue enum
      57             :  */
      58           7 : DLT_STATIC DltReturnValue dlt_gateway_check_ip(DltGatewayConnection *con, char *value)
      59             : {
      60           7 :     if ((con == NULL) || (value == NULL)) {
      61           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
      62           1 :         return DLT_RETURN_WRONG_PARAMETER;
      63             :     }
      64             : 
      65             :     int ret = DLT_RETURN_ERROR;
      66             : #ifdef DLT_USE_IPv6
      67             :     struct sockaddr_in6 sa6;
      68           6 :     ret = inet_pton(AF_INET6, value, &(sa6.sin6_addr));
      69             : #else
      70             :     struct sockaddr_in sa;
      71             :     ret = inet_pton(AF_INET, value, &(sa.sin_addr));
      72             : #endif
      73             : 
      74             :     /* valid IP address */
      75           6 :     if (ret != 0) {
      76           6 :         con->ip_address = strdup(value);
      77             : 
      78           6 :         if (con->ip_address == NULL) {
      79           0 :             dlt_log(LOG_ERR, "Cannot copy passive node IP address string\n");
      80           0 :             return DLT_RETURN_ERROR;
      81             :         }
      82             : 
      83             :         return DLT_RETURN_OK;
      84             :     }
      85             :     else {
      86           0 :         dlt_log(LOG_ERR, "IP address is not valid\n");
      87             :     }
      88             : 
      89           0 :     return DLT_RETURN_ERROR;
      90             : }
      91             : 
      92             : /**
      93             :  * Check port number
      94             :  *
      95             :  * @param con     DltGatewayConnection to be updated
      96             :  * @param value   string to be tested
      97             :  * @return Value from DltReturnValue enum
      98             :  */
      99           9 : DLT_STATIC DltReturnValue dlt_gateway_check_port(DltGatewayConnection *con,
     100             :                                                  char *value)
     101             : {
     102             :     long int tmp = -1;
     103             : 
     104           9 :     if ((con == NULL) || (value == NULL)) {
     105           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     106           1 :         return DLT_RETURN_WRONG_PARAMETER;
     107             :     }
     108             : 
     109           8 :     errno = 0;
     110           8 :     tmp = strtol(value, NULL, 10);
     111           8 :     if ((errno == ERANGE && (tmp == LONG_MAX || tmp == LONG_MIN))
     112           8 :          || (errno != 0 && tmp == 0)) {
     113           0 :         dlt_vlog(LOG_ERR, "%s: cannot convert port number\n", __func__);
     114           0 :         return DLT_RETURN_ERROR;
     115             :     }
     116             : 
     117             :     /* port ranges for unprivileged applications */
     118           8 :     if ((tmp > IPPORT_RESERVED) && ((unsigned)tmp <= USHRT_MAX))
     119             :     {
     120           6 :         con->port = (int)tmp;
     121           6 :         return DLT_RETURN_OK;
     122             :     }
     123             :     else {
     124           2 :         dlt_log(LOG_ERR, "Port number is invalid\n");
     125             :     }
     126             : 
     127           2 :     return DLT_RETURN_ERROR;
     128             : }
     129             : 
     130             : /**
     131             :  * Check ECU name
     132             :  *
     133             :  * @param con     DltGatewayConnection to be updated
     134             :  * @param value   string to be used as ECU identifier
     135             :  * @return Value from DltReturnValue enum
     136             :  */
     137           6 : DLT_STATIC DltReturnValue dlt_gateway_check_ecu(DltGatewayConnection *con,
     138             :                                                 char *value)
     139             : {
     140           6 :     if ((con == NULL) || (value == NULL)) {
     141           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     142           1 :         return DLT_RETURN_WRONG_PARAMETER;
     143             :     }
     144             : 
     145           5 :     con->ecuid = strdup(value);
     146             : 
     147           5 :     if (con->ecuid == NULL)
     148           0 :         return DLT_RETURN_ERROR;
     149             : 
     150             :     return DLT_RETURN_OK;
     151             : }
     152             : 
     153             : /**
     154             :  * Check connection trigger
     155             :  *
     156             :  * @param con     DltGatewayConnection to be updated
     157             :  * @param value   string to be tested
     158             :  * @return Value from DltReturnValue enum
     159             :  */
     160           7 : DLT_STATIC DltReturnValue dlt_gateway_check_connect_trigger(DltGatewayConnection *con,
     161             :                                                             char *value)
     162             : {
     163           7 :     if ((con == NULL) || (value == NULL)) {
     164           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     165           1 :         return DLT_RETURN_WRONG_PARAMETER;
     166             :     }
     167             : 
     168           6 :     if (strncasecmp(value, "OnStartup", strlen("OnStartup")) == 0) {
     169           5 :         con->trigger = DLT_GATEWAY_ON_STARTUP;
     170             :     }
     171           1 :     else if (strncasecmp(value, "OnDemand", strlen("OnDemand")) == 0)
     172             :     {
     173           0 :         con->trigger = DLT_GATEWAY_ON_DEMAND;
     174             :     }
     175             :     else {
     176           1 :         dlt_log(LOG_ERR, "Wrong connection trigger state given.\n");
     177           1 :         con->trigger = DLT_GATEWAY_UNDEFINED;
     178           1 :         return DLT_RETURN_ERROR;
     179             :     }
     180             : 
     181             :     return DLT_RETURN_OK;
     182             : }
     183             : 
     184             : /**
     185             :  * Check connection timeout value
     186             :  *
     187             :  * @param con     DltGatewayConnection to be updated
     188             :  * @param value   string to be tested
     189             :  * @return Value from DltReturnValue enum
     190             :  */
     191           7 : DLT_STATIC DltReturnValue dlt_gateway_check_timeout(DltGatewayConnection *con,
     192             :                                                     char *value)
     193             : {
     194           7 :     if ((con == NULL) || (value == NULL)) {
     195           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     196           1 :         return DLT_RETURN_WRONG_PARAMETER;
     197             :     }
     198             : 
     199           6 :     con->timeout = (int)strtol(value, NULL, 10);
     200             : 
     201             : 
     202           6 :     if (con->timeout >= 0)
     203           5 :         return DLT_RETURN_OK;
     204             : 
     205             :     return DLT_RETURN_ERROR;
     206             : }
     207             : 
     208             : /**
     209             :  * Check connection interval value in General section
     210             :  *
     211             :  * @param con     DltGateway to be updated
     212             :  * @param value   string to be tested
     213             :  * @return Value from DltReturnValue enum
     214             :  */
     215           0 : DLT_STATIC DltReturnValue dlt_gateway_check_interval(DltGateway *gateway,
     216             :                                                     char *value)
     217             : {
     218           0 :     if ((gateway == NULL) || (value == NULL)) {
     219           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     220           0 :         return DLT_RETURN_WRONG_PARAMETER;
     221             :     }
     222             : 
     223           0 :     gateway->interval = (int)strtol(value, NULL, 10);
     224             : 
     225           0 :     if (gateway->interval > 0)
     226           0 :         return DLT_RETURN_OK;
     227             : 
     228             :     return DLT_RETURN_ERROR;
     229             : }
     230             : 
     231             : /**
     232             :  * Check the value for SendSerialHeader
     233             :  *
     234             :  * @param con   DltGatewayConnection to be updated
     235             :  * @param value string to be tested
     236             :  * @return Value from DltReturnValue enum
     237             :  */
     238           6 : DLT_STATIC DltReturnValue dlt_gateway_check_send_serial(DltGatewayConnection *con,
     239             :                                                         char *value)
     240             : {
     241           6 :     if ((con == NULL) || (value == NULL)) {
     242           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     243           1 :         return DLT_RETURN_WRONG_PARAMETER;
     244             :     }
     245             : 
     246           5 :     con->send_serial = !!((int)strtol(value, NULL, 10));
     247             : 
     248           5 :     return DLT_RETURN_OK;
     249             : }
     250             : 
     251             : /**
     252             :  * Allocate passive control messages
     253             :  *
     254             :  * @param con   DltGatewayConnection to be updated
     255             :  * @return Value from DltReturnValue enum
     256             :  */
     257          17 : DLT_STATIC DltReturnValue dlt_gateway_allocate_control_messages(DltGatewayConnection *con)
     258             : {
     259          17 :     if (con == NULL) {
     260           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     261           1 :         return DLT_RETURN_WRONG_PARAMETER;
     262             :     }
     263             : 
     264          16 :     if (con->p_control_msgs == NULL) {
     265           7 :         con->p_control_msgs = calloc(1, sizeof(DltPassiveControlMessage));
     266             : 
     267           7 :         if (!con->p_control_msgs) {
     268           0 :             dlt_log(LOG_ERR,
     269             :                     "Passive Control Message could not be allocated\n");
     270           0 :             return DLT_RETURN_ERROR;
     271             :         }
     272             :     }
     273             :     else {
     274           9 :         con->p_control_msgs->next = calloc(1, sizeof(DltPassiveControlMessage));
     275             : 
     276           9 :         if (!con->p_control_msgs->next) {
     277           0 :             dlt_log(LOG_ERR,
     278             :                     "Passive Control Message could not be allocated\n");
     279           0 :             return DLT_RETURN_ERROR;
     280             :         }
     281             : 
     282           9 :         con->p_control_msgs = con->p_control_msgs->next;
     283             :     }
     284             : 
     285             :     return DLT_RETURN_OK;
     286             : }
     287             : 
     288             : /**
     289             :  * Check the specified control messages identifier
     290             :  *
     291             :  * @param con   DltGatewayConnection to be updated
     292             :  * @param value string to be tested
     293             :  * @return Value from DltReturnValue enum
     294             :  */
     295           6 : DLT_STATIC DltReturnValue dlt_gateway_check_control_messages(DltGatewayConnection *con,
     296             :                                                              char *value)
     297             : {
     298             :     /* list of allowed clients given */
     299             :     char *token = NULL;
     300           6 :     char *rest = NULL;
     301             :     DltPassiveControlMessage *head = NULL;
     302             : 
     303           6 :     if ((con == NULL) || (value == NULL)) {
     304           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     305           1 :         return DLT_RETURN_WRONG_PARAMETER;
     306             :     }
     307             : 
     308           5 :     if (strlen(value) == 0)
     309             :         return DLT_RETURN_OK;
     310             : 
     311             :     /* set on startup control msg id and interval*/
     312           5 :     token = strtok_r(value, ",", &rest);
     313             : 
     314          18 :     while (token != NULL) {
     315          13 :         if (dlt_gateway_allocate_control_messages(con) != DLT_RETURN_OK) {
     316           0 :             dlt_log(LOG_ERR,
     317             :                     "Passive Control Message could not be allocated\n");
     318           0 :             return DLT_RETURN_ERROR;
     319             :         }
     320             : 
     321          13 :         con->p_control_msgs->id = strtol(token, NULL, 16);
     322          13 :         con->p_control_msgs->user_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
     323          13 :         con->p_control_msgs->type = CONTROL_MESSAGE_ON_STARTUP;
     324          13 :         con->p_control_msgs->req = CONTROL_MESSAGE_NOT_REQUESTED;
     325          13 :         con->p_control_msgs->interval = -1;
     326             : 
     327          13 :         if (head == NULL)
     328             :             head = con->p_control_msgs;
     329             : 
     330          13 :         if ((errno == EINVAL) || (errno == ERANGE)) {
     331           0 :             dlt_vlog(LOG_ERR,
     332             :                      "Control message ID is not an integer: %s\n",
     333             :                      token);
     334           0 :             return DLT_RETURN_ERROR;
     335             :         }
     336          13 :         else if ((con->p_control_msgs->id < DLT_SERVICE_ID_SET_LOG_LEVEL) ||
     337             :                  (con->p_control_msgs->id >= DLT_SERVICE_ID_LAST_ENTRY))
     338             :         {
     339           0 :             dlt_vlog(LOG_ERR,
     340             :                      "Control message ID is not valid: %s\n",
     341             :                      token);
     342           0 :             return DLT_RETURN_ERROR;
     343             :         }
     344             : 
     345          13 :         token = strtok_r(NULL, ",", &rest);
     346             :     }
     347             : 
     348             :     /* get back to head */
     349           5 :     con->p_control_msgs = head;
     350           5 :     con->head = head;
     351             : 
     352           5 :     return DLT_RETURN_OK;
     353             : }
     354             : 
     355             : /**
     356             :  * Check the specified periodic control messages identifier
     357             :  *
     358             :  * @param con   DltGatewayConnection to be updated
     359             :  * @param value string to be tested
     360             :  * @return Value from DltReturnValue enum
     361             :  */
     362           2 : DLT_STATIC DltReturnValue dlt_gateway_check_periodic_control_messages(
     363             :     DltGatewayConnection *con,
     364             :     char *value)
     365             : {
     366             :     char *token = NULL;
     367           2 :     char *rest = NULL;
     368             :     DltPassiveControlMessage *head = NULL;
     369             : 
     370           2 :     if ((con == NULL) || (value == NULL)) {
     371           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     372           1 :         return DLT_RETURN_WRONG_PARAMETER;
     373             :     }
     374             : 
     375           1 :     if (strlen(value) == 0)
     376             :         return DLT_RETURN_OK;
     377             : 
     378             :     /* store head address */
     379           1 :     head = con->p_control_msgs;
     380             : 
     381             :     /* set periodic control msg id and interval*/
     382           1 :     token = strtok_r(value, ",", &rest);
     383             : 
     384           3 :     while (token != NULL) {
     385             :         char *p_token = NULL;
     386           2 :         char *p_rest = NULL;
     387             :         uint32_t id = 0;
     388             : 
     389           2 :         p_token = strtok_r(token, ":", &p_rest);
     390             : 
     391           2 :         if ((p_token != NULL) && (strlen(p_token) != 0)) {
     392           2 :             id = strtol(p_token, NULL, 16);
     393             : 
     394             :             /* get back to head */
     395           2 :             con->p_control_msgs = head;
     396             : 
     397             :             /* check if there is already id set in p_control_msgs */
     398           3 :             while (con->p_control_msgs != NULL) {
     399           1 :                 if (con->p_control_msgs->id == id) {
     400           0 :                     con->p_control_msgs->type = CONTROL_MESSAGE_BOTH;
     401           0 :                     con->p_control_msgs->interval = strtol(p_rest, NULL, 10);
     402             : 
     403           0 :                     if (con->p_control_msgs->interval <= 0)
     404           0 :                         dlt_vlog(LOG_WARNING,
     405             :                                  "%s interval is %d. It won't be send periodically.\n",
     406             :                                  dlt_get_service_name(con->p_control_msgs->id),
     407             :                                  con->p_control_msgs->interval);
     408             : 
     409             :                     break;
     410             :                 }
     411             : 
     412           1 :                 con->p_control_msgs = con->p_control_msgs->next;
     413             :             }
     414             : 
     415             :             /* if the id is not added yet, p_control_msgs supposed to be NULL */
     416           2 :             if (con->p_control_msgs == NULL) {
     417             :                 /* get back to head */
     418           2 :                 con->p_control_msgs = head;
     419             : 
     420             :                 /* go to last pointer */
     421           2 :                 while (con->p_control_msgs != NULL) {
     422           1 :                     if (con->p_control_msgs->next == NULL)
     423             :                         break;
     424             : 
     425           0 :                     con->p_control_msgs = con->p_control_msgs->next;
     426             :                 }
     427             : 
     428           2 :                 if (dlt_gateway_allocate_control_messages(con) != DLT_RETURN_OK) {
     429           0 :                     dlt_log(LOG_ERR,
     430             :                             "Passive Control Message could not be allocated\n");
     431           0 :                     return DLT_RETURN_ERROR;
     432             :                 }
     433             : 
     434           2 :                 con->p_control_msgs->id = id;
     435           2 :                 con->p_control_msgs->user_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
     436           2 :                 con->p_control_msgs->type = CONTROL_MESSAGE_PERIODIC;
     437           2 :                 con->p_control_msgs->req = CONTROL_MESSAGE_NOT_REQUESTED;
     438           2 :                 con->p_control_msgs->interval = strtol(p_rest, NULL, 10);
     439             : 
     440           2 :                 if (con->p_control_msgs->interval <= 0)
     441           0 :                     dlt_vlog(LOG_WARNING,
     442             :                              "%s interval is %d. It won't be send periodically.\n",
     443             :                              dlt_get_service_name(con->p_control_msgs->id),
     444             :                              con->p_control_msgs->interval);
     445             : 
     446           2 :                 if (head == NULL)
     447           1 :                     head = con->p_control_msgs;
     448             :             }
     449             :         }
     450             : 
     451           2 :         if ((errno == EINVAL) || (errno == ERANGE)) {
     452           0 :             dlt_vlog(LOG_ERR,
     453             :                      "Control message ID is not an integer: %s\n",
     454             :                      p_token);
     455           0 :             return DLT_RETURN_ERROR;
     456             :         }
     457           2 :         else if ((con->p_control_msgs->id < DLT_SERVICE_ID_SET_LOG_LEVEL) ||
     458             :                  (con->p_control_msgs->id >= DLT_SERVICE_ID_LAST_ENTRY))
     459             :         {
     460           0 :             dlt_vlog(LOG_ERR,
     461             :                      "Control message ID is not valid: %s\n",
     462             :                      p_token);
     463           0 :             return DLT_RETURN_ERROR;
     464             :         }
     465             : 
     466           2 :         token = strtok_r(NULL, ",", &rest);
     467             :     }
     468             : 
     469             :     /* get back to head */
     470           1 :     con->p_control_msgs = head;
     471           1 :     con->head = head;
     472             : 
     473           1 :     return DLT_RETURN_OK;
     474             : }
     475             : 
     476             : /**
     477             :  * Expected entries for a passive node configuration
     478             :  * Caution: after changing entries here,
     479             :  * dlt_gateway_check_param needs to be updated as well
     480             :  * */
     481             : DLT_STATIC DltGatewayConf configuration_entries[GW_CONF_COUNT] = {
     482             :     [GW_CONF_IP_ADDRESS] = {
     483             :         .key = "IPaddress",
     484             :         .func = dlt_gateway_check_ip,
     485             :         .is_opt = 0
     486             :     },
     487             :     [GW_CONF_PORT] = {
     488             :         .key = "Port",
     489             :         .func = dlt_gateway_check_port,
     490             :         .is_opt = 1
     491             :     },
     492             :     [GW_CONF_ECUID] = {
     493             :         .key = "EcuID",
     494             :         .func = dlt_gateway_check_ecu,
     495             :         .is_opt = 0
     496             :     },
     497             :     [GW_CONF_CONNECT] = {
     498             :         .key = "Connect",
     499             :         .func = dlt_gateway_check_connect_trigger,
     500             :         .is_opt = 1
     501             :     },
     502             :     [GW_CONF_TIMEOUT] = {
     503             :         .key = "Timeout",
     504             :         .func = dlt_gateway_check_timeout,
     505             :         .is_opt = 0
     506             :     },
     507             :     [GW_CONF_SEND_CONTROL] = {
     508             :         .key = "SendControl",
     509             :         .func = dlt_gateway_check_control_messages,
     510             :         .is_opt = 1
     511             :     },
     512             :     [GW_CONF_SEND_PERIODIC_CONTROL] = {
     513             :         .key = "SendPeriodicControl",
     514             :         .func = dlt_gateway_check_periodic_control_messages,
     515             :         .is_opt = 1
     516             :     },
     517             :     [GW_CONF_SEND_SERIAL_HEADER] = {
     518             :         .key = "SendSerialHeader",
     519             :         .func = dlt_gateway_check_send_serial,
     520             :         .is_opt = 1
     521             :     }
     522             : };
     523             : 
     524             : DLT_STATIC DltGatewayGeneralConf general_entries[GW_CONF_COUNT] = {
     525             :     [GW_CONF_GENERAL_INTERVAL] = {
     526             :         .key = "Interval",
     527             :         .func = dlt_gateway_check_interval,
     528             :         .is_opt = 1
     529             :     }
     530             : };
     531             : 
     532             : #define DLT_GATEWAY_NUM_PROPERTIES_MAX GW_CONF_COUNT
     533             : 
     534             : /**
     535             :  * Check if gateway connection general configuration parameter is valid.
     536             :  *
     537             :  * @param gateway    DltGateway
     538             :  * @param ctype      DltGatwayGeneralConnection property
     539             :  * @param value      specified property value from configuration file
     540             :  * @return Value from DltReturnValue enum
     541             :  */
     542           0 : DLT_STATIC DltReturnValue dlt_gateway_check_general_param(DltGateway *gateway,
     543             :                                                   DltGatewayGeneralConfType ctype,
     544             :                                                   char *value)
     545             : {
     546           0 :     if ((gateway == NULL) || (value == NULL)) {
     547           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     548           0 :         return DLT_RETURN_WRONG_PARAMETER;
     549             :     }
     550             : 
     551           0 :     if (ctype < GW_CONF_GENEREL_COUNT)
     552           0 :         return general_entries[ctype].func(gateway, value);
     553             : 
     554             :     return DLT_RETURN_ERROR;
     555             : }
     556             : 
     557             : /**
     558             :  * Check if gateway connection configuration parameter is valid.
     559             :  *
     560             :  * @param gateway    DltGateway
     561             :  * @param con        DltGatewayConnection
     562             :  * @param ctype      DltGatwayConnection property
     563             :  * @param value      specified property value from configuration file
     564             :  * @return Value from DltReturnValue enum
     565             :  */
     566          32 : DLT_STATIC DltReturnValue dlt_gateway_check_param(DltGateway *gateway,
     567             :                                                   DltGatewayConnection *con,
     568             :                                                   DltGatewayConfType ctype,
     569             :                                                   char *value)
     570             : {
     571          32 :     if ((gateway == NULL) || (con == NULL) || (value == NULL)) {
     572           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     573           1 :         return DLT_RETURN_WRONG_PARAMETER;
     574             :     }
     575             : 
     576          31 :     if (ctype < GW_CONF_COUNT)
     577          31 :         return configuration_entries[ctype].func(con, value);
     578             : 
     579             :     return DLT_RETURN_ERROR;
     580             : }
     581             : 
     582             : /**
     583             :  * Store gateway connection in internal data structure
     584             :  *
     585             :  * @param gateway    DltGatway
     586             :  * @param tmp        DltGatewayConnection
     587             :  * @param verbose    verbose flag
     588             :  * @return 0 on success, -1 otherwise
     589             :  */
     590           7 : int dlt_gateway_store_connection(DltGateway *gateway,
     591             :                                  DltGatewayConnection *tmp,
     592             :                                  int verbose)
     593             : {
     594             :     int i = 0;
     595             : 
     596           7 :     PRINT_FUNCTION_VERBOSE(verbose);
     597             : 
     598           7 :     if ((gateway == NULL) || (tmp == NULL)) {
     599           2 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     600           2 :         return DLT_RETURN_WRONG_PARAMETER;
     601             :     }
     602             : 
     603             :     /* find next free entry in connection array */
     604           5 :     while (i < gateway->num_connections) {
     605           5 :         if (gateway->connections[i].status == DLT_GATEWAY_UNINITIALIZED)
     606             :             break;
     607             : 
     608           0 :         i++;
     609             :     }
     610             : 
     611             :     /* store values */
     612           5 :     gateway->connections[i].ip_address = strdup(tmp->ip_address);
     613           5 :     gateway->connections[i].ecuid = strdup(tmp->ecuid);
     614           5 :     gateway->connections[i].sock_domain = tmp->sock_domain;
     615           5 :     gateway->connections[i].sock_type = tmp->sock_type;
     616           5 :     gateway->connections[i].sock_protocol = tmp->sock_protocol;
     617           5 :     gateway->connections[i].port = tmp->port;
     618           5 :     gateway->connections[i].trigger = tmp->trigger;
     619           5 :     gateway->connections[i].timeout = tmp->timeout;
     620           5 :     gateway->connections[i].handle = 0;
     621           5 :     gateway->connections[i].status = DLT_GATEWAY_INITIALIZED;
     622           5 :     gateway->connections[i].p_control_msgs = tmp->p_control_msgs;
     623           5 :     gateway->connections[i].head = tmp->head;
     624           5 :     gateway->connections[i].send_serial = tmp->send_serial;
     625             : 
     626           5 :     if (dlt_client_init_port(&gateway->connections[i].client,
     627             :                              gateway->connections[i].port,
     628             :                              verbose) != 0) {
     629           0 :         free(gateway->connections[i].ip_address);
     630           0 :         gateway->connections[i].ip_address = NULL;
     631           0 :         free(gateway->connections[i].ecuid);
     632           0 :         gateway->connections[i].ecuid = NULL;
     633           0 :         free(gateway->connections[i].p_control_msgs);
     634           0 :         gateway->connections[i].p_control_msgs = NULL;
     635           0 :         dlt_log(LOG_CRIT, "dlt_client_init_port() failed for gateway connection\n");
     636           0 :         return DLT_RETURN_ERROR;
     637             :     }
     638             : 
     639             :     /* setup DltClient Structure */
     640           5 :     if (dlt_client_set_server_ip(&gateway->connections[i].client,
     641           5 :                                  gateway->connections[i].ip_address) == -1) {
     642           0 :         dlt_log(LOG_ERR,
     643             :                 "dlt_client_set_server_ip() failed for gateway connection \n");
     644           0 :         return DLT_RETURN_ERROR;
     645             :     }
     646             : 
     647             :     return DLT_RETURN_OK;
     648             : }
     649             : 
     650             : /**
     651             :  * Read configuration file and initialize connection data structures
     652             :  *
     653             :  * @param gateway       DltGateway
     654             :  * @param config_file   Gateway configuration
     655             :  * @param verbose       verbose flag
     656             :  * @return 0 on success, -1 otherwise
     657             :  */
     658           5 : int dlt_gateway_configure(DltGateway *gateway, char *config_file, int verbose)
     659             : {
     660             :     int ret = 0;
     661             :     int i = 0;
     662             :     DltConfigFile *file = NULL;
     663           5 :     int num_sections = 0;
     664             : 
     665           5 :     PRINT_FUNCTION_VERBOSE(verbose);
     666             : 
     667           5 :     if ((gateway == NULL) || (config_file == 0) || (config_file[0] == '\0')) {
     668           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     669           1 :         return DLT_RETURN_WRONG_PARAMETER;
     670             :     }
     671             : 
     672             :     /* read configuration file */
     673           4 :     file = dlt_config_file_init(config_file);
     674           4 :     if(file == NULL) {
     675             :         return DLT_RETURN_ERROR;
     676             :     }
     677             : 
     678             :     /* get number of entries and allocate memory to store information */
     679           4 :     ret = dlt_config_file_get_num_sections(file, &num_sections);
     680           4 :     if (ret != 0) {
     681           0 :         dlt_config_file_release(file);
     682           0 :         dlt_log(LOG_ERR, "Invalid number of sections in configuration file\n");
     683           0 :         return DLT_RETURN_ERROR;
     684             :     }
     685             : 
     686           4 :     ret = dlt_config_file_check_section_name_exists(file, DLT_GATEWAY_GENERAL_SECTION_NAME);
     687           4 :     if (ret == -1) {
     688             :         /*
     689             :          * No General section in configuration file.
     690             :          * Try to use default for interval.
     691             :          */
     692           4 :         gateway->num_connections = num_sections;
     693           4 :         dlt_vlog(LOG_WARNING,
     694             :                 "Missing General section in gateway. Using default interval %d (secs)\n",
     695             :                 gateway->interval);
     696             :     }
     697             :     else {
     698             :         /*
     699             :          * Since the General section is also counted in num_sections,
     700             :          * so number of connections must be number of sections - 1.
     701             :          */
     702           0 :         gateway->num_connections = num_sections - 1;
     703             :     }
     704             : 
     705           4 :     gateway->connections = calloc(gateway->num_connections,
     706             :                                 sizeof(DltGatewayConnection));
     707             : 
     708           4 :     if (gateway->connections == NULL) {
     709           0 :         dlt_config_file_release(file);
     710           0 :         dlt_log(LOG_CRIT, "Memory allocation for gateway connections failed\n");
     711           0 :         return DLT_RETURN_ERROR;
     712             :     }
     713             : 
     714           8 :     for (i = 0; i < num_sections; i++) {
     715             :         DltGatewayConnection tmp;
     716             :         int invalid = 0;
     717             :         DltGatewayConfType j = 0;
     718             :         DltGatewayGeneralConfType g = 0;
     719           4 :         char section[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = { '\0' };
     720           4 :         char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = { '\0' };
     721             : 
     722             :         memset(&tmp, 0, sizeof(tmp));
     723             : 
     724             :         /* Set default */
     725           4 :         tmp.send_serial = gateway->send_serial;
     726           4 :         tmp.port = DLT_DAEMON_TCP_PORT;
     727             : 
     728           4 :         ret = dlt_config_file_get_section_name(file, i, section);
     729           4 :         if (ret != 0) {
     730           0 :             dlt_log(LOG_WARNING, "Get section name failed\n");
     731           0 :             continue;
     732             :         }
     733             : 
     734           4 :         if (strncmp(section, DLT_GATEWAY_GENERAL_SECTION_NAME,
     735             :                 sizeof(DLT_GATEWAY_GENERAL_SECTION_NAME)) == 0) {
     736           0 :             for (g = 0; g < GW_CONF_GENEREL_COUNT; g++) {
     737           0 :                 ret = dlt_config_file_get_value(file,
     738             :                                                 section,
     739           0 :                                                 general_entries[g].key,
     740             :                                                 value);
     741             : 
     742           0 :                 if ((ret != 0) && general_entries[g].is_opt) {
     743             :                     /* Use default values for this key */
     744           0 :                     dlt_vlog(LOG_WARNING,
     745             :                              "Using default for %s.\n",
     746             :                              general_entries[g].key);
     747           0 :                     continue;
     748             :                 }
     749           0 :                 else if (ret != 0)
     750             :                 {
     751           0 :                     dlt_vlog(LOG_WARNING,
     752             :                              "Missing configuration for %s.\n",
     753             :                              general_entries[g].key);
     754           0 :                     break;
     755             :                 }
     756             : 
     757             :                 /* check value and store general configuration */
     758           0 :                 ret = dlt_gateway_check_general_param(gateway, g, value);
     759             : 
     760           0 :                 if (ret != 0)
     761           0 :                     dlt_vlog(LOG_ERR,
     762             :                              "Configuration %s = %s is invalid. Using default.\n",
     763             :                              general_entries[g].key, value);
     764             :             }
     765             :         }
     766             :         else {
     767          36 :             for (j = 0; j < GW_CONF_COUNT; j++) {
     768          32 :                 ret = dlt_config_file_get_value(file,
     769             :                                                 section,
     770          32 :                                                 configuration_entries[j].key,
     771             :                                                 value);
     772             : 
     773          32 :                 if ((ret != 0) && configuration_entries[j].is_opt) {
     774             :                     /* Use default values for this key */
     775           4 :                     dlt_vlog(LOG_WARNING,
     776             :                              "Using default for %s.\n",
     777             :                              configuration_entries[j].key);
     778           4 :                     continue;
     779             :                 }
     780          28 :                 else if (ret != 0)
     781             :                 {
     782           0 :                     dlt_vlog(LOG_WARNING,
     783             :                              "Missing configuration for %s.\n",
     784             :                              configuration_entries[j].key);
     785             :                     invalid = 1;
     786           0 :                     break;
     787             :                 }
     788             : 
     789             :                 /* check value and store temporary */
     790          28 :                 ret = dlt_gateway_check_param(gateway, &tmp, j, value);
     791             : 
     792          28 :                 if (ret != 0)
     793           0 :                     dlt_vlog(LOG_ERR,
     794             :                              "Configuration %s = %s is invalid.\n"
     795             :                              "Using default.\n",
     796             :                              configuration_entries[j].key, value);
     797             :             }
     798             : 
     799           4 :             if (!tmp.ip_address) {
     800             :                 invalid = 1;
     801             :             }
     802             : 
     803           4 :             if (invalid) {
     804           0 :                 dlt_vlog(LOG_ERR,
     805             :                          "%s configuration is invalid.\n"
     806             :                          "Ignoring.\n",
     807             :                          section);
     808             :             }
     809             :             else {
     810           4 :                 ret = dlt_gateway_store_connection(gateway, &tmp, verbose);
     811             : 
     812           4 :                 if (ret != 0)
     813           0 :                     dlt_log(LOG_ERR, "Storing gateway connection data failed\n");
     814             :             }
     815             :         }
     816             : 
     817             :         /* strdup used inside some get_value function */
     818           4 :         if (tmp.ecuid != NULL) {
     819           4 :             free(tmp.ecuid);
     820           4 :             tmp.ecuid = NULL;
     821             :         }
     822           4 :         if (tmp.ip_address != NULL) {
     823           4 :             free(tmp.ip_address);
     824             :             tmp.ip_address = NULL;
     825             :         }
     826             :     }
     827             : 
     828           4 :     dlt_config_file_release(file);
     829           4 :     return ret;
     830             : }
     831             : 
     832           4 : int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose)
     833             : {
     834           4 :     PRINT_FUNCTION_VERBOSE(verbose);
     835             : 
     836           4 :     if (daemon_local == NULL) {
     837           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     838           1 :         return DLT_RETURN_WRONG_PARAMETER;
     839             :     }
     840             : 
     841           3 :     DltGateway *gateway = &daemon_local->pGateway;
     842             : 
     843             :     if (gateway != NULL) {
     844             :         /* Get default value from daemon_local */
     845           3 :         gateway->send_serial = daemon_local->flags.lflag;
     846           3 :         gateway->interval = DLT_GATEWAY_TIMER_DEFAULT_INTERVAL;
     847             : 
     848           3 :         if (dlt_gateway_configure(gateway,
     849           3 :                                   daemon_local->flags.gatewayConfigFile,
     850             :                                   verbose) != 0) {
     851           0 :             dlt_log(LOG_ERR, "Gateway initialization failed\n");
     852           0 :             return DLT_RETURN_ERROR;
     853             :         }
     854             :     }
     855             :     else {
     856             :         dlt_log(LOG_CRIT, "Pointer to Gateway structure is NULL\n");
     857             :         return DLT_RETURN_ERROR;
     858             :     }
     859             : 
     860             :     /* ignore return value */
     861           3 :     dlt_gateway_establish_connections(gateway, daemon_local, verbose);
     862             : 
     863           3 :     return DLT_RETURN_OK;
     864             : }
     865             : 
     866          10 : void dlt_gateway_deinit(DltGateway *gateway, int verbose)
     867             : {
     868             :     DltPassiveControlMessage *msg;
     869             :     int i = 0;
     870             : 
     871          10 :     if (gateway == NULL) {
     872           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     873           0 :         return;
     874             :     }
     875             : 
     876          10 :     PRINT_FUNCTION_VERBOSE(verbose);
     877             : 
     878          12 :     for (i = 0; i < gateway->num_connections; i++) {
     879           2 :         DltGatewayConnection *c = &gateway->connections[i];
     880           2 :         dlt_client_cleanup(&c->client, verbose);
     881           2 :         free(c->ip_address);
     882           2 :         c->ip_address = NULL;
     883           2 :         free(c->ecuid);
     884           2 :         c->ecuid = NULL;
     885             : 
     886           6 :         while (c->p_control_msgs != NULL) {
     887           4 :             msg = c->p_control_msgs->next;
     888           4 :             free(c->p_control_msgs);
     889           4 :             c->p_control_msgs = msg;
     890             :         }
     891             :     }
     892             : 
     893          10 :     free(gateway->connections);
     894          10 :     gateway->connections = NULL;
     895             : }
     896             : 
     897             : /**
     898             :  * If connection to passive node established, add to event loop
     899             :  *
     900             :  * @param daemon_local  DltDaemonLocal
     901             :  * @param con           DltGatewayConnection
     902             :  * @param verbose       verbose flag
     903             :  * @return 0 on success, -1 otherwise
     904             :  */
     905           3 : DLT_STATIC int dlt_gateway_add_to_event_loop(DltDaemonLocal *daemon_local,
     906             :                                              DltGatewayConnection *con,
     907             :                                              int verbose)
     908             : {
     909             :     DltPassiveControlMessage *control_msg = NULL;
     910             :     int sendtime = 1;
     911             : 
     912           3 :     if ((daemon_local == NULL) || (con == NULL)) {
     913           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     914           0 :         return DLT_RETURN_WRONG_PARAMETER;
     915             :     }
     916             : 
     917             :     /* connection to passive node established, add to event loop */
     918           3 :     con->status = DLT_GATEWAY_CONNECTED;
     919           3 :     con->reconnect_cnt = 0;
     920           3 :     con->timeout_cnt = 0;
     921           3 :     con->sendtime_cnt = 0;
     922             : 
     923             :     /* setup dlt connection and add to poll event loop here */
     924           3 :     if (dlt_connection_create(daemon_local,
     925             :                               &daemon_local->pEvent,
     926             :                               con->client.sock,
     927             :                               POLLIN,
     928             :                               DLT_CONNECTION_GATEWAY) != 0) {
     929           0 :         dlt_log(LOG_ERR, "Gateway connection creation failed\n");
     930           0 :         return DLT_RETURN_ERROR;
     931             :     }
     932             : 
     933             :     /* immediately send configured control messages */
     934           3 :     control_msg = con->p_control_msgs;
     935             : 
     936           9 :     while (control_msg != NULL) {
     937           6 :         if ((control_msg->type == CONTROL_MESSAGE_ON_STARTUP) ||
     938             :             (control_msg->type == CONTROL_MESSAGE_BOTH)) {
     939           6 :             if (dlt_gateway_send_control_message(con,
     940             :                                                  control_msg,
     941             :                                                  NULL,
     942             :                                                  verbose) == DLT_RETURN_OK)
     943           6 :                 control_msg->req = CONTROL_MESSAGE_REQUESTED;
     944             :         }
     945             : 
     946             :         /* multiply periodic sending time */
     947           6 :         if (((control_msg->type == CONTROL_MESSAGE_PERIODIC) ||
     948           0 :              (control_msg->type == CONTROL_MESSAGE_BOTH)) &&
     949           0 :             (control_msg->interval > 0))
     950           0 :             sendtime *= control_msg->interval;
     951             : 
     952           6 :         control_msg = control_msg->next;
     953             :     }
     954             : 
     955             :     /* set periodic sending time */
     956           3 :     con->sendtime = sendtime;
     957           3 :     con->sendtime_cnt = con->sendtime;
     958             : 
     959           3 :     return DLT_RETURN_OK;
     960             : }
     961             : 
     962           6 : int dlt_gateway_establish_connections(DltGateway *gateway,
     963             :                                       DltDaemonLocal *daemon_local,
     964             :                                       int verbose)
     965             : {
     966             :     int i = 0;
     967             :     int ret = 0;
     968             : 
     969           6 :     PRINT_FUNCTION_VERBOSE(verbose);
     970             : 
     971           6 :     if ((gateway == NULL) || (daemon_local == NULL)) {
     972           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
     973           1 :         return DLT_RETURN_WRONG_PARAMETER;
     974             :     }
     975             : 
     976          10 :     for (i = 0; i < gateway->num_connections; i++) {
     977           5 :         DltGatewayConnection *con = &(gateway->connections[i]);
     978             :         DltPassiveControlMessage *control_msg = NULL;
     979             : 
     980           5 :         if ((con->status != DLT_GATEWAY_CONNECTED) &&
     981           5 :             (con->trigger != DLT_GATEWAY_ON_DEMAND) &&
     982             :             (con->trigger != DLT_GATEWAY_DISABLED)) {
     983           5 :             ret = dlt_client_connect(&con->client, verbose);
     984             : 
     985           5 :             if (ret == 0) {
     986             :                 /* setup dlt connection and add to poll event loop here */
     987           3 :                 if (dlt_gateway_add_to_event_loop(daemon_local, con, verbose) != DLT_RETURN_OK) {
     988           0 :                     dlt_log(LOG_ERR, "Gateway connection creation failed\n");
     989           0 :                     return DLT_RETURN_ERROR;
     990             :                 }
     991             :             }
     992             :             else {
     993           2 :                 dlt_log(LOG_DEBUG,
     994             :                         "Passive Node is not up. Connection failed.\n");
     995             : 
     996           2 :                 con->timeout_cnt++;
     997             : 
     998           2 :                 if (con->timeout > 0) {
     999           0 :                     if (con->timeout_cnt > con->timeout) {
    1000           0 :                         con->trigger = DLT_GATEWAY_DISABLED;
    1001           0 :                         dlt_log(LOG_WARNING,
    1002             :                                 "Passive Node connection retry timed out. "
    1003             :                                 "Give up.\n");
    1004             :                     }
    1005             :                 }
    1006           2 :                 else if (con->timeout == 0) {
    1007           2 :                     dlt_vlog(LOG_DEBUG, "Retried [%d] times\n", con->timeout_cnt);
    1008             :                 }
    1009             :             }
    1010             :         }
    1011           0 :         else if ((con->status == DLT_GATEWAY_CONNECTED) &&
    1012           0 :                  (con->trigger != DLT_GATEWAY_DISABLED))
    1013             :         {
    1014             :             /* setup dlt connection and add to poll event loop here */
    1015           0 :             if (dlt_connection_create(daemon_local,
    1016             :                                       &daemon_local->pEvent,
    1017             :                                       con->client.sock,
    1018             :                                       POLLIN,
    1019             :                                       DLT_CONNECTION_GATEWAY) != 0) {
    1020           0 :                 dlt_log(LOG_ERR, "Gateway connection creation failed\n");
    1021           0 :                 return DLT_RETURN_ERROR;
    1022             :             }
    1023             : 
    1024             :             /* immediately send periodic configured control messages */
    1025           0 :             control_msg = con->p_control_msgs;
    1026             : 
    1027           0 :             while (control_msg != NULL) {
    1028           0 :                 if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) ||
    1029             :                     (control_msg->type == CONTROL_MESSAGE_BOTH)) {
    1030           0 :                     if (dlt_gateway_send_control_message(con,
    1031             :                                                          control_msg,
    1032             :                                                          NULL,
    1033             :                                                          verbose) == DLT_RETURN_OK)
    1034           0 :                         control_msg->req = CONTROL_MESSAGE_REQUESTED;
    1035             :                 }
    1036             : 
    1037           0 :                 control_msg = control_msg->next;
    1038             :             }
    1039             : 
    1040             :             /* check sendtime counter */
    1041           0 :             if (con->sendtime_cnt > 0)
    1042           0 :                 con->sendtime_cnt--;
    1043             : 
    1044           0 :             if (con->sendtime_cnt == 0)
    1045           0 :                 con->sendtime_cnt = con->sendtime;
    1046             :         }
    1047             :     }
    1048             : 
    1049             :     return DLT_RETURN_OK;
    1050             : }
    1051             : 
    1052           6 : DltReceiver *dlt_gateway_get_connection_receiver(DltGateway *gateway, int fd)
    1053             : {
    1054             :     int i = 0;
    1055             : 
    1056           6 :     if (gateway == NULL) {
    1057           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1058           1 :         return NULL;
    1059             :     }
    1060             : 
    1061           6 :     for (i = 0; i < gateway->num_connections; i++) {
    1062           5 :         DltGatewayConnection *c = &gateway->connections[i];
    1063             : 
    1064           5 :         if ((c->status == DLT_GATEWAY_CONNECTED) && (c->client.sock == fd))
    1065           4 :             return &c->client.receiver;
    1066             :     }
    1067             : 
    1068             :     return NULL;
    1069             : }
    1070             : 
    1071             : /**
    1072             :  * Parse GET_LOG_INFO
    1073             :  *
    1074             :  * @param daemon          DltDaemon
    1075             :  * @param ecu             Ecu ID
    1076             :  * @param msg             DltMessage
    1077             :  * @param req             1 if requested from gateway, 0 otherwise
    1078             :  * @param verbose verbose flag
    1079             :  * @return Value from DltReturnValue enum
    1080             :  */
    1081           3 : DLT_STATIC DltReturnValue dlt_gateway_parse_get_log_info(DltDaemon *daemon,
    1082             :                                                          char *ecu,
    1083             :                                                          DltMessage *msg,
    1084             :                                                          int req,
    1085             :                                                          int verbose)
    1086             : {
    1087           3 :     char resp_text[DLT_RECEIVE_BUFSIZE] = { '\0' };
    1088             :     DltServiceGetLogInfoResponse *resp = NULL;
    1089             :     AppIDsType app;
    1090             :     ContextIDsInfoType con;
    1091             :     int i = 0;
    1092             :     int j = 0;
    1093             : 
    1094           3 :     PRINT_FUNCTION_VERBOSE(verbose);
    1095             : 
    1096           3 :     if ((msg == NULL) || (msg->databuffer == NULL)) {
    1097           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1098           1 :         return DLT_RETURN_WRONG_PARAMETER;
    1099             :     }
    1100             : 
    1101           2 :     if (dlt_check_rcv_data_size(msg->datasize, sizeof(DltServiceGetLogInfoResponse)) < 0)
    1102             :         return DLT_RETURN_ERROR;
    1103             : 
    1104             :     /* if the request was send from gateway, clear all application and context list */
    1105           1 :     if (req == CONTROL_MESSAGE_REQUESTED) {
    1106             :         /* clear application list */
    1107           0 :         if (dlt_daemon_applications_clear(daemon, ecu, verbose) == DLT_RETURN_ERROR) {
    1108           0 :             dlt_log(LOG_ERR, "Cannot clear applications list\n");
    1109           0 :             return DLT_RETURN_ERROR;
    1110             :         }
    1111             : 
    1112             :         /* clear context list */
    1113           0 :         if (dlt_daemon_contexts_clear(daemon, ecu, verbose) == DLT_RETURN_ERROR) {
    1114           0 :             dlt_log(LOG_ERR, "Cannot clear contexts list\n");
    1115           0 :             return DLT_RETURN_ERROR;
    1116             :         }
    1117             :     }
    1118             : 
    1119             :     /* check response */
    1120           1 :     if (dlt_message_payload(msg,
    1121             :                             resp_text,
    1122             :                             DLT_RECEIVE_BUFSIZE,
    1123             :                             DLT_OUTPUT_ASCII, 0) != DLT_RETURN_OK) {
    1124           0 :         dlt_log(LOG_ERR, "GET_LOG_INFO payload failed\n");
    1125           0 :         return DLT_RETURN_ERROR;
    1126             :     }
    1127             : 
    1128             :     /* prepare pointer to message request */
    1129           1 :     resp = (DltServiceGetLogInfoResponse *)calloc(1, sizeof(DltServiceGetLogInfoResponse));
    1130             : 
    1131           1 :     if (resp == NULL) {
    1132           0 :         dlt_log(LOG_ERR,
    1133             :                 "Get Log Info Response could not be allocated\n");
    1134           0 :         return DLT_RETURN_ERROR;
    1135             :     }
    1136             : 
    1137           1 :     if (dlt_set_loginfo_parse_service_id(resp_text, &resp->service_id, &resp->status) != DLT_RETURN_OK) {
    1138           0 :         dlt_log(LOG_ERR, "Parsing GET_LOG_INFO failed\n");
    1139           0 :         dlt_client_cleanup_get_log_info(resp);
    1140           0 :         return DLT_RETURN_ERROR;
    1141             :     }
    1142             : 
    1143           1 :     if (dlt_client_parse_get_log_info_resp_text(resp, resp_text) != DLT_RETURN_OK) {
    1144           0 :         dlt_log(LOG_ERR, "Parsing GET_LOG_INFO failed\n");
    1145           0 :         dlt_client_cleanup_get_log_info(resp);
    1146           0 :         return DLT_RETURN_ERROR;
    1147             :     }
    1148             : 
    1149           2 :     for (i = 0; i < resp->log_info_type.count_app_ids; i++) {
    1150           1 :         app = resp->log_info_type.app_ids[i];
    1151             : 
    1152             :         /* add application */
    1153           1 :         if (dlt_daemon_application_add(daemon,
    1154             :                                        app.app_id,
    1155             :                                        0,
    1156             :                                        app.app_description,
    1157             :                                        -1,
    1158             :                                        ecu,
    1159             :                                        verbose) == 0) {
    1160           0 :             dlt_vlog(LOG_WARNING,
    1161             :                      "%s: dlt_daemon_application_add failed\n",
    1162             :                      __func__);
    1163           0 :             dlt_client_cleanup_get_log_info(resp);
    1164           0 :             return DLT_RETURN_ERROR;
    1165             :         }
    1166             : 
    1167           2 :         for (j = 0; j < app.count_context_ids; j++) {
    1168           1 :             con = app.context_id_info[j];
    1169             : 
    1170             :             /* add context */
    1171           1 :             if (dlt_daemon_context_add(daemon,
    1172             :                                        app.app_id,
    1173             :                                        con.context_id,
    1174           1 :                                        con.log_level,
    1175           1 :                                        con.trace_status,
    1176             :                                        0,
    1177             :                                        -1,
    1178             :                                        con.context_description,
    1179             :                                        ecu,
    1180             :                                        verbose) == 0) {
    1181           0 :                 dlt_vlog(LOG_WARNING,
    1182             :                          "%s: dlt_daemon_context_add failed for %4s\n",
    1183             :                          __func__,
    1184             :                          app.app_id);
    1185           0 :                 dlt_client_cleanup_get_log_info(resp);
    1186           0 :                 return DLT_RETURN_ERROR;
    1187             :             }
    1188             :         }
    1189             :     }
    1190             : 
    1191             :     /* free response */
    1192           1 :     dlt_client_cleanup_get_log_info(resp);
    1193             : 
    1194           1 :     return DLT_RETURN_OK;
    1195             : }
    1196             : 
    1197             : /**
    1198             :  * Parse GET_DEFAULT_LOG_LEVEL
    1199             :  *
    1200             :  * @param daemon          DltDaemon
    1201             :  * @param daemon_local    DltDaemonLocal
    1202             :  * @param ecu             Ecu ID
    1203             :  * @param msg             DltMessage
    1204             :  * @param verbose verbose flag
    1205             :  * @return 0 on success, -1 otherwise
    1206             :  */
    1207           0 : DLT_STATIC int dlt_gateway_parse_get_default_log_level(DltDaemon *daemon,
    1208             :                                                        DltDaemonLocal *daemon_local,
    1209             :                                                        char *ecu,
    1210             :                                                        DltMessage *msg,
    1211             :                                                        int verbose)
    1212             : {
    1213             :     DltServiceGetDefaultLogLevelResponse *resp = NULL;
    1214             :     DltGatewayConnection *con = NULL;
    1215             : 
    1216           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1217             : 
    1218           0 :     if ((daemon == NULL) || (daemon_local == NULL)) {
    1219           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1220           0 :         return DLT_RETURN_WRONG_PARAMETER;
    1221             :     }
    1222             : 
    1223           0 :     if (dlt_check_rcv_data_size(msg->datasize,
    1224             :                                 sizeof(DltServiceGetDefaultLogLevelResponse)) < 0) {
    1225           0 :         dlt_log(LOG_ERR, "Received data incomplete.\n");
    1226           0 :         return DLT_RETURN_ERROR;
    1227             :     }
    1228             : 
    1229             :     /* prepare pointer to message request */
    1230           0 :     resp = (DltServiceGetDefaultLogLevelResponse *)(msg->databuffer);
    1231             : 
    1232           0 :     con = dlt_gateway_get_connection(&daemon_local->pGateway,
    1233             :                                      ecu,
    1234             :                                      verbose);
    1235             : 
    1236           0 :     if (con == NULL) {
    1237           0 :         dlt_vlog(LOG_ERR, "No information about passive ECU: %s\n",
    1238             :                  ecu);
    1239             : 
    1240           0 :         return DLT_RETURN_ERROR;
    1241             :     }
    1242             : 
    1243           0 :     con->default_log_level = resp->log_level;
    1244             : 
    1245           0 :     return DLT_RETURN_OK;
    1246             : }
    1247             : 
    1248             : /**
    1249             :  * Service offline logstorage
    1250             :  *
    1251             :  * @param daemon       DltDaemon
    1252             :  * @param daemon_local DltDaemonLocal
    1253             :  * @param verbose      int
    1254             :  * @return 0 on success, -1 otherwise
    1255             :  */
    1256           1 : DLT_STATIC int dlt_gateway_control_service_logstorage(DltDaemon *daemon,
    1257             :                                                       DltDaemonLocal *daemon_local,
    1258             :                                                       int verbose)
    1259             : {
    1260             :     unsigned int connection_type = 0;
    1261             :     int i = 0;
    1262             : 
    1263           1 :     if (daemon_local->flags.offlineLogstorageMaxDevices <= 0) {
    1264           1 :         dlt_log(LOG_INFO,
    1265             :                 "Logstorage functionality not enabled or MAX device set is 0\n");
    1266           1 :         return DLT_RETURN_ERROR;
    1267             :     }
    1268             : 
    1269           0 :     for (i = 0; i < daemon_local->flags.offlineLogstorageMaxDevices; i++) {
    1270           0 :         connection_type = daemon->storage_handle[i].connection_type;
    1271             : 
    1272           0 :         if (connection_type == DLT_OFFLINE_LOGSTORAGE_DEVICE_CONNECTED)
    1273             :             /* Check if log level of running application needs an update */
    1274           0 :             dlt_daemon_logstorage_update_application_loglevel(daemon,
    1275             :                                                               daemon_local,
    1276             :                                                               i,
    1277             :                                                               verbose);
    1278             :     }
    1279             : 
    1280             :     return DLT_RETURN_OK;
    1281             : }
    1282             : 
    1283           5 : DltReturnValue dlt_gateway_process_passive_node_messages(DltDaemon *daemon,
    1284             :                                                          DltDaemonLocal *daemon_local,
    1285             :                                                          DltReceiver *receiver,
    1286             :                                                          int verbose)
    1287             : {
    1288             :     int i = 0;
    1289             :     DltGateway *gateway = NULL;
    1290             :     DltGatewayConnection *con = NULL;
    1291           5 :     DltMessage msg = { 0 };
    1292             :     bool b_reset_receiver = false;
    1293             : 
    1294           5 :     if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL)) {
    1295           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1296           1 :         return DLT_RETURN_WRONG_PARAMETER;
    1297             :     }
    1298             : 
    1299           4 :     PRINT_FUNCTION_VERBOSE(verbose);
    1300             : 
    1301             :     gateway = &daemon_local->pGateway;
    1302             : 
    1303             :     if (gateway == NULL) {
    1304             :         dlt_log(LOG_ERR, "Gateway structure is NULL\n");
    1305             :         return DLT_RETURN_ERROR;
    1306             :     }
    1307             : 
    1308           4 :     for (i = 0; i < gateway->num_connections; i++)
    1309           4 :         if ((gateway->connections[i].status == DLT_GATEWAY_CONNECTED) && (gateway->connections[i].client.sock == receiver->fd)) {
    1310             :             con = &gateway->connections[i];
    1311             :             break;
    1312             :         }
    1313             : 
    1314           4 :     if (con == NULL) {
    1315           0 :         dlt_log(LOG_ERR, "Cannot associate fd to passive Node connection\n");
    1316           0 :         return DLT_RETURN_ERROR;
    1317             :     }
    1318             : 
    1319             :     /* now the corresponding passive node connection is available */
    1320           4 :     if (dlt_message_init(&msg, verbose) == -1) {
    1321           0 :         dlt_log(LOG_ERR,
    1322             :                 "Cannot initialize DLT message for passive node forwarding\n");
    1323           0 :         return DLT_RETURN_ERROR;
    1324             :     }
    1325             : 
    1326             :     /* nearly copy and paste of dlt_client_main_loop function */
    1327           4 :     if (dlt_receiver_receive(receiver) <= 0) {
    1328             :         /* No more data to be received */
    1329           1 :         if (dlt_message_free(&msg, verbose) < 0) {
    1330           0 :             dlt_log(LOG_ERR, "Cannot free DLT message\n");
    1331           0 :             return DLT_RETURN_ERROR;
    1332             :         }
    1333             : 
    1334           1 :         dlt_log(LOG_WARNING, "Connection to passive node lost\n");
    1335             : 
    1336           1 :         if (con->reconnect_cnt < DLT_GATEWAY_RECONNECT_MAX) {
    1337           1 :             dlt_log(LOG_WARNING, "Try to reconnect.\n");
    1338           1 :             con->reconnect_cnt += 1;
    1339           1 :             con->timeout_cnt = 0;
    1340             :         }
    1341             :         else {
    1342           0 :             con->status = DLT_GATEWAY_DISCONNECTED;
    1343             : 
    1344           0 :             if (dlt_event_handler_unregister_connection(&daemon_local->pEvent,
    1345             :                                                         daemon_local,
    1346             :                                                         receiver->fd) != 0)
    1347           0 :                 dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
    1348             :         }
    1349             : 
    1350           1 :         return DLT_RETURN_OK;
    1351             :     }
    1352             : 
    1353          14 :     while (dlt_message_read(&msg,
    1354          14 :                             (unsigned char *)receiver->buf,
    1355          14 :                             receiver->bytesRcvd,
    1356             :                             0,
    1357          14 :                             verbose) == DLT_MESSAGE_ERROR_OK) {
    1358             :         DltStandardHeaderExtra *header = (DltStandardHeaderExtra *)
    1359             :             (msg.headerbuffer +
    1360             :              sizeof(DltStorageHeader) +
    1361             :              sizeof(DltStandardHeader));
    1362             : 
    1363             :         /* only forward messages if the received ECUid is the expected one */
    1364          11 :         if (strncmp(header->ecu, con->ecuid, DLT_ID_SIZE) == 0) {
    1365             :             uint32_t id;
    1366             :             uint32_t id_tmp;
    1367          11 :             DltPassiveControlMessage *control_msg = con->p_control_msgs;
    1368             : 
    1369          11 :             dlt_vlog(LOG_DEBUG,
    1370             :                      "Received ECUid (%.*s) similar to configured ECUid(%s). "
    1371             :                      "Forwarding message (%s).\n",
    1372             :                      DLT_ID_SIZE,
    1373             :                      header->ecu,
    1374             :                      con->ecuid,
    1375             :                      msg.databuffer);
    1376             : 
    1377          11 :             id_tmp = *((uint32_t *)(msg.databuffer));
    1378          11 :             id = DLT_ENDIAN_GET_32(msg.standardheader->htyp, id_tmp);
    1379             : 
    1380             :             /* if ID is GET_LOG_INFO, parse msg */
    1381          11 :             if (id == DLT_SERVICE_ID_GET_LOG_INFO) {
    1382           1 :                 while (control_msg) {
    1383           1 :                     if (control_msg->id == id) {
    1384           1 :                         if (dlt_gateway_parse_get_log_info(daemon,
    1385             :                                                            header->ecu,
    1386             :                                                            &msg,
    1387           1 :                                                            control_msg->req,
    1388             :                                                            verbose) == DLT_RETURN_ERROR)
    1389           1 :                             dlt_log(LOG_WARNING, "Parsing GET_LOG_INFO message failed!\n");
    1390             : 
    1391             :                         /* Check for logstorage */
    1392           1 :                         dlt_gateway_control_service_logstorage(daemon,
    1393             :                                                                daemon_local,
    1394             :                                                                verbose);
    1395             : 
    1396             :                         /* initialize the flag */
    1397           1 :                         control_msg->req = CONTROL_MESSAGE_NOT_REQUESTED;
    1398           1 :                         break;
    1399             :                     }
    1400             : 
    1401           0 :                     control_msg = control_msg->next;
    1402             :                 }
    1403             :             }
    1404          10 :             else if (id == DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL)
    1405             :             {
    1406           0 :                 if (dlt_gateway_parse_get_default_log_level(
    1407             :                         daemon,
    1408             :                         daemon_local,
    1409             :                         header->ecu,
    1410             :                         &msg,
    1411             :                         verbose) == DLT_RETURN_ERROR)
    1412           0 :                     dlt_log(LOG_WARNING,
    1413             :                             "Parsing GET_DEFAULT_LOG_LEVEL message failed!\n");
    1414             :             }
    1415             : 
    1416             :             /* prepare storage header */
    1417          11 :             if (dlt_set_storageheader(msg.storageheader,
    1418             :                                       msg.headerextra.ecu) == DLT_RETURN_ERROR) {
    1419           0 :                 dlt_vlog(LOG_ERR, "%s: Can't set storage header\n", __func__);
    1420           0 :                 return DLT_RETURN_ERROR;
    1421             :             }
    1422             : 
    1423          11 :             dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL,
    1424             :                                        daemon,
    1425             :                                        daemon_local,
    1426             :                                        msg.headerbuffer,
    1427             :                                        sizeof(DltStorageHeader),
    1428             :                                        msg.headerbuffer + sizeof(DltStorageHeader),
    1429          11 :                                        msg.headersize - sizeof(DltStorageHeader),
    1430          11 :                                        msg.databuffer,
    1431             :                                        msg.datasize,
    1432             :                                        verbose);
    1433             :         } else { /* otherwise remove this connection and do not connect again */
    1434           0 :             dlt_vlog(LOG_WARNING,
    1435             :                      "Received ECUid (%.*s) differs to configured ECUid(%s). "
    1436             :                      "Discard this message.\n",
    1437             :                      DLT_ID_SIZE,
    1438             :                      header->ecu,
    1439             :                      con->ecuid);
    1440             : 
    1441             :             /* disconnect from passive node */
    1442           0 :             con->status = DLT_GATEWAY_DISCONNECTED;
    1443           0 :             con->trigger = DLT_GATEWAY_DISABLED;
    1444             : 
    1445           0 :             if (dlt_event_handler_unregister_connection(&daemon_local->pEvent,
    1446             :                                                         daemon_local,
    1447             :                                                         receiver->fd)
    1448             :                 != 0)
    1449           0 :                 dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
    1450             : 
    1451           0 :             dlt_log(LOG_WARNING,
    1452             :                     "Disconnect from passive node due to invalid ECUid\n");
    1453             : 
    1454             :             /* it is possible that a partial log was received through the last recv call */
    1455             :             /* however, the rest will never be received since the socket will be closed by above method */
    1456             :             /* as such, we need to reset the receiver to prevent permanent corruption */
    1457             :             b_reset_receiver = true;
    1458             :         }
    1459             : 
    1460          11 :         if (msg.found_serialheader) {
    1461           0 :             if (dlt_receiver_remove(receiver,
    1462           0 :                                     msg.headersize +
    1463           0 :                                     msg.datasize -
    1464           0 :                                     sizeof(DltStorageHeader) +
    1465             :                                     sizeof(dltSerialHeader)) == -1) {
    1466             :                 /* Return value ignored */
    1467           0 :                 dlt_message_free(&msg, verbose);
    1468           0 :                 return DLT_RETURN_ERROR;
    1469             :             }
    1470             :         }
    1471          11 :         else if (dlt_receiver_remove(receiver,
    1472          11 :                                      msg.headersize +
    1473          11 :                                      msg.datasize -
    1474             :                                      sizeof(DltStorageHeader)) == -1) {
    1475             :             /* Return value ignored */
    1476           0 :             dlt_message_free(&msg, verbose);
    1477           0 :             return DLT_RETURN_ERROR;
    1478             :         }
    1479             :     }
    1480             : 
    1481           3 :     if (b_reset_receiver)
    1482           0 :         dlt_receiver_remove(receiver, receiver->bytesRcvd);
    1483             : 
    1484           3 :     if (dlt_receiver_move_to_begin(receiver) == -1) {
    1485             :         /* Return value ignored */
    1486           0 :         dlt_message_free(&msg, verbose);
    1487           0 :         return DLT_RETURN_ERROR;
    1488             :     }
    1489             : 
    1490           3 :     if (dlt_message_free(&msg, verbose) == -1)
    1491           0 :         return DLT_RETURN_ERROR;
    1492             : 
    1493             :     return DLT_RETURN_OK;
    1494             : }
    1495             : 
    1496           2 : int dlt_gateway_process_gateway_timer(DltDaemon *daemon,
    1497             :                                       DltDaemonLocal *daemon_local,
    1498             :                                       DltReceiver *receiver,
    1499             :                                       int verbose)
    1500             : {
    1501           2 :     uint64_t expir = 0;
    1502             :     ssize_t res = 0;
    1503             : 
    1504           2 :     PRINT_FUNCTION_VERBOSE(verbose);
    1505             : 
    1506           2 :     if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL)) {
    1507           1 :         dlt_vlog(LOG_ERR,
    1508             :                  "%s: invalid parameters\n",
    1509             :                  __func__);
    1510           1 :         return DLT_RETURN_WRONG_PARAMETER;
    1511             :     }
    1512             : 
    1513           1 :     res = read(receiver->fd, &expir, sizeof(expir));
    1514             : 
    1515           1 :     if (res < 0)
    1516           1 :         dlt_vlog(LOG_WARNING,
    1517             :                  "%s: Fail to read timer (%s)\n",
    1518             :                  __func__,
    1519           1 :                  strerror(errno));
    1520             :         /* Activity received on timer_wd, but unable to read the fd:
    1521             :          * let's go on sending notification */
    1522             : 
    1523             :     /* try to connect to passive nodes */
    1524           1 :     dlt_gateway_establish_connections(&daemon_local->pGateway,
    1525             :                                       daemon_local,
    1526             :                                       verbose);
    1527             : 
    1528           1 :     dlt_log(LOG_DEBUG, "Gateway Timer\n");
    1529             : 
    1530           1 :     return DLT_RETURN_OK;
    1531             : }
    1532             : 
    1533           0 : int dlt_gateway_forward_control_message(DltGateway *gateway,
    1534             :                                         DltDaemonLocal *daemon_local,
    1535             :                                         DltMessage *msg,
    1536             :                                         char *ecu,
    1537             :                                         int verbose)
    1538             : {
    1539             :     int i = 0;
    1540             :     int ret = 0;
    1541             :     DltGatewayConnection *con = NULL;
    1542             :     uint32_t id_tmp;
    1543             :     uint32_t id;
    1544             : 
    1545           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1546             : 
    1547           0 :     if ((gateway == NULL) || (daemon_local == NULL) || (msg == NULL) || (ecu == NULL)) {
    1548           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1549           0 :         return DLT_RETURN_WRONG_PARAMETER;
    1550             :     }
    1551             : 
    1552           0 :     for (i = 0; i < gateway->num_connections; i++)
    1553           0 :         if (strncmp(gateway->connections[i].ecuid,
    1554             :                     ecu,
    1555             :                     DLT_ID_SIZE) == 0) {
    1556             :             con = &gateway->connections[i];
    1557             :             break;
    1558             :         }
    1559             : 
    1560             : 
    1561             : 
    1562           0 :     if (con == NULL) {
    1563           0 :         dlt_log(LOG_WARNING, "Unknown passive node identifier\n");
    1564           0 :         return DLT_RETURN_ERROR;
    1565             :     }
    1566             : 
    1567           0 :     if (con->status != DLT_GATEWAY_CONNECTED) {
    1568           0 :         dlt_log(LOG_INFO, "Passive node is not connected\n");
    1569           0 :         return DLT_RETURN_ERROR;
    1570             :     }
    1571             : 
    1572           0 :     if (con->send_serial) { /* send serial header */
    1573           0 :         ret = send(con->client.sock,
    1574             :                    (void *)dltSerialHeader,
    1575             :                    sizeof(dltSerialHeader),
    1576             :                    0);
    1577             : 
    1578           0 :         if (ret == -1) {
    1579           0 :             dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
    1580           0 :             return DLT_RETURN_ERROR;
    1581             :         }
    1582             :     }
    1583             : 
    1584           0 :     ret = send(con->client.sock,
    1585             :                msg->headerbuffer + sizeof(DltStorageHeader),
    1586           0 :                msg->headersize - sizeof(DltStorageHeader),
    1587             :                0);
    1588             : 
    1589           0 :     if (ret == -1) {
    1590           0 :         dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
    1591           0 :         return DLT_RETURN_ERROR;
    1592             :     }
    1593             :     else {
    1594           0 :         ret = send(con->client.sock, msg->databuffer, msg->datasize, 0);
    1595             : 
    1596           0 :         if (ret == -1) {
    1597           0 :             dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
    1598           0 :             return DLT_RETURN_ERROR;
    1599             :         }
    1600             :     }
    1601             : 
    1602           0 :     id_tmp = *((uint32_t *)(msg->databuffer));
    1603           0 :     id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
    1604             : 
    1605           0 :     dlt_vlog(LOG_INFO,
    1606             :              "Control message forwarded : %s\n",
    1607             :              dlt_get_service_name(id));
    1608           0 :     return DLT_RETURN_OK;
    1609             : }
    1610             : 
    1611           3 : int dlt_gateway_process_on_demand_request(DltGateway *gateway,
    1612             :                                           DltDaemonLocal *daemon_local,
    1613             :                                           char node_id[DLT_ID_SIZE],
    1614             :                                           int connection_status,
    1615             :                                           int verbose)
    1616             : {
    1617             :     int i = 0;
    1618             :     DltGatewayConnection *con = NULL;
    1619             : 
    1620           3 :     PRINT_FUNCTION_VERBOSE(verbose);
    1621             : 
    1622           3 :     if ((gateway == NULL) || (daemon_local == NULL) || (node_id == NULL)) {
    1623           1 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1624           1 :         return DLT_RETURN_WRONG_PARAMETER;
    1625             :     }
    1626             : 
    1627             :     /* find connection by ECU id */
    1628           2 :     for (i = 0; i < gateway->num_connections; i++) {
    1629           2 :         if (strncmp(node_id, gateway->connections[i].ecuid, DLT_ID_SIZE) == 0) {
    1630             :             con = &gateway->connections[i];
    1631             :             break;
    1632             :         }
    1633             :     }
    1634             : 
    1635           2 :     if (con == NULL) {
    1636           0 :         dlt_log(LOG_WARNING, "Specified ECUid not found\n");
    1637           0 :         return DLT_RETURN_ERROR;
    1638             :     }
    1639             : 
    1640           2 :     if (connection_status == 1) { /* try to connect */
    1641             : 
    1642           2 :         if (con->status != DLT_GATEWAY_CONNECTED) {
    1643           1 :             if (dlt_client_connect(&con->client, verbose) == 0) {
    1644             :                 /* setup dlt connection and add to poll event loop here */
    1645           0 :                 if (dlt_gateway_add_to_event_loop(daemon_local, con, verbose) != DLT_RETURN_OK) {
    1646           0 :                     dlt_log(LOG_ERR, "Gateway connection creation failed\n");
    1647           0 :                     return DLT_RETURN_ERROR;
    1648             :                 }
    1649             :             }
    1650             :             else {
    1651           1 :                 dlt_log(LOG_ERR, "Could not connect to passive node\n");
    1652           1 :                 return DLT_RETURN_ERROR;
    1653             :             }
    1654             :         }
    1655             :         else {
    1656           1 :             dlt_log(LOG_INFO, "Passive node already connected\n");
    1657             :         }
    1658             :     }
    1659           0 :     else if (connection_status == 0) /* disconnect*/
    1660             :     {
    1661             : 
    1662           0 :         con->status = DLT_GATEWAY_DISCONNECTED;
    1663           0 :         con->trigger = DLT_GATEWAY_ON_DEMAND;
    1664             : 
    1665           0 :         if (dlt_event_handler_unregister_connection(&daemon_local->pEvent,
    1666             :                                                     daemon_local,
    1667             :                                                     con->client.sock) != 0)
    1668           0 :             dlt_log(LOG_ERR,
    1669             :                     "Remove passive node event handler connection failed\n");
    1670             :     }
    1671             :     else {
    1672           0 :         dlt_log(LOG_ERR, "Unknown command (connection_status)\n");
    1673           0 :         return DLT_RETURN_ERROR;
    1674             :     }
    1675             : 
    1676             :     return DLT_RETURN_OK;
    1677             : }
    1678             : 
    1679          12 : int dlt_gateway_send_control_message(DltGatewayConnection *con,
    1680             :                                      DltPassiveControlMessage *control_msg,
    1681             :                                      void *data,
    1682             :                                      int verbose)
    1683             : {
    1684             :     int ret = DLT_RETURN_OK;
    1685             : 
    1686          12 :     PRINT_FUNCTION_VERBOSE(verbose);
    1687             : 
    1688          12 :     if (con == NULL) {
    1689           1 :         dlt_vlog(LOG_WARNING,
    1690             :                  "%s: Invalid parameter given\n",
    1691             :                  __func__);
    1692           1 :         return DLT_RETURN_WRONG_PARAMETER;
    1693             :     }
    1694             : 
    1695             :     /* no (more) control message to be send */
    1696          11 :     if (control_msg->id == 0)
    1697             :         return DLT_RETURN_ERROR;
    1698             : 
    1699             :     /* check sendtime counter and message interval */
    1700             :     /* sendtime counter is 0 on startup, otherwise positive value */
    1701          11 :     if ((control_msg->type != CONTROL_MESSAGE_ON_DEMAND) && (con->sendtime_cnt > 0)) {
    1702           0 :         if (control_msg->interval <= 0)
    1703             :             return DLT_RETURN_ERROR;
    1704             : 
    1705           0 :         if ((control_msg->type == CONTROL_MESSAGE_PERIODIC) ||
    1706             :             (control_msg->type == CONTROL_MESSAGE_BOTH)) {
    1707           0 :             if ((con->sendtime_cnt - 1) % control_msg->interval != 0)
    1708             :                 return DLT_RETURN_ERROR;
    1709             :         }
    1710             :     }
    1711             : 
    1712          11 :     if (con->send_serial) { /* send serial header */
    1713           0 :         ret = send(con->client.sock,
    1714             :                    (void *)dltSerialHeader,
    1715             :                    sizeof(dltSerialHeader),
    1716             :                    0);
    1717             : 
    1718           0 :         if (ret == -1) {
    1719           0 :             dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
    1720           0 :             return DLT_RETURN_ERROR;
    1721             :         }
    1722             :     }
    1723             : 
    1724          11 :     switch (control_msg->id) {
    1725           4 :     case DLT_SERVICE_ID_GET_LOG_INFO:
    1726           4 :         return dlt_client_get_log_info(&con->client);
    1727             :         break;
    1728           1 :     case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
    1729           1 :         return dlt_client_get_default_log_level(&con->client);
    1730             :         break;
    1731           4 :     case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
    1732           4 :         return dlt_client_get_software_version(&con->client);
    1733             :         break;
    1734           2 :     case DLT_SERVICE_ID_SET_LOG_LEVEL:
    1735             : 
    1736           2 :         if (data == NULL) {
    1737           1 :             dlt_vlog(LOG_WARNING,
    1738             :                      "Insufficient data for %s received. Send control request failed.\n",
    1739             :                      dlt_get_service_name(control_msg->id));
    1740           1 :             return DLT_RETURN_ERROR;
    1741             :         }
    1742             : 
    1743             :         DltServiceSetLogLevel *req = (DltServiceSetLogLevel *)data;
    1744           1 :         return dlt_client_send_log_level(&con->client,
    1745           1 :                                          req->apid,
    1746           1 :                                          req->ctid,
    1747           1 :                                          req->log_level);
    1748             :         break;
    1749           0 :     default:
    1750           0 :         dlt_vlog(LOG_WARNING,
    1751             :                  "Cannot forward request: %s.\n",
    1752             :                  dlt_get_service_name(control_msg->id));
    1753             :     }
    1754             : 
    1755           0 :     return DLT_RETURN_OK;
    1756             : }
    1757             : 
    1758           0 : DltGatewayConnection *dlt_gateway_get_connection(DltGateway *gateway,
    1759             :                                                  char *ecu,
    1760             :                                                  int verbose)
    1761             : {
    1762             :     DltGatewayConnection *con = NULL;
    1763             :     int i = 0;
    1764             : 
    1765           0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1766             : 
    1767           0 :     if ((gateway == NULL) || (ecu == NULL)) {
    1768           0 :         dlt_vlog(LOG_ERR, "%s: wrong parameter\n", __func__);
    1769           0 :         return con;
    1770             :     }
    1771             : 
    1772           0 :     for (i = 0; i < gateway->num_connections; i++) {
    1773           0 :         con = &gateway->connections[i];
    1774             : 
    1775           0 :         if (strncmp(con->ecuid, ecu, DLT_ID_SIZE) == 0)
    1776           0 :             return con;
    1777             :     }
    1778             : 
    1779           0 :     dlt_vlog(LOG_ERR, "%s: No connection found\n", ecu);
    1780             : 
    1781           0 :     return con;
    1782             : }

Generated by: LCOV version 1.14