LCOV - code coverage report
Current view: top level - gateway - dlt_gateway.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 60.9 % 629 383
Test Date: 2025-03-25 20:53:42 Functions: 82.1 % 28 23

            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              :                 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              :                 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              :             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            4 : 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            4 :     DltMessage msg = { 0 };
    1292              :     bool b_reset_receiver = false;
    1293              : 
    1294            4 :     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            3 :     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            3 :     for (i = 0; i < gateway->num_connections; i++)
    1309            3 :         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            3 :     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            3 :     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            3 :     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           13 :     while (dlt_message_read(&msg,
    1354           13 :                             (unsigned char *)receiver->buf,
    1355           13 :                             receiver->bytesRcvd,
    1356              :                             0,
    1357           13 :                             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            2 :     if (b_reset_receiver)
    1482            0 :         dlt_receiver_remove(receiver, receiver->bytesRcvd);
    1483              : 
    1484            2 :     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            2 :     if (dlt_message_free(&msg, verbose) == -1)
    1491              :         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 2.0-1