summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--include/dlt/dlt_common.h40
-rw-r--r--include/dlt/dlt_protocol.h2
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/console/CMakeLists.txt6
-rw-r--r--src/console/dlt-passive-node-ctrl.c457
-rw-r--r--src/daemon/CMakeLists.txt2
-rw-r--r--src/daemon/dlt-daemon.c365
-rw-r--r--src/daemon/dlt-daemon.h26
-rw-r--r--src/daemon/dlt.conf5
-rw-r--r--src/daemon/dlt_daemon_client.c221
-rw-r--r--src/daemon/dlt_daemon_client.h26
-rw-r--r--src/daemon/dlt_daemon_connection.c24
-rw-r--r--src/daemon/dlt_daemon_connection_types.h6
-rw-r--r--src/daemon/dlt_daemon_event_handler.c9
-rw-r--r--src/daemon/dlt_daemon_event_handler_types.h1
-rw-r--r--src/gateway/CMakeLists.txt22
-rw-r--r--src/gateway/dlt_gateway.c1052
-rw-r--r--src/gateway/dlt_gateway.conf9
-rw-r--r--src/gateway/dlt_gateway.h169
-rw-r--r--src/gateway/dlt_gateway_types.h106
21 files changed, 2403 insertions, 147 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 32ff107..ccf2ba2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,6 +96,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/lib/
${CMAKE_SOURCE_DIR}/src/daemon/
${CMAKE_SOURCE_DIR}/src/console/
+ ${CMAKE_SOURCE_DIR}/src/gateway/
${CMAKE_SOURCE_DIR}/systemd/3rdparty/
)
diff --git a/include/dlt/dlt_common.h b/include/dlt/dlt_common.h
index 2083a18..c3a44d1 100644
--- a/include/dlt/dlt_common.h
+++ b/include/dlt/dlt_common.h
@@ -327,6 +327,10 @@ enum {
#define DLT_MOUNT_PATH_MAX 1024
/**
+ * Maximal length of an entry
+ */
+#define DLT_ENTRY_MAX 100
+/**
* The definition of the serial header containing the characters "DLS" + 0x01.
*/
extern const char dltSerialHeader[DLT_ID_SIZE];
@@ -565,6 +569,42 @@ typedef struct
} PACKED DltServiceOfflineLogstorage;
/**
+ * The structure of DLT Service Get Filter Config
+ */
+typedef struct
+{
+ uint32_t service_id; /**< service ID */
+ uint8_t status; /**< response status */
+ char name[DLT_ENTRY_MAX]; /**< config name */
+ uint32_t level; /**< filter level */
+ uint32_t client_mask; /**< client mask */
+ uint32_t ctrl_mask; /**< control message mask */
+ char injections[DLT_ENTRY_MAX]; /**< list of injections */
+} PACKED DltServiceGetCurrentFilterInfo;
+
+/**
+ * The structure of DLT Service Passive Node Connect
+ */
+typedef struct
+{
+ uint32_t service_id; /**< service ID */
+ uint32_t connection_status; /**< connect/disconnect */
+ char node_id[DLT_ID_SIZE]; /**< passive node ID */
+} PACKED DltServicePassiveNodeConnect;
+
+/**
+ * The structure of DLT Service Passive Node Connection Status
+ */
+typedef struct
+{
+ uint32_t service_id; /**< service ID */
+ uint8_t status; /**< response status */
+ uint32_t num_connections; /**< number of connections */
+ uint8_t connection_status[DLT_ENTRY_MAX]; /**< list of connection status */
+ char node_id[DLT_ENTRY_MAX]; /**< list of passive node IDs */
+} PACKED DltServicePassiveNodeConnectionInfo;
+
+/**
* Structure to store filter parameters.
* ID are maximal four characters. Unused values are filled with zeros.
* If every value as filter is valid, the id should be empty by having only zero values.
diff --git a/include/dlt/dlt_protocol.h b/include/dlt/dlt_protocol.h
index 3c8488a..4600d2e 100644
--- a/include/dlt/dlt_protocol.h
+++ b/include/dlt/dlt_protocol.h
@@ -199,6 +199,8 @@
#define DLT_SERVICE_ID_TIMEZONE 0xf03 /**< Service ID: Timezone */
#define DLT_SERVICE_ID_MARKER 0xf04 /**< Service ID: Marker */
#define DLT_SERVICE_ID_OFFLINE_LOGSTORAGE 0xf05 /**< Service ID: Offline log storage */
+#define DLT_SERVICE_ID_PASSIVE_NODE_CONNECT 0xf0E /**< Service ID: (Dis)Connect passive Node */
+#define DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS 0xf0F /**< Service ID: Passive Node status information */
#define DLT_SERVICE_ID_CALLSW_CINJECTION 0xFFF /**< Service ID: Message Injection (minimal ID) */
/*
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 23db5dd..6fd8a64 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,6 +17,7 @@
add_subdirectory( lib )
add_subdirectory( daemon )
+add_subdirectory( gateway )
if( WITH_DLT_CONSOLE )
add_subdirectory( console )
diff --git a/src/console/CMakeLists.txt b/src/console/CMakeLists.txt
index f0a036a..f2b7c30 100644
--- a/src/console/CMakeLists.txt
+++ b/src/console/CMakeLists.txt
@@ -33,6 +33,10 @@ set_target_properties(dlt-control PROPERTIES LINKER_LANGUAGE C)
set(dlt_control_common_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/dlt-control-common.c)
add_subdirectory( logstorage )
-install(TARGETS dlt-convert dlt-receive dlt-control
+set(dlt_passive_node_ctrl_SRCS dlt-passive-node-ctrl.c dlt-control-common.c)
+add_executable(dlt-passive-node-ctrl ${dlt_passive_node_ctrl_SRCS} ${dlt_most_SRCS})
+target_link_libraries(dlt-passive-node-ctrl dlt ${EXPAT_LIBRARIES})
+
+install(TARGETS dlt-convert dlt-receive dlt-control dlt-passive-node-ctrl
RUNTIME DESTINATION bin
COMPONENT base)
diff --git a/src/console/dlt-passive-node-ctrl.c b/src/console/dlt-passive-node-ctrl.c
new file mode 100644
index 0000000..db12085
--- /dev/null
+++ b/src/console/dlt-passive-node-ctrl.c
@@ -0,0 +1,457 @@
+/**
+ * @licence app begin@
+ * Copyright (C) 2015 Advanced Driver Information Technology.
+ * This code is developed by Advanced Driver Information Technology.
+ * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
+ *
+ * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
+ *
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Christoph Lipka <clipka@jp.adit-jv.com> ADIT 2015
+ *
+ * \file dlt-passive-node-ctrl.c
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt-passive-node-ctrl.c **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Christoph Lipka <clipka@jp.adit-jv.com> **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** CL Christoph Lipka ADIT **
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <pthread.h>
+#include "dlt_protocol.h"
+#include "dlt_client.h"
+#include "dlt-control-common.h"
+#include "dlt_daemon_connection_types.h"
+
+#define MAX_RESPONSE_LENGTH 32
+
+#define DLT_NODE_CONNECT 1
+#define DLT_NODE_DISCONNECT 0
+#define DLT_NODE_CONNECT_UNDEF 999
+
+#define DLT_GATEWAY_CONNECTED 2
+#define DLT_NODE_CONNECTED_STR "Connected"
+#define DLT_NODE_DISCONNECTED_STR "Disconnected"
+
+#define UNDEFINED 999
+
+static struct PassiveNodeOptions {
+ unsigned int command; /**< passive node control command */
+ unsigned int connection_state; /**< connection state */
+ char node_id[DLT_ID_SIZE]; /**< node identifier */
+ long timeout; /**< Default timeout */
+} g_options = {
+ .command = UNDEFINED,
+ .connection_state = UNDEFINED,
+ .node_id = {'\0'},
+};
+
+unsigned int get_command(void)
+{
+ return g_options.command;
+}
+
+void set_command(unsigned int c)
+{
+ g_options.command = c;
+}
+
+unsigned int get_connection_state(void)
+{
+ return g_options.connection_state;
+}
+
+void set_connection_state(unsigned int s)
+{
+ if ((s == DLT_NODE_CONNECT) || (s == DLT_NODE_DISCONNECT))
+ {
+ g_options.connection_state = s;
+ set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECT);
+ }
+ else
+ {
+ pr_error("Connection status %u invalid\n", s);
+ exit(-1);
+ }
+}
+
+void set_node_id(char *id)
+{
+ if (id == 0)
+ {
+ pr_error("node identifier is NULL\n");
+ exit(-1);
+ }
+ else
+ {
+ strncpy(g_options.node_id, id, DLT_ID_SIZE);
+ }
+}
+
+char *get_node_id()
+{
+ return g_options.node_id;
+}
+
+/**
+ * @brief Print passive node status information
+ *
+ * @param info DltServicePassiveNodeConnectionInfo
+ */
+static void dlt_print_passive_node_status(
+ DltServicePassiveNodeConnectionInfo *info)
+{
+ unsigned int i = 0;
+ char *status;
+
+ if (info == NULL)
+ {
+ return;
+ }
+
+ printf("\nPassive Node connection status:\n"
+ "---------------------------------\n");
+ for(i = 0; i < info->num_connections; i++)
+ {
+ if (info->connection_status[i] == DLT_GATEWAY_CONNECTED)
+ {
+ status = DLT_NODE_CONNECTED_STR;
+ }
+ else
+ {
+ status = DLT_NODE_DISCONNECTED_STR;
+ }
+
+ printf("%.4s: %s\n", &info->node_id[i * DLT_ID_SIZE], status);
+ }
+
+ printf("\n");
+}
+
+/**
+ * @brief Analyze received DLT Daemon response
+ *
+ * This function checks the received message. In particular, it checks the
+ * answer string 'service(<ID>, {ok, error, perm_denied})'. In any case the
+ * g_callback_return variable will be set as well which is evaluated in the
+ * main function after the communication thread returned.
+ *
+ * @param message Received DLT Message
+ * @return 0 if daemon returns 'ok' message, -1 otherwise
+ */
+static int dlt_passive_node_analyze_response(char *answer,
+ void *payload,
+ int len)
+{
+ int ret = -1;
+ char resp_ok[MAX_RESPONSE_LENGTH] = { 0 };
+
+ if (answer == NULL || payload == NULL)
+ {
+ return -1;
+ }
+
+ snprintf(resp_ok,
+ MAX_RESPONSE_LENGTH,
+ "service(%u), ok",
+ get_command());
+
+ pr_verbose("Response received: '%s'\n", answer);
+ pr_verbose("Response expected: '%s'\n", resp_ok);
+
+ if (strncmp(answer, resp_ok, strlen(resp_ok)) == 0)
+ {
+ ret = 0;
+
+ if (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS)
+ {
+ if ((int)sizeof(DltServicePassiveNodeConnectionInfo) > len)
+ {
+ pr_error("Received payload is smaller than expected\n");
+ pr_verbose("Expected: %lu,\nreceived: %d",
+ sizeof(DltServicePassiveNodeConnectionInfo),
+ len);
+ ret = -1;
+ }
+ else
+ {
+ DltServicePassiveNodeConnectionInfo *info =
+ (DltServicePassiveNodeConnectionInfo *) (payload);
+ if (info == NULL)
+ {
+ fprintf(stderr, "Received response is NULL\n");
+ return -1;
+ }
+
+ dlt_print_passive_node_status(info);
+ }
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Prepare message body to be send to DLT Daemon
+ *
+ * @return Pointer ot DltControlMsgBody, NULL otherwise
+ */
+DltControlMsgBody *dlt_passive_node_prepare_message_body()
+{
+ DltControlMsgBody *mb = calloc(1, sizeof(DltControlMsgBody));
+ char *ecuid = get_node_id();
+ if (mb == NULL)
+ {
+ return NULL;
+ }
+
+ if (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECT)
+ {
+ mb->data = calloc(1, sizeof(DltServicePassiveNodeConnect));
+ if (mb->data == NULL)
+ {
+ free(mb);
+ return NULL;
+ }
+ mb->size = sizeof(DltServicePassiveNodeConnect);
+ DltServicePassiveNodeConnect *serv = (DltServicePassiveNodeConnect *)
+ mb->data;
+ serv->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
+ serv->connection_status = get_connection_state();
+
+ memcpy(serv->node_id, ecuid, DLT_ID_SIZE);
+ }
+ else /* DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS */
+ {
+ mb->data = calloc(1, sizeof(DltServicePassiveNodeConnectionInfo));
+ if (mb->data == NULL)
+ {
+ free(mb);
+ return NULL;
+ }
+
+ mb->size = sizeof(DltServicePassiveNodeConnectionInfo);
+ DltServicePassiveNodeConnectionInfo *serv =
+ (DltServicePassiveNodeConnectionInfo *) mb->data;
+ serv->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS;
+ }
+
+ return mb;
+}
+
+/**
+ * @brief Destroy message body
+ */
+void dlt_passive_node_destroy_message_body(DltControlMsgBody *msg_body)
+{
+ if (msg_body == NULL)
+ {
+ return;
+ }
+
+ if (msg_body->data != NULL)
+ {
+ free(msg_body->data);
+ }
+ free(msg_body);
+}
+
+/**
+ * @brief Send a single command to DLT daemon and wait for response
+ *
+ * @return 0 on success, -1 on error
+ */
+static int dlt_passive_node_ctrl_single_request()
+{
+ int ret = -1;
+
+ /* Initializing the communication with the daemon */
+ if (dlt_control_init(dlt_passive_node_analyze_response,
+ get_ecuid(),
+ get_verbosity()) != 0)
+ {
+ pr_error("Failed to initialize connection with the daemon.\n");
+ return ret;
+ }
+
+ /* prepare message body */
+ DltControlMsgBody *msg_body = NULL;
+ msg_body = dlt_passive_node_prepare_message_body();
+
+ if (msg_body == NULL)
+ {
+ pr_error("Data for Dlt Message body is NULL\n");
+ return ret;
+ }
+
+ ret = dlt_control_send_message(msg_body, get_timeout());
+
+ dlt_passive_node_destroy_message_body(msg_body);
+
+ dlt_control_deinit();
+
+ return ret;
+}
+
+static void usage()
+{
+ printf("Usage: dlt-passive-node-ctrl [options]\n");
+ printf("Send a trigger to DLT daemon to (dis)connect a passive node "
+ "or get current passive node status \n");
+ printf("\n");
+ printf("Options:\n");
+ printf(" -c Connection status (1 - connect, 0 - disconnect)\n");
+ printf(" -h Usage\n");
+ printf(" -n passive Node identifier (e.g. ECU2)\n");
+ printf(" -s Show passive node(s) connection status\n");
+ printf(" -t Specify connection timeout (Default: %ds)\n",
+ DLT_CTRL_TIMEOUT);
+ printf(" -v Set verbose flag (Default:%d)\n", get_verbosity());
+}
+
+/**
+ * @brief Parse application arguments
+ *
+ * The arguments are parsed and saved in static structure for future use.
+ *
+ * @param argc amount of arguments
+ * @param argv argument table
+ * @return 0 on success, -1 otherwise
+ */
+static int parse_args(int argc, char *argv[])
+{
+ int c = 0;
+ int state = -1;
+
+ /* Get command line arguments */
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, "c:hn:stv")) != -1)
+ {
+ switch(c)
+ {
+ case 'c':
+ state = (int)strtol(optarg,NULL, 10);
+ if (state == DLT_NODE_CONNECT || state == DLT_NODE_DISCONNECT)
+ {
+ set_connection_state(state);
+ set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECT);
+ }
+ else
+ {
+ pr_error("unknown connection state: %d\n", state);
+ return -1;
+ }
+ break;
+ case 'h':
+ usage();
+ return -1;
+ case 'n':
+ set_node_id(optarg);
+ break;
+ case 's':
+ set_command(DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS);
+ break;
+ case 't':
+ set_timeout(strtol(optarg, NULL, 10));
+ break;
+ case 'v':
+ set_verbosity(1);
+ pr_verbose("Now in verbose mode.\n");
+ break;
+ case '?':
+ if (isprint(optopt))
+ {
+ pr_error("Unknown option -%c.\n", optopt);
+ }
+ else
+ {
+ pr_error("Unknown option character \\x%x.\n", optopt);
+ }
+ usage();
+ return -1;
+ default:
+ pr_error("Try %s -h for more information.\n", argv[0]);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Entry point
+ *
+ * Execute the argument parser and call the main feature accordingly
+ *
+ * @param argc amount of arguments
+ * @param argv argument table
+ * @return 0 on success, -1 otherwise
+ */
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+
+ set_ecuid(DLT_CTRL_DEFAULT_ECUID);
+ set_timeout(DLT_CTRL_TIMEOUT);
+
+ /* Get command line arguments */
+ if (parse_args(argc, argv) != 0)
+ {
+ return -1;
+ }
+
+ if (get_command() == UNDEFINED ||
+ (get_command() == DLT_SERVICE_ID_PASSIVE_NODE_CONNECT &&
+ g_options.node_id[0] == '\0' &&
+ g_options.connection_state == DLT_NODE_CONNECT_UNDEF))
+ {
+ pr_error("No valid parameter configuration given!\n");
+ usage();
+ return -1;
+ }
+
+ pr_verbose("Sending command to DLT daemon.\n");
+
+ /* one shot request */
+ ret = dlt_passive_node_ctrl_single_request();
+
+ pr_verbose("Exiting.\n");
+
+ return ret;
+}
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index 128dbe8..7a04b64 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -20,7 +20,7 @@ if(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD)
message( STATUS "Added ${systemd_SRCS} to dlt-daemon")
endif(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD)
-set(dlt_daemon_SRCS dlt-daemon.c dlt_daemon_common.c dlt_daemon_connection.c dlt_daemon_event_handler.c dlt_daemon_socket.c dlt_daemon_unix_socket.c dlt_daemon_serial.c dlt_daemon_client.c dlt_daemon_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_offline_trace.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_config_file_parser.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage_behavior.c)
+set(dlt_daemon_SRCS dlt-daemon.c dlt_daemon_common.c dlt_daemon_connection.c dlt_daemon_event_handler.c ${CMAKE_SOURCE_DIR}/src/gateway/dlt_gateway.c dlt_daemon_socket.c dlt_daemon_unix_socket.c dlt_daemon_serial.c dlt_daemon_client.c dlt_daemon_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_offline_trace.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage.c ${CMAKE_SOURCE_DIR}/src/lib/dlt_client.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_config_file_parser.c ${CMAKE_SOURCE_DIR}/src/offlinelogstorage/dlt_offline_logstorage_behavior.c)
add_executable(dlt-daemon ${dlt_daemon_SRCS} ${systemd_SRCS})
target_link_libraries(dlt-daemon rt ${CMAKE_THREAD_LIBS_INIT})
diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c
index 79be6ba..c8af773 100644
--- a/src/daemon/dlt-daemon.c
+++ b/src/daemon/dlt-daemon.c
@@ -64,6 +64,7 @@
#include "dlt_daemon_connection.h"
#include "dlt_daemon_event_handler.h"
#include "dlt_daemon_offline_logstorage.h"
+#include "dlt_gateway.h"
#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
#include "sd-daemon.h"
@@ -246,6 +247,7 @@ int option_file_parser(DltDaemonLocal *daemon_local)
strncpy(daemon_local->flags.ctrlSockPath,
DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH,
sizeof(daemon_local->flags.ctrlSockPath) - 1);
+ daemon_local->flags.gatewayMode = 0;
/* open configuration file */
if(daemon_local->flags.cvalue[0])
@@ -482,6 +484,11 @@ int option_file_parser(DltDaemonLocal *daemon_local)
value,
DLT_DAEMON_FLAG_MAX-1);
}
+ else if(strcmp(token,"GatewayMode")==0)
+ {
+ daemon_local->flags.gatewayMode = atoi(value);
+ //printf("Option: %s=%s\n",token,value);
+ }
else
{
fprintf(stderr, "Unknown option: %s=%s\n",token,value);
@@ -631,6 +638,22 @@ int main(int argc, char* argv[])
DLT_TIMER_ECU);
}
+ /* initiate gateway */
+ if (daemon_local.flags.gatewayMode == 1)
+ {
+ if (dlt_gateway_init(&daemon_local, daemon_local.flags.vflag) == -1)
+ {
+ dlt_log(LOG_CRIT, "Fail to create gateway\n");
+ return -1;
+ }
+
+ /* create gateway timer */
+ create_timer_fd(&daemon_local,
+ DLT_GATEWAY_TIMER_INTERVAL,
+ DLT_GATEWAY_TIMER_INTERVAL,
+ &daemon_local.timer_gateway.fd,
+ DLT_TIMER_GATEWAY);
+ }
if (dlt_connection_create_remaining(&daemon_local) == -1)
{
/* TODO: Perform clean-up */
@@ -656,7 +679,6 @@ int main(int argc, char* argv[])
&daemon_local);
}
-
dlt_daemon_log_internal(&daemon, &daemon_local, "Exiting Daemon...", daemon_local.flags.vflag);
dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
@@ -1409,7 +1431,10 @@ int dlt_daemon_log_internal(DltDaemon *daemon, DltDaemonLocal *daemon_local, cha
return 0;
}
-int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+int dlt_daemon_process_client_connect(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
+ int verbose)
{
socklen_t cli_size;
struct sockaddr cli;
@@ -1418,31 +1443,40 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (daemon_local==0))
+ if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
{
- dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
+ dlt_log(LOG_ERR,
+ "Invalid function parameters used for function "
+ "dlt_daemon_process_client_connect()\n");
return -1;
}
/* event from TCP server socket, new connection */
cli_size = sizeof(cli);
- if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
+ if ((in_sock = accept(receiver->fd,&cli, &cli_size)) < 0)
{
dlt_log(LOG_ERR, "accept() failed!\n");
return -1 ;
}
- /* check if file file descriptor was already used, and make it invalid if it is reused */
+ /* check if file file descriptor was already used, and make it invalid if it
+ * is reused. */
/* This prevents sending messages to wrong file descriptor */
- dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
- dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
+ dlt_daemon_applications_invalidate_fd(daemon, in_sock, verbose);
+ dlt_daemon_contexts_invalidate_fd(daemon, in_sock, verbose);
/* Set socket timeout in reception */
struct timeval timeout_send;
timeout_send.tv_sec = daemon_local->timeoutOnSend;
timeout_send.tv_usec = 0;
- if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0)
+ if (setsockopt (in_sock,
+ SOL_SOCKET,
+ SO_SNDTIMEO,
+ (char *)&timeout_send,
+ sizeof(timeout_send)) < 0)
+ {
dlt_log(LOG_WARNING, "setsockopt failed\n");
+ }
if (dlt_connection_create(daemon_local,
&daemon_local->pEvent,
@@ -1457,26 +1491,42 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_
if (daemon_local->flags.vflag)
{
- snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
+ snprintf(str,
+ DLT_DAEMON_TEXTBUFSIZE,
+ "New connection to client established, #connections: %d\n",
+ daemon_local->client_connections);
dlt_log(LOG_INFO, str);
}
// send connection info about connected
- dlt_daemon_control_message_connection_info(in_sock,daemon,daemon_local,DLT_CONNECTION_STATUS_CONNECTED,"",verbose);
+ dlt_daemon_control_message_connection_info(in_sock,
+ daemon,
+ daemon_local,
+ DLT_CONNECTION_STATUS_CONNECTED,
+ "",
+ verbose);
// send ecu version string
- if(daemon_local->flags.sendECUSoftwareVersion > 0)
+ if (daemon_local->flags.sendECUSoftwareVersion > 0)
{
- if(daemon_local->flags.sendECUSoftwareVersion > 0)
- dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local, daemon_local->flags.vflag);
+ if (daemon_local->flags.sendECUSoftwareVersion > 0)
+ {
+ dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL,
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag);
+ }
- if(daemon_local->flags.sendTimezone > 0)
+ if (daemon_local->flags.sendTimezone > 0)
{
- dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,daemon_local->flags.vflag);
+ dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag);
}
}
- if (daemon_local->client_connections==1)
+ if (daemon_local->client_connections == 1)
{
if (daemon_local->flags.vflag)
{
@@ -1497,25 +1547,30 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_
return 0;
}
-int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+int dlt_daemon_process_client_messages(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
+ int verbose)
{
int bytes_to_be_removed=0;
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (daemon_local==0))
+ if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
{
- dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
+ dlt_log(LOG_ERR,
+ "Invalid function parameters used for function "
+ "dlt_daemon_process_client_messages()\n");
return -1;
}
- if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
+ if (dlt_receiver_receive_socket(receiver) <= 0)
{
- dlt_daemon_close_socket(daemon_local->receiverSock.fd,
+ dlt_daemon_close_socket(receiver->fd,
daemon,
daemon_local,
verbose);
- daemon_local->receiverSock.fd = -1;
+ receiver->fd = -1;
/* FIXME: Why the hell do we need to close the socket
* on control message reception ??
*/
@@ -1523,15 +1578,26 @@ int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon
}
/* Process all received messages */
- while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==DLT_MESSAGE_ERROR_OK)
+ while (dlt_message_read(&(daemon_local->msg),
+ (uint8_t*)receiver->buf,
+ receiver->bytesRcvd,
+ daemon_local->flags.nflag,
+ daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
{
/* Check for control message */
- if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
+ if (0 < receiver->fd &&
+ DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
{
- dlt_daemon_client_process_control(daemon_local->receiverSock.fd, daemon,daemon_local, &(daemon_local->msg), daemon_local->flags.vflag);
+ dlt_daemon_client_process_control(receiver->fd,
+ daemon,
+ daemon_local,
+ &(daemon_local->msg),
+ daemon_local->flags.vflag);
}
- bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
+ bytes_to_be_removed = daemon_local->msg.headersize +
+ daemon_local->msg.datasize -
+ sizeof(DltStorageHeader);
if (daemon_local->msg.found_serialheader)
{
bytes_to_be_removed += sizeof(dltSerialHeader);
@@ -1541,56 +1607,76 @@ int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon
bytes_to_be_removed += daemon_local->msg.resync_offset;
}
- if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed) == DLT_RETURN_ERROR)
+ if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1)
{
- dlt_log(LOG_WARNING,"Can't remove bytes from receiver for sockets\n");
+ dlt_log(LOG_WARNING,
+ "Can't remove bytes from receiver for sockets\n");
return -1;
}
} /* while */
-
- if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock)) == DLT_RETURN_ERROR)
+ if (dlt_receiver_move_to_begin(receiver) == -1)
{
- dlt_log(LOG_WARNING,"Can't move bytes to beginning of receiver buffer for sockets\n");
+ dlt_log(LOG_WARNING,
+ "Can't move bytes to beginning of receiver buffer for sockets\n");
return -1;
}
return 0;
}
-int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+int dlt_daemon_process_client_messages_serial(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
+ int verbose)
{
int bytes_to_be_removed=0;
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (daemon_local==0))
+ if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
{
- dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
+ dlt_log(LOG_ERR,
+ "Invalid function parameters used for function "
+ "dlt_daemon_process_client_messages_serial()\n");
return -1;
}
- if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
+ if (dlt_receiver_receive_fd(receiver) <= 0)
{
- dlt_log(LOG_WARNING, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
+ dlt_log(LOG_WARNING,
+ "dlt_receiver_receive_fd() for messages from serial interface "
+ "failed!\n");
return -1;
}
/* Process all received messages */
- while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==DLT_MESSAGE_ERROR_OK)
+ while (dlt_message_read(&(daemon_local->msg),
+ (uint8_t*)receiver->buf,
+ receiver->bytesRcvd,
+ daemon_local->flags.mflag,
+ daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
{
/* Check for control message */
if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
{
- if (dlt_daemon_client_process_control(daemon_local->receiverSerial.fd, daemon,daemon_local, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_client_process_control(receiver->fd,
+ daemon,
+ daemon_local,
+ &(daemon_local->msg),
+ daemon_local->flags.vflag)
+ == -1)
{
- dlt_log(LOG_WARNING,"Can't process control messages\n");
+ dlt_log(LOG_WARNING, "Can't process control messages\n");
return -1;
}
}
- bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
+ bytes_to_be_removed = daemon_local->msg.headersize +
+ daemon_local->msg.datasize -
+ sizeof(DltStorageHeader);
+
if (daemon_local->msg.found_serialheader)
{
bytes_to_be_removed += sizeof(dltSerialHeader);
@@ -1600,18 +1686,20 @@ int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal
bytes_to_be_removed += daemon_local->msg.resync_offset;
}
- if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed) == DLT_RETURN_ERROR)
+ if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1)
{
- dlt_log(LOG_WARNING,"Can't remove bytes from receiver for serial connection\n");
+ dlt_log(LOG_WARNING,
+ "Can't remove bytes from receiver for serial connection\n");
return -1;
}
} /* while */
-
- if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial)) == DLT_RETURN_ERROR)
+ if (dlt_receiver_move_to_begin(receiver) == -1)
{
- dlt_log(LOG_WARNING,"Can't move bytes to beginning of receiver buffer for serial connection\n");
+ dlt_log(LOG_WARNING,
+ "Can't move bytes to beginning of receiver buffer for serial "
+ "connection\n");
return -1;
}
@@ -1621,6 +1709,7 @@ int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal
int dlt_daemon_process_control_connect(
DltDaemon *daemon,
DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
int verbose)
{
socklen_t ctrl_size;
@@ -1629,24 +1718,27 @@ int dlt_daemon_process_control_connect(
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (daemon_local==0))
+ if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
{
- dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_control_connect()\n");
+ dlt_log(LOG_ERR,
+ "Invalid function parameters used for function "
+ "dlt_daemon_process_control_connect()\n");
return -1;
}
/* event from UNIX server socket, new connection */
ctrl_size = sizeof(ctrl);
- if ((in_sock = accept(daemon_local->ctrlsock, &ctrl, &ctrl_size)) < 0)
+ if ((in_sock = accept(receiver->fd, &ctrl, &ctrl_size)) < 0)
{
dlt_log(LOG_ERR, "accept() on UNIX socket failed!\n");
return -1 ;
}
- /* check if file file descriptor was already used, and make it invalid if it is reused */
+ /* check if file file descriptor was already used, and make it invalid if it
+ * is reused */
/* This prevents sending messages to wrong file descriptor */
- dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
- dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
+ dlt_daemon_applications_invalidate_fd(daemon, in_sock, verbose);
+ dlt_daemon_contexts_invalidate_fd(daemon, in_sock, verbose);
if (dlt_connection_create(daemon_local,
&daemon_local->pEvent,
@@ -1661,8 +1753,8 @@ int dlt_daemon_process_control_connect(
if (verbose)
{
- snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "New connection to client established, #connections: %d\n",
- daemon_local->client_connections);
+ snprintf(str,DLT_DAEMON_TEXTBUFSIZE,
+ "New connection to control client established\n");
dlt_log(LOG_INFO, str);
}
@@ -1673,25 +1765,28 @@ int dlt_daemon_process_control_connect(
int dlt_daemon_process_control_messages(
DltDaemon *daemon,
DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
int verbose)
{
int bytes_to_be_removed=0;
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (daemon_local==0))
+ if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
{
- dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_control_messages()\n");
+ dlt_log(LOG_ERR,
+ "Invalid function parameters used for function "
+ "dlt_daemon_process_control_messages()\n");
return -1;
}
- if (dlt_receiver_receive_socket(&(daemon_local->receiverCtrlSock)) <= 0)
+ if (dlt_receiver_receive_socket(receiver) <= 0)
{
- dlt_daemon_close_socket(daemon_local->receiverCtrlSock.fd,
+ dlt_daemon_close_socket(receiver->fd,
daemon,
daemon_local,
verbose);
- daemon_local->receiverCtrlSock.fd = -1;
+ receiver->fd = -1;
/* FIXME: Why the hell do we need to close the socket
* on control message reception ??
*/
@@ -1701,25 +1796,24 @@ int dlt_daemon_process_control_messages(
/* Process all received messages */
while (dlt_message_read(
&(daemon_local->msg),
- (uint8_t*)daemon_local->receiverCtrlSock.buf,
- daemon_local->receiverCtrlSock.bytesRcvd,
+ (uint8_t*)receiver->buf,
+ receiver->bytesRcvd,
daemon_local->flags.nflag,
daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
{
/* Check for control message */
- if (daemon_local->receiverCtrlSock.fd > 0 &&
+ if (receiver->fd > 0 &&
DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
{
- dlt_daemon_client_process_control(
- daemon_local->receiverCtrlSock.fd,
- daemon,daemon_local,
- &(daemon_local->msg),
- daemon_local->flags.vflag);
+ dlt_daemon_client_process_control(receiver->fd,
+ daemon,daemon_local,
+ &(daemon_local->msg),
+ daemon_local->flags.vflag);
}
- bytes_to_be_removed =
- daemon_local->msg.headersize+daemon_local->msg.datasize -
- sizeof(DltStorageHeader);
+ bytes_to_be_removed = daemon_local->msg.headersize +
+ daemon_local->msg.datasize -
+ sizeof(DltStorageHeader);
if (daemon_local->msg.found_serialheader)
{
@@ -1730,16 +1824,16 @@ int dlt_daemon_process_control_messages(
bytes_to_be_removed += daemon_local->msg.resync_offset;
}
- if (dlt_receiver_remove(&(daemon_local->receiverCtrlSock),bytes_to_be_removed)==-1)
+ if (dlt_receiver_remove(receiver, bytes_to_be_removed) == -1)
{
- dlt_log(LOG_WARNING,"Can't remove bytes from receiver for sockets\n");
+ dlt_log(LOG_WARNING,
+ "Can't remove bytes from receiver for sockets\n");
return -1;
}
} /* while */
-
- if (dlt_receiver_move_to_begin(&(daemon_local->receiverCtrlSock)) == -1)
+ if (dlt_receiver_move_to_begin(receiver) == -1)
{
dlt_log(LOG_WARNING,"Can't move bytes to beginning of receiver buffer for sockets\n");
return -1;
@@ -1748,40 +1842,46 @@ int dlt_daemon_process_control_messages(
return 0;
}
-int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+int dlt_daemon_process_user_messages(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
+ int verbose)
{
- int offset=0;
- int run_loop=1;
+ int offset = 0;
+ int run_loop = 1;
DltUserHeader *userheader;
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (daemon_local==0))
+ if ((daemon == NULL) || (daemon_local == NULL) || (receiver == NULL))
{
- dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
+ dlt_log(LOG_ERR,
+ "Invalid function parameters used for function "
+ "dlt_daemon_process_user_messages()\n");
return -1;
}
/* read data from FIFO */
- if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
+ if (dlt_receiver_receive_fd(receiver) < 0)
{
- dlt_log(LOG_WARNING, "dlt_receiver_receive_fd() for user messages failed!\n");
+ dlt_log(LOG_WARNING,
+ "dlt_receiver_receive_fd() for user messages failed!\n");
return -1;
}
/* look through buffer as long as data is in there */
do
{
- if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
+ if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
{
break;
}
/* resync if necessary */
- offset=0;
+ offset = 0;
do
{
- userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
+ userheader = (DltUserHeader*) (receiver->buf+offset);
/* Check for user header pattern */
if (dlt_user_check_userheader(userheader))
@@ -1790,88 +1890,111 @@ int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_l
}
offset++;
-
- }
- while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
+ } while ((int32_t)(sizeof(DltUserHeader) + offset) <=
+ receiver->bytesRcvd);
/* Check for user header pattern */
- if (dlt_user_check_userheader(userheader)==0)
+ if (dlt_user_check_userheader(userheader) == 0)
{
break;
}
/* Set new start offset */
- if (offset>0)
+ if (offset > 0)
{
- daemon_local->receiver.buf+=offset;
- daemon_local->receiver.bytesRcvd-=offset;
+ receiver->buf += offset;
+ receiver->bytesRcvd -= offset;
}
switch (userheader->message)
{
case DLT_USER_MESSAGE_OVERFLOW:
{
- if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_overflow(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
case DLT_USER_MESSAGE_REGISTER_CONTEXT:
{
- if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_register_context(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
{
- if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_unregister_context(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
case DLT_USER_MESSAGE_LOG:
{
- if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_log(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
#ifdef DLT_SHM_ENABLE
case DLT_USER_MESSAGE_LOG_SHM:
{
- if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_log_shm(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
#endif
case DLT_USER_MESSAGE_REGISTER_APPLICATION:
{
- if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_register_application(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
{
- if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_unregister_application(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
case DLT_USER_MESSAGE_APP_LL_TS:
{
- if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_set_app_ll_ts(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
@@ -1885,26 +2008,34 @@ int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_l
}
case DLT_USER_MESSAGE_MARKER:
{
- if (dlt_daemon_process_user_message_marker(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ if (dlt_daemon_process_user_message_marker(
+ daemon,
+ daemon_local,
+ daemon_local->flags.vflag) == -1)
{
- run_loop=0;
+ run_loop = 0;
}
break;
}
default:
{
- snprintf(str, DLT_DAEMON_TEXTBUFSIZE, "Invalid user message type received: %d!\n", userheader->message);
+ snprintf(str,
+ DLT_DAEMON_TEXTBUFSIZE,
+ "Invalid user message type received: %d!\n",
+ userheader->message);
dlt_log(LOG_ERR,str);
/* remove user header */
- if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)) == DLT_RETURN_ERROR)
+ if (dlt_receiver_remove(receiver, sizeof(DltUserHeader)) == -1)
{
- dlt_log(LOG_WARNING,"Can't remove bytes from receiver for user messages\n");
+ dlt_log(LOG_WARNING,
+ "Can't remove bytes from receiver for user messages\n");
return -1;
}
- /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
- run_loop=0;
+ /* In next invocation of do-while loop, a resync will be triggered
+ * if additional data was received */
+ run_loop = 0;
break;
}
@@ -1914,9 +2045,11 @@ int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_l
while (run_loop);
/* keep not read data in buffer */
- if (dlt_receiver_move_to_begin(&(daemon_local->receiver)) == DLT_RETURN_ERROR)
+ if (dlt_receiver_move_to_begin(receiver) == -1)
{
- dlt_log(LOG_WARNING,"Can't move bytes to beginning of receiver buffer for user messages\n");
+ dlt_log(LOG_WARNING,
+ "Can't move bytes to beginning of receiver buffer for user "
+ "messages\n");
return -1;
}
diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h
index 02a55b3..2dffcc9 100644
--- a/src/daemon/dlt-daemon.h
+++ b/src/daemon/dlt-daemon.h
@@ -75,7 +75,7 @@
#include "dlt_user_shared.h"
#include "dlt_user_shared_cfg.h"
#include "dlt_daemon_event_handler_types.h"
-
+#include "dlt_gateway_types.h"
#include <dlt_offline_trace.h>
#include <sys/time.h>
@@ -123,8 +123,8 @@ typedef struct
char daemonFifoName[NAME_MAX + 1]; /**< (String: Filename) name of local fifo (Default: /tmp/dlt) */
unsigned int port; /**< port number */
char ctrlSockPath[DLT_DAEMON_FLAG_MAX]; /**< Path to Control socket */
+ int gatewayMode; /**< (Boolean) Gateway Mode */
} DltDaemonFlags;
-
/**
* The global parameters of a dlt daemon.
*/
@@ -137,6 +137,7 @@ typedef struct
int ctrlsock; /**< handle for control socket connection */
DltFile file; /**< struct for file access */
DltEventHandler pEvent; /**< struct for message producer event handling */
+ DltGateway pGateway; /**< struct for passive node connection handling */
DltMessage msg; /**< one dlt message */
DltReceiver receiver; /**< receiver for fifo connection */
DltReceiver receiverSock; /**< receiver for socket connection */
@@ -157,6 +158,7 @@ typedef struct
#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
DltReceiver timer_wd; /**< file descriptor for watchdog timer */
#endif
+ DltReceiver timer_gateway; /**< timer for gateway reconnection handling */
} DltDaemonLocal;
typedef struct
@@ -188,16 +190,16 @@ int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_
void dlt_daemon_daemonize(int verbose);
void dlt_daemon_signal_handler(int sig);
-int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_process_one_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_process_systemd_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-
-int dlt_daemon_process_control_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local,int verbose);
-int dlt_daemon_process_control_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local,int verbose);
+int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *revc, int verbose);
+int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+int dlt_daemon_process_one_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+int dlt_daemon_process_systemd_timer(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+
+int dlt_daemon_process_control_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
+int dlt_daemon_process_control_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, DltReceiver *recv, int verbose);
int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
diff --git a/src/daemon/dlt.conf b/src/daemon/dlt.conf
index 5deec60..aab9c7d 100644
--- a/src/daemon/dlt.conf
+++ b/src/daemon/dlt.conf
@@ -24,6 +24,9 @@ SendContextRegistration = 1
# Set ECU ID (Default: ECU1)
ECUId = ECU1
+# Enable Gateway mode (Default: 0)
+# GatewayMode = 1
+
# Size of shared memory (Default: 100000)
SharedMemorySize = 100000
@@ -147,4 +150,4 @@ ControlSocketPath = /tmp/dlt-ctrl.sock
# OfflineLogstorageMaxCounter = 999
# Maximal used memory for Logstorage Cache in KB (Default: 30000 KB)
-# OfflineLogstorageCacheSize = 30000 \ No newline at end of file
+# OfflineLogstorageCacheSize = 30000
diff --git a/src/daemon/dlt_daemon_client.c b/src/daemon/dlt_daemon_client.c
index 7658787..a96c329 100644
--- a/src/daemon/dlt_daemon_client.c
+++ b/src/daemon/dlt_daemon_client.c
@@ -62,6 +62,8 @@
#include "dlt_daemon_connection.h"
#include "dlt_daemon_offline_logstorage.h"
+#include "dlt_gateway.h"
+
/** Global text output buffer, mainly used for creation of error/warning strings */
static char str[DLT_DAEMON_TEXTBUFSIZE];
@@ -402,10 +404,11 @@ int dlt_daemon_client_send_control_message( int sock, DltDaemon *daemon, DltDaem
int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose)
{
uint32_t id,id_tmp=0;
+ DltStandardHeaderExtra extra;
PRINT_FUNCTION_VERBOSE(verbose);
- if ((daemon==0) || (msg==0))
+ if (daemon == NULL || daemon_local == NULL|| msg == NULL)
{
return -1;
}
@@ -415,10 +418,24 @@ int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLoca
return -1;
}
+ extra = msg->headerextra;
+
+ /* check if the message needs to be forwarded */
+ if (daemon_local->flags.gatewayMode == 1)
+ {
+ if (strcmp(daemon_local->flags.evalue, extra.ecu) != 0)
+ {
+ return dlt_gateway_forward_control_message(&daemon_local->pGateway,
+ daemon_local,
+ msg,
+ extra.ecu,
+ verbose);
+ }
+ }
id_tmp = *((uint32_t*)(msg->databuffer));
id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
- if ((id > 0) && ((id < DLT_SERVICE_ID_LAST_ENTRY) || ((id == DLT_SERVICE_ID_OFFLINE_LOGSTORAGE))))
+ if ((id > 0) && (id != DLT_SERVICE_ID_CALLSW_CINJECTION))
{
/* Control message handling */
switch (id)
@@ -546,6 +563,23 @@ int dlt_daemon_client_process_control(int sock, DltDaemon *daemon, DltDaemonLoca
dlt_daemon_control_service_logstorage(sock, daemon, daemon_local, msg, verbose);
break;
}
+ case DLT_SERVICE_ID_PASSIVE_NODE_CONNECT:
+ {
+ dlt_daemon_control_passive_node_connect(sock,
+ daemon,
+ daemon_local,
+ msg,
+ verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS:
+ {
+ dlt_daemon_control_passive_node_connect_status(sock,
+ daemon,
+ daemon_local,
+ verbose);
+ break;
+ }
default:
{
dlt_daemon_control_service_response(sock, daemon, daemon_local, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
@@ -1747,6 +1781,7 @@ void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal
int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
int verbose)
{
uint64_t expir = 0;
@@ -1755,7 +1790,7 @@ int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
PRINT_FUNCTION_VERBOSE(verbose);
- if((daemon_local == NULL) || (daemon == NULL))
+ if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
{
snprintf(local_str,
DLT_DAEMON_TEXTBUFSIZE,
@@ -1765,7 +1800,7 @@ int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
return -1;
}
- res = read(daemon_local->timer_one_s.fd, &expir, sizeof(expir));
+ res = read(receiver->fd, &expir, sizeof(expir));
if(res < 0)
{
@@ -1805,6 +1840,7 @@ int dlt_daemon_process_one_s_timer(DltDaemon *daemon,
int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
int verbose)
{
uint64_t expir = 0;
@@ -1813,7 +1849,7 @@ int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
PRINT_FUNCTION_VERBOSE(verbose);
- if((daemon_local == NULL) || (daemon == NULL))
+ if((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
{
snprintf(str,
DLT_DAEMON_TEXTBUFSIZE,
@@ -1823,7 +1859,7 @@ int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
return -1;
}
- res = read(daemon_local->timer_sixty_s.fd, &expir, sizeof(expir));
+ res = read(receiver->fd, &expir, sizeof(expir));
if(res < 0)
{
@@ -1867,6 +1903,7 @@ int dlt_daemon_process_sixty_s_timer(DltDaemon *daemon,
#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
int verbose)
{
uint64_t expir = 0;
@@ -1875,7 +1912,7 @@ int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
PRINT_FUNCTION_VERBOSE(verbose);
- if((daemon_local == NULL) || (daemon == NULL))
+ if((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
{
snprintf(local_str,
DLT_DAEMON_TEXTBUFSIZE,
@@ -1885,7 +1922,7 @@ int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
return res;
}
- res = read(daemon_local->timer_wd.fd, &expir, sizeof(expir));
+ res = read(receiver->fd, &expir, sizeof(expir));
if(res < 0)
{
@@ -1910,10 +1947,12 @@ int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
#else
int dlt_daemon_process_systemd_timer(DltDaemon *daemon,
DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
int verbose)
{
(void)daemon;
(void)daemon_local;
+ (void)receiver;
(void)verbose;
dlt_log(LOG_DEBUG, "Timer watchdog not enabled\n");
@@ -2015,3 +2054,169 @@ void dlt_daemon_control_service_logstorage(int sock, DltDaemon *daemon, DltDaemo
dlt_daemon_control_service_response(sock, daemon, daemon_local, DLT_SERVICE_ID_OFFLINE_LOGSTORAGE, DLT_SERVICE_RESPONSE_ERROR, verbose);
}
}
+
+void dlt_daemon_control_passive_node_connect(int sock,
+ DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltMessage *msg,
+ int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ DltServicePassiveNodeConnect *req;
+ uint32_t id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECT;
+
+ if (daemon == NULL || daemon_local == NULL || msg == NULL ||
+ msg->databuffer == NULL)
+ {
+ return;
+ }
+
+ /* return error, if gateway mode not enabled*/
+ if (daemon_local->flags.gatewayMode == 0)
+ {
+ dlt_log(LOG_WARNING,
+ "Received passive node connection status request, "
+ "but GatewayMode is disabled\n");
+
+ dlt_daemon_control_service_response(
+ sock,
+ daemon,
+ daemon_local,
+ DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
+ DLT_SERVICE_RESPONSE_ERROR,
+ verbose);
+
+ return;
+ }
+
+ req = (DltServicePassiveNodeConnect *) msg->databuffer;
+
+ if (dlt_gateway_process_on_demand_request(&daemon_local->pGateway,
+ daemon_local,
+ req->node_id,
+ req->connection_status,
+ verbose) < 0)
+ {
+ dlt_daemon_control_service_response(sock,
+ daemon,
+ daemon_local,
+ id,
+ DLT_SERVICE_RESPONSE_ERROR,
+ verbose);
+ }
+ else
+ {
+ dlt_daemon_control_service_response(sock,
+ daemon,
+ daemon_local,
+ id,
+ DLT_SERVICE_RESPONSE_OK,
+ verbose);
+ }
+}
+
+void dlt_daemon_control_passive_node_connect_status(int sock,
+ DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ int verbose)
+{
+ DltMessage msg;
+ DltServicePassiveNodeConnectionInfo *resp;
+ DltGatewayConnection *con = NULL;
+ unsigned int i = 0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon == NULL || daemon_local == NULL)
+ {
+ return;
+ }
+
+ if (dlt_message_init(&msg, verbose) == -1)
+ {
+ return;
+ }
+
+ /* return error, if gateway mode not enabled*/
+ if (daemon_local->flags.gatewayMode == 0)
+ {
+ dlt_log(LOG_WARNING,
+ "Received passive node connection status request, "
+ "but GatewayMode is disabled\n");
+
+ dlt_daemon_control_service_response(
+ sock,
+ daemon,
+ daemon_local,
+ DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
+ DLT_SERVICE_RESPONSE_ERROR,
+ verbose);
+
+ return;
+ }
+
+ /* prepare payload of data */
+ msg.datasize = sizeof(DltServicePassiveNodeConnectionInfo);
+ if (msg.databuffer && (msg.databuffersize < msg.datasize))
+ {
+ msg.databuffer = NULL;
+ }
+ if (msg.databuffer == NULL)
+ {
+ msg.databuffer = (uint8_t *) malloc(msg.datasize);
+ if (msg.databuffer == NULL)
+ {
+ dlt_log(LOG_CRIT, "Cannot allocate memory for message response\n");
+ return;
+ }
+ msg.databuffersize = msg.datasize;
+ }
+
+ resp = (DltServicePassiveNodeConnectionInfo *) msg.databuffer;
+ memset(resp, 0, msg.datasize);
+ resp->service_id = DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS;
+ resp->status = DLT_SERVICE_RESPONSE_OK;
+ resp->num_connections = daemon_local->pGateway.num_connections;
+
+ for (i = 0; i < resp->num_connections; i++)
+ {
+ if ((i * DLT_ID_SIZE) > DLT_ENTRY_MAX)
+ {
+ dlt_log(LOG_ERR,
+ "Maximal message size reached. Skip further information\n");
+ break;
+ }
+
+ con = &daemon_local->pGateway.connections[i];
+ if (con == NULL)
+ {
+ dlt_log(LOG_CRIT, "Passive node connection structure is NULL\n");
+ dlt_daemon_control_service_response(
+ sock,
+ daemon,
+ daemon_local,
+ DLT_SERVICE_ID_PASSIVE_NODE_CONNECTION_STATUS,
+ DLT_SERVICE_RESPONSE_ERROR,
+ verbose);
+
+ /* free message */
+ dlt_message_free(&msg, verbose);
+
+ return;
+ }
+
+ resp->connection_status[i] = con->status;
+ memcpy(&resp->node_id[i * DLT_ID_SIZE], con->ecuid, DLT_ID_SIZE);
+ }
+
+ dlt_daemon_client_send_control_message(sock,
+ daemon,
+ daemon_local,
+ &msg,
+ "",
+ "",
+ verbose);
+ /* free message */
+ dlt_message_free(&msg, verbose);
+}
diff --git a/src/daemon/dlt_daemon_client.h b/src/daemon/dlt_daemon_client.h
index 4b5ebcb..7128ddb 100644
--- a/src/daemon/dlt_daemon_client.h
+++ b/src/daemon/dlt_daemon_client.h
@@ -265,4 +265,30 @@ void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, DltDaemonLocal
*/
void dlt_daemon_control_service_logstorage(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received passive node connect control
+ * message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param daemon_local pointer to dlt daemon local structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_passive_node_connect(int sock,
+ DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltMessage *msg,
+ int verbose);
+/**
+ * Process and generate response to received passive node connection status
+ * control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param daemon_local pointer to dlt daemon local structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_passive_node_connect_status(int sock,
+ DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ int verbose);
#endif /* DLT_DAEMON_CLIENT_H */
diff --git a/src/daemon/dlt_daemon_connection.c b/src/daemon/dlt_daemon_connection.c
index 1a7af3f..1629cc3 100644
--- a/src/daemon/dlt_daemon_connection.c
+++ b/src/daemon/dlt_daemon_connection.c
@@ -45,6 +45,7 @@
#include "dlt-daemon_cfg.h"
#include "dlt_daemon_common.h"
#include "dlt_common.h"
+#include "dlt_gateway.h"
/** @brief Generic sending function.
*
@@ -171,7 +172,8 @@ DltConnection *dlt_connection_get_next(DltConnection *current, int type_mask)
* @return DltReceiver structure or NULL if none corresponds to the type.
*/
static DltReceiver *dlt_connection_get_receiver(DltDaemonLocal *daemon_local,
- DltConnectionType type)
+ DltConnectionType type,
+ int fd)
{
DltReceiver *ret = NULL;
@@ -206,6 +208,16 @@ static DltReceiver *dlt_connection_get_receiver(DltDaemonLocal *daemon_local,
case DLT_CONNECTION_CONTROL_MSG:
ret = &daemon_local->receiverCtrlSock;
break;
+ case DLT_CONNECTION_GATEWAY:
+ /* FIXME: This is complete different approach compared to having the
+ * receiver as part of daemon_local structure. Approaches need
+ * to be harmonized.
+ */
+ ret = dlt_gateway_get_connection_receiver(&daemon_local->pGateway, fd);
+ break;
+ case DLT_CONNECTION_GATEWAY_TIMER:
+ ret = &daemon_local->timer_gateway;
+ break;
default:
ret = NULL;
}
@@ -265,6 +277,12 @@ void *dlt_connection_get_callback(DltConnection *con)
case DLT_CONNECTION_CONTROL_MSG:
ret = dlt_daemon_process_control_messages;
break;
+ case DLT_CONNECTION_GATEWAY:
+ ret = dlt_gateway_process_passive_node_messages;
+ break;
+ case DLT_CONNECTION_GATEWAY_TIMER:
+ ret = dlt_gateway_process_gateway_timer;
+ break;
default:
ret = NULL;
}
@@ -332,7 +350,7 @@ int dlt_connection_create(DltDaemonLocal *daemon_local,
temp->fd = fd;
temp->type = type;
- temp->receiver = dlt_connection_get_receiver(daemon_local, type);
+ temp->receiver = dlt_connection_get_receiver(daemon_local, type, fd);
/* Now give the ownership of the newly created connection
* to the event handler, by registering for events.
@@ -358,7 +376,7 @@ int dlt_connection_create_remaining(DltDaemonLocal *daemon_local)
for (i = 0 ; i < DLT_CONNECTION_TYPE_MAX ; i++)
{
int fd = 0;
- DltReceiver *rec = dlt_connection_get_receiver(daemon_local, i);
+ DltReceiver *rec = dlt_connection_get_receiver(daemon_local, i, fd);
if (rec == NULL)
{
diff --git a/src/daemon/dlt_daemon_connection_types.h b/src/daemon/dlt_daemon_connection_types.h
index c35b43e..5edb875 100644
--- a/src/daemon/dlt_daemon_connection_types.h
+++ b/src/daemon/dlt_daemon_connection_types.h
@@ -41,6 +41,8 @@ typedef enum {
DLT_CONNECTION_SYSTEMD_TIMER,
DLT_CONNECTION_CONTROL_CONNECT,
DLT_CONNECTION_CONTROL_MSG,
+ DLT_CONNECTION_GATEWAY,
+ DLT_CONNECTION_GATEWAY_TIMER,
DLT_CONNECTION_TYPE_MAX
} DltConnectionType;
@@ -53,7 +55,9 @@ typedef enum {
#define DLT_CON_MASK_SYSTEMD_TIMER (1 << DLT_CONNECTION_SYSTEMD_TIMER)
#define DLT_CON_MASK_CONTROL_CONNECT (1 << DLT_CONNECTION_CONTROL_CONNECT)
#define DLT_CON_MASK_CONTROL_MSG (1 << DLT_CONNECTION_CONTROL_MSG)
-#define DLT_CON_MASK_ALL (0xff)
+#define DLT_CON_MASK_GATEWAY (1 << DLT_CONNECTION_GATEWAY)
+#define DLT_CON_MASK_GATEWAY_TIMER (1 << DLT_CONNECTION_GATEWAY_TIMER)
+#define DLT_CON_MASK_ALL (0xffff)
/* TODO: squash the DltReceiver structure in there
* and remove any other duplicates of FDs
diff --git a/src/daemon/dlt_daemon_event_handler.c b/src/daemon/dlt_daemon_event_handler.c
index 3762ca2..5b5a8ac 100644
--- a/src/daemon/dlt_daemon_event_handler.c
+++ b/src/daemon/dlt_daemon_event_handler.c
@@ -91,7 +91,7 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent,
int nfds = 0;
int i = 0;
char str[DLT_DAEMON_TEXTBUFSIZE];
- int (*callback)(DltDaemon *, DltDaemonLocal *, int) = NULL;
+ int (*callback)(DltDaemon *, DltDaemonLocal *, DltReceiver *, int) = NULL;
/*CM Change begin*/
nfds = epoll_wait(pEvent->epfd,
@@ -142,7 +142,6 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent,
type);
continue;
}
-
/* Get the function to be used to handle the event */
callback = dlt_connection_get_callback((DltConnection *)ev->data.ptr);
@@ -161,7 +160,10 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent,
((DltConnection *)ev->data.ptr)->receiver->fd = fd;
/* From now on, callback is correct */
- if (callback(daemon, daemon_local, daemon_local->flags.vflag) == -1)
+ if (callback(daemon,
+ daemon_local,
+ ((DltConnection *)ev->data.ptr)->receiver,
+ daemon_local->flags.vflag) == -1)
{
snprintf(str,
DLT_DAEMON_TEXTBUFSIZE,
@@ -171,7 +173,6 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent,
return -1;
}
}
-
return 0;
}
diff --git a/src/daemon/dlt_daemon_event_handler_types.h b/src/daemon/dlt_daemon_event_handler_types.h
index 080c331..a2945b4 100644
--- a/src/daemon/dlt_daemon_event_handler_types.h
+++ b/src/daemon/dlt_daemon_event_handler_types.h
@@ -46,6 +46,7 @@ typedef enum {
#ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
DLT_TIMER_SYSTEMD,
#endif
+ DLT_TIMER_GATEWAY,
DLT_TIMER_UNKNOWN
} DltTimers;
diff --git a/src/gateway/CMakeLists.txt b/src/gateway/CMakeLists.txt
new file mode 100644
index 0000000..a34b44e
--- /dev/null
+++ b/src/gateway/CMakeLists.txt
@@ -0,0 +1,22 @@
+#######
+# @licence make begin@
+# SPDX license identifier: MPL-2.0
+#
+# Copyright (C) 2015, Advanced Driver Information Technology
+# This code is developed by Advanced Driver Information Technology.
+# Copyright of Advanced Driver Information Technology, Bosch and DENSO.
+#
+# This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+#
+# This Source Code Form is subject to the terms of the
+# Mozilla Public License (MPL), v. 2.0.
+# If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# For further information see http://www.genivi.org/.
+# @licence end@
+#######
+
+INSTALL(FILES dlt_gateway.conf
+ DESTINATION ${CONFIGURATION_FILES_DIR}
+ COMPONENT base)
diff --git a/src/gateway/dlt_gateway.c b/src/gateway/dlt_gateway.c
new file mode 100644
index 0000000..a7d7d39
--- /dev/null
+++ b/src/gateway/dlt_gateway.c
@@ -0,0 +1,1052 @@
+/*
+ * @licence app begin@
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2015 Advanced Driver Information Technology.
+ * This code is developed by Advanced Driver Information Technology.
+ * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License (MPL), v. 2.0.
+ * If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+/*!
+ * \author
+ * Christoph Lipka <clipka@jp.adit-jv.com>
+ *
+ * \copyright Copyright © 2015 Advanced Driver Information Technology. \n
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_gateway.c
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <limits.h>
+#include <errno.h>
+#include "dlt_gateway.h"
+#include "dlt_config_file_parser.h"
+#include "dlt_common.h"
+#include "dlt-daemon_cfg.h"
+#include "dlt_daemon_event_handler.h"
+#include "dlt_daemon_connection.h"
+#include "dlt_daemon_client.h"
+
+/**
+ * Expected entries for a passive node configuration
+ * Caution: after changing entries here,
+ * dlt_gateway_check_params need to be updated as well
+ * */
+char *configuration_entries [] =
+{
+ "IPaddress",
+ "Port",
+ "EcuID",
+ "Connect",
+ "Timeout"
+};
+
+#define DLT_GATEWAY_NUM_PROPERTIES_MAX 5
+
+/**
+ * Check if given string is a valid IP address
+ *
+ * @param ip IP address
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_ip(char **ip, char *value)
+{
+ struct sockaddr_in sa;
+ int ret = -1;
+
+ if (ip == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ ret = inet_pton(AF_INET, value, &(sa.sin_addr));
+
+ /* valid IP address */
+ if (ret != 0)
+ {
+ *ip = strdup(value);
+
+ if (*ip == NULL)
+ {
+ dlt_log(LOG_ERR, "Cannot copy passive node IP address string\n");
+ return -1;
+ }
+
+ return 0;
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "IP address is not valid\n");
+ }
+
+ return -1;
+}
+
+/**
+ * Check socket domain
+ *
+ * This function is currently not used; only AF_INET is supported.
+ *
+ * @param domain socket domain
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_domain(int *domain, char *value)
+{
+ int ret = -1;
+
+ if (domain == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ ret = strncmp(value, "AF_INET", strlen("AF_INET"));
+
+ if (ret == 0)
+ {
+ *domain = AF_INET;
+ return 0;
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Only socket domain AF_INET supported\n");
+ }
+
+ return -1;
+}
+
+/**
+ * Check socket type
+ *
+ * This function is currently not used; only SOCK_STREAM is supported.
+ *
+ * @param type socket type
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_type(int *type, char *value)
+{
+ int ret = -1;
+
+ if (type == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ ret = strncmp(value, "SOCK_STREAM", strlen("SOCK_STREAM"));
+
+ if (ret == 0)
+ {
+ *type = SOCK_STREAM;
+ return 0;
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Only socket type SOCK_STREAM is supported\n");
+ }
+
+ return -1;
+}
+
+/**
+ * Check socket protocol
+ *
+ * This function is currently not used; only IPPROTO_TCP is supported.
+ *
+ * @param protocol socket protocol
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_protocol(int *protocol, char *value)
+{
+ if (protocol == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ if (strncmp(value, "IPPROTO_TCP", strlen("IPPROTO_TCP")) == 0)
+ {
+ *protocol = IPPROTO_TCP;
+ return 0;
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Only protocol IPPROTO_TCP is supported\n");
+ }
+
+ return -1;
+}
+
+/**
+ * Check port number
+ *
+ * @param port port number
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_port(int *port, char *value)
+{
+ int tmp = -1;
+
+ if (port == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ tmp = (int) strtol(value, NULL, 10);
+
+ /* port ranges for unprivileged applications */
+ if (tmp > IPPORT_RESERVED && tmp <= USHRT_MAX)
+ {
+ *port = tmp;
+ return 0;
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Port number is invalid\n");
+ }
+
+ return -1;
+}
+
+/**
+ * Check ECU name
+ *
+ * @param ecuid ecu name
+ * @param value string to be used as ECU identifier
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_ecu(char **ecuid, char *value)
+{
+ if (ecuid == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ *ecuid = strdup(value);
+
+ if (*ecuid == NULL)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check connection trigger
+ *
+ * @param trigger connection setup trigger
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_connect_trigger(int *trigger, char *value)
+{
+ if (trigger == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ if (strncasecmp(value, "OnStartup", strlen("OnStartup")) == 0)
+ {
+ *trigger = DLT_GATEWAY_ON_STARTUP;
+ }
+ else if (strncasecmp(value, "OnDemand", strlen("OnDemand")) == 0)
+ {
+ *trigger = DLT_GATEWAY_ON_DEMAND;
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Wrong connection trigger state given.\n");
+ *trigger = DLT_GATEWAY_UNDEFINED;
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check connection timeout value
+ *
+ * @param timeout connection timeout
+ * @param value string to be tested
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_timeout(int *timeout, char *value)
+{
+ if (timeout == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ *timeout = (int) strtol(value, NULL, 10);
+
+ if (*timeout > 0)
+ {
+ return 0;
+ }
+
+ return -1;
+}
+
+/**
+ * Check if gateway connection configuration parameter is valid.
+ *
+ * @param g DltGateway
+ * @param c DltGatewayConnection
+ * @param key DltGatwayConnection property
+ * @param value specified property value from configuration file
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_check_param(DltGateway *gateway,
+ DltGatewayConnection *con,
+ char *key,
+ char *value)
+{
+ if (gateway == NULL || con == NULL || key == NULL || value == NULL)
+ {
+ return -1;
+ }
+
+ if (strncmp(key, "IPaddress", sizeof("IPaddress")) == 0)
+ {
+ return dlt_gateway_check_ip(&con->ip_address, value);
+ }
+ else if (strncmp(key, "SockDomain", sizeof("SockDomain")) == 0)
+ {
+ return dlt_gateway_check_domain(&(con->sock_domain), value);
+ }
+ else if (strncmp(key, "SockType", sizeof("SockType")) == 0)
+ {
+ return dlt_gateway_check_type(&(con->sock_type), value);
+ }
+ else if (strncmp(key, "SockProtocol", sizeof("SockProtocol")) == 0)
+ {
+ return dlt_gateway_check_protocol(&(con->sock_protocol), value);
+ }
+ else if (strncmp(key, "Port", sizeof("Port")) == 0)
+ {
+ return dlt_gateway_check_port(&(con->port), value);
+ }
+ else if (strncmp(key, "EcuID", sizeof("EcuID")) == 0)
+ {
+ return dlt_gateway_check_ecu(&con->ecuid,value);
+ }
+ else if (strncmp(key, "Connect", sizeof("Connect")) == 0)
+ {
+ return dlt_gateway_check_connect_trigger(&(con->trigger), value);
+ }
+ else if (strncmp(key, "Timeout", sizeof("Timeout")) == 0)
+ {
+ return dlt_gateway_check_timeout(&(con->timeout), value);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+/**
+ * Store gateway connection in internal data structure
+ *
+ * @param g DltGatway
+ * @param tmp DltGatewayConnection
+ * @param verbose verbose flag
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_store_connection(DltGateway *gateway,
+ DltGatewayConnection *tmp,
+ int verbose)
+{
+ int i = 0;
+ int ret = 0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (gateway == NULL || tmp == NULL)
+ {
+ return -1;
+ }
+
+ /* find next free entry in connection array */
+ while (i < gateway->num_connections)
+ {
+ if (gateway->connections[i].status == DLT_GATEWAY_UNINITIALIZED)
+ {
+ break;
+ }
+
+ i++;
+ }
+
+ if (&gateway->connections[i] == NULL)
+ {
+ return -1;
+ }
+
+ /* store values */
+ gateway->connections[i].ip_address = strdup(tmp->ip_address);
+ gateway->connections[i].ecuid = strdup(tmp->ecuid);
+ gateway->connections[i].sock_domain = tmp->sock_domain;
+ gateway->connections[i].sock_type = tmp->sock_type;
+ gateway->connections[i].sock_protocol = tmp->sock_protocol;
+ gateway->connections[i].port = tmp->port;
+ gateway->connections[i].trigger = tmp->trigger;
+ gateway->connections[i].timeout = tmp->timeout;
+ gateway->connections[i].handle = 0;
+ gateway->connections[i].status = DLT_GATEWAY_INITIALIZED;
+
+ if (dlt_client_init(&gateway->connections[i].client, verbose) != 0)
+ {
+ free(gateway->connections[i].ip_address);
+ free(gateway->connections[i].ecuid);
+ dlt_log(LOG_CRIT, "dlt_client_init() failed for gateway connection\n");
+ return -1;
+ }
+ dlt_receiver_init(&gateway->connections[i].client.receiver,
+ gateway->connections[i].client.sock,
+ DLT_DAEMON_RCVBUFSIZESOCK);
+ /* setup DltClient Structure */
+ gateway->connections[i].client.servIP =
+ strdup(gateway->connections[i].ip_address);
+ // TODO: modify DltClient structure to make port configurable
+ // g->connections[i].client.servPort = g->connections[i].port;
+
+ if (ret != 0)
+ {
+ free(gateway->connections[i].ip_address);
+ free(gateway->connections[i].ecuid);
+ dlt_log(LOG_ERR, "Gateway: DltClient initialization failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * Read configuration file and initialize connection data structures
+ *
+ * @param g DltGateway
+ * @param verbose verbose flag
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_configure(DltGateway *gateway, int verbose)
+{
+ int ret = 0;
+ int i = 0;
+ DltGatewayConnection tmp;
+ DltConfigFile *file = NULL;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (gateway == NULL)
+ {
+ return -1;
+ }
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ /* read configuration file */
+ file = dlt_config_file_init(DLT_GATEWAY_CONFIG_PATH);
+
+ /* get number of entries and allocate memory to store information */
+ ret = dlt_config_file_get_num_sections(file, &gateway->num_connections);
+
+ if (ret != 0)
+ {
+ dlt_config_file_release(file);
+ dlt_log(LOG_ERR, "Invalid number of sections in configuration file\n");
+ return -1;
+ }
+
+ gateway->connections = calloc(sizeof(DltGatewayConnection),
+ gateway->num_connections);
+
+ if (gateway->connections == NULL)
+ {
+ dlt_config_file_release(file);
+ dlt_log(LOG_CRIT, "Memory allocation for gateway connections failed\n");
+ return -1;
+ }
+
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ int j = 0;
+ char section[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {'\0'};
+ char value[DLT_CONFIG_FILE_ENTRY_MAX_LEN] = {'\0'};
+ int is_node_valid = 1; /* 1 - valid, <= 0 invalid */
+
+ ret = dlt_config_file_get_section_name(file, i, section);
+
+ for (j = 0; j < DLT_GATEWAY_NUM_PROPERTIES_MAX; j++)
+ {
+ ret = dlt_config_file_get_value(file,
+ section,
+ configuration_entries[j],
+ value);
+
+ if (ret != 0)
+ {
+ is_node_valid = -1;
+ break;
+ }
+
+ /* check value and store temporary */
+ ret = dlt_gateway_check_param(gateway,
+ &tmp,
+ configuration_entries[j],
+ value);
+
+ if (ret != 0)
+ {
+ char error_str[DLT_DAEMON_TEXTBUFSIZE] = {'\0'};
+ sprintf(error_str,
+ "Configuration %s = %s is invalid\n",
+ configuration_entries[j], value);
+ dlt_log(LOG_ERR, error_str);
+ is_node_valid = -1;
+ break;
+ }
+ }
+
+ if (is_node_valid >= 1)
+ {
+ ret = dlt_gateway_store_connection(gateway, &tmp, verbose);
+
+ if (ret != 0)
+ {
+ dlt_log(LOG_ERR, "Storing gateway connection data failed\n");
+ }
+ }
+
+ /* strdup used inside some get_value function */
+ free(tmp.ecuid);
+ free(tmp.ip_address);
+ }
+
+ dlt_config_file_release(file);
+ return ret;
+}
+
+int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon_local == NULL)
+ {
+ return -1;
+ }
+
+ DltGateway *gateway = &daemon_local->pGateway;
+
+ if (gateway != NULL)
+ {
+ if (dlt_gateway_configure(gateway, verbose) != 0)
+ {
+ dlt_log(LOG_ERR, "Gateway initialization failed\n");
+ return -1;
+ }
+ }
+ else
+ {
+ dlt_log(LOG_CRIT, "Pointer to Gateway structure is NULL\n");
+ return -1;
+ }
+
+ /* ignore return value */
+ dlt_gateway_establish_connections(gateway, daemon_local, verbose);
+
+ return 0;
+}
+
+void dlt_gateway_deinit(DltGateway *gateway, int verbose)
+{
+ int i = 0;
+
+ if (gateway == NULL)
+ {
+ return;
+ }
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ DltGatewayConnection *c = &gateway->connections[i];
+ dlt_client_cleanup(&c->client, verbose);
+ free(c->ip_address);
+ free(c->ecuid);
+ }
+
+ free(gateway->connections);
+ free(gateway);
+}
+
+int dlt_gateway_establish_connections(DltGateway *gateway,
+ DltDaemonLocal *daemon_local,
+ int verbose)
+{
+ int i = 0;
+ int ret = 0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (gateway == NULL || daemon_local == NULL)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ DltGatewayConnection *con = &(gateway->connections[i]);
+ if (con == NULL)
+ {
+ dlt_log(LOG_CRIT, "Cannot retrieve gateway connection details\n");
+ return -1;
+ }
+
+ if (con->status != DLT_GATEWAY_CONNECTED &&
+ con->trigger != DLT_GATEWAY_ON_DEMAND &&
+ con->trigger != DLT_GATEWAY_DISABLED)
+ {
+ ret = dlt_client_connect(&con->client, verbose);
+
+ if (ret == 0)
+ {
+ /* connection to passive node established, add to event loop */
+ con->status = DLT_GATEWAY_CONNECTED;
+
+ /* setup dlt connection and add to epoll event loop here */
+ if (dlt_connection_create(daemon_local,
+ &daemon_local->pEvent,
+ con->client.sock,
+ EPOLLIN,
+ DLT_CONNECTION_GATEWAY) != 0)
+ {
+ dlt_log(LOG_ERR, "Gateway connection creation failed\n");
+ return -1;
+ }
+ }
+ else
+ {
+ dlt_log(LOG_DEBUG,
+ "Passive Node is not up. Connection failed.\n");
+
+ con->timeout_cnt++;
+ if (con->timeout_cnt > con->timeout)
+ {
+ con->trigger = DLT_GATEWAY_DISABLED;
+ dlt_log(LOG_WARNING,
+ "Passive Node connection retry timed out. "
+ "Give up.\n");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+DltReceiver *dlt_gateway_get_connection_receiver(DltGateway *gateway, int fd)
+{
+ int i = 0;
+
+ if (gateway == NULL)
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ DltGatewayConnection *c = &gateway->connections[i];
+ if (c->status == DLT_GATEWAY_CONNECTED && c->client.sock == fd)
+ {
+ return &c->client.receiver;
+ }
+ }
+
+ return NULL;
+}
+
+int dlt_gateway_process_passive_node_messages(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
+ int verbose)
+{
+ int i = 0;
+ DltGateway *gateway = NULL;
+ DltGatewayConnection *con = NULL;
+ DltMessage msg;
+ char local_str[DLT_DAEMON_TEXTBUFSIZE];
+
+ if (daemon == NULL || daemon_local == NULL || receiver == NULL)
+ {
+ return -1;
+ }
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ gateway = &daemon_local->pGateway;
+ if (gateway == NULL)
+ {
+ dlt_log(LOG_ERR, "Gateway structure is NULL\n");
+ return -1;
+ }
+
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ if (gateway->connections[i].client.sock == receiver->fd)
+ {
+ con = &gateway->connections[i];
+ break;
+ }
+ }
+
+ if (con == NULL)
+ {
+ dlt_log(LOG_ERR, "Cannot associate fd to passive Node connection\n");
+ return -1;
+ }
+
+ /* now the corresponding passive node connection is available */
+ if (dlt_message_init(&msg, verbose) == -1)
+ {
+ dlt_log(LOG_ERR,
+ "Cannot initialize DLT message for passive node forwarding\n");
+ return -1;
+ }
+
+ /* nearly copy and paste of dlt_client_main_loop function */
+ if (dlt_receiver_receive_socket(receiver) <= 0)
+ {
+ /* No more data to be received */
+ if (dlt_message_free(&msg, verbose) < 0)
+ {
+ dlt_log(LOG_ERR, "Cannot free DLT message\n");
+ return -1;
+ }
+
+ con->status = DLT_GATEWAY_DISCONNECTED;
+ if (dlt_event_handler_unregister_connection(&daemon_local->pEvent,
+ daemon_local,
+ receiver->fd,
+ DLT_CONNECTION_GATEWAY) != 0)
+ {
+ dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
+ }
+
+ dlt_log(LOG_WARNING, "Connection to passive node lost\n");
+
+ return 0;
+ }
+
+ while (dlt_message_read(&msg,
+ (unsigned char *)receiver->buf,
+ receiver->bytesRcvd,
+ 0,
+ verbose) == DLT_MESSAGE_ERROR_OK)
+ {
+ DltStandardHeaderExtra *header = (DltStandardHeaderExtra *)
+ (msg.headerbuffer +
+ sizeof(DltStorageHeader) +
+ sizeof(DltStandardHeader));
+
+ /* only forward messages if the received ECUid is the expected one */
+ if (strncmp(header->ecu, con->ecuid, strlen(con->ecuid)) == 0)
+ {
+ if (dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL,
+ daemon,
+ daemon_local,
+ msg.headerbuffer,
+ sizeof(DltStorageHeader),
+ msg.headerbuffer + sizeof(DltStorageHeader),
+ msg.headersize - sizeof(DltStorageHeader),
+ msg.databuffer,
+ msg.datasize,
+ verbose) != DLT_DAEMON_ERROR_OK)
+ {
+ dlt_log(LOG_WARNING, "Forward message to clients failed!\n");
+ }
+ }
+ else /* otherwise remove this connection and do not connect again */
+ {
+ snprintf(local_str,
+ DLT_DAEMON_TEXTBUFSIZE,
+ "Received ECUid (%s) differs to configured ECUid(%s). "
+ "Discard this message.\n",
+ header->ecu,
+ con->ecuid);
+ dlt_log(LOG_WARNING, local_str);
+
+ /* disconnect from passive node */
+ con->status = DLT_GATEWAY_DISCONNECTED;
+ con->trigger = DLT_GATEWAY_DISABLED;
+ if (dlt_event_handler_unregister_connection(&daemon_local->pEvent,
+ daemon_local,
+ receiver->fd,
+ DLT_CONNECTION_GATEWAY)
+ != 0)
+ {
+ dlt_log(LOG_ERR, "Remove passive node Connection failed\n");
+ }
+
+ dlt_log(LOG_WARNING,
+ "Disconnect from passive node due to invalid ECUid\n");
+ }
+
+ if (msg.found_serialheader)
+ {
+ if (dlt_receiver_remove(receiver,
+ msg.headersize +
+ msg.datasize -
+ sizeof(DltStorageHeader) +
+ sizeof(dltSerialHeader)) == -1)
+ {
+ /* Return value ignored */
+ dlt_message_free(&msg,verbose);
+ return -1;
+ }
+ }
+ else
+ {
+ if (dlt_receiver_remove(receiver,
+ msg.headersize +
+ msg.datasize -
+ sizeof(DltStorageHeader)) == -1)
+ {
+ /* Return value ignored */
+ dlt_message_free(&msg,verbose);
+ return -1;
+ }
+ }
+ }
+
+ if (dlt_receiver_move_to_begin(receiver) == -1)
+ {
+ /* Return value ignored */
+ dlt_message_free(&msg, verbose);
+ return -1;
+ }
+
+ if (dlt_message_free(&msg, verbose) == -1)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_gateway_process_gateway_timer(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *receiver,
+ int verbose)
+{
+ uint64_t expir = 0;
+ ssize_t res = 0;
+ char local_str[DLT_DAEMON_TEXTBUFSIZE];
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon_local == NULL) || (daemon == NULL) || (receiver == NULL))
+ {
+ snprintf(local_str,
+ DLT_DAEMON_TEXTBUFSIZE,
+ "%s: invalid parameters",
+ __func__);
+ dlt_log(LOG_ERR, local_str);
+ return -1;
+ }
+
+ res = read(receiver->fd, &expir, sizeof(expir));
+
+ if(res < 0)
+ {
+ snprintf(local_str,
+ DLT_DAEMON_TEXTBUFSIZE,
+ "%s: Fail to read timer (%s)\n", __func__, strerror(errno));
+ dlt_log(LOG_WARNING, local_str);
+ /* Activity received on timer_wd, but unable to read the fd:
+ let's go on sending notification */
+ }
+
+ /* try to connect to passive nodes */
+ dlt_gateway_establish_connections(&daemon_local->pGateway,
+ daemon_local,
+ verbose);
+
+ dlt_log(LOG_DEBUG, "Gateway Timer\n");
+
+ return 0;
+}
+
+int dlt_gateway_forward_control_message(DltGateway *gateway,
+ DltDaemonLocal *daemon_local,
+ DltMessage *msg,
+ char *ecu,
+ int verbose)
+{
+ int i = 0;
+ int ret = 0;
+ DltGatewayConnection *con = NULL;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (gateway == NULL || daemon_local == NULL || msg == NULL || ecu == NULL)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ if (strncmp(gateway->connections[i].ecuid,
+ ecu,
+ strlen(gateway->connections[i].ecuid)) == 0)
+ {
+ con = &gateway->connections[i];
+ break;
+ }
+ }
+
+ if (con == NULL)
+ {
+ dlt_log(LOG_WARNING, "Unknown passive node identifier\n");
+ return -1;
+ }
+
+ if (con->status != DLT_GATEWAY_CONNECTED)
+ {
+ dlt_log(LOG_INFO, "Passive node is not connected\n");
+ return -1;
+ }
+
+ ret = send(con->client.sock,
+ msg->headerbuffer + sizeof(DltStorageHeader),
+ msg->headersize - sizeof(DltStorageHeader),
+ 0);
+ if (ret == -1)
+ {
+ dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
+ return -1;
+ }
+ else
+ {
+ ret = send(con->client.sock, msg->databuffer, msg->datasize, 0);
+ if (ret == -1)
+ {
+ dlt_log(LOG_ERR, "Sending message to passive DLT Daemon failed\n");
+ return -1;
+ }
+ }
+
+ dlt_log(LOG_INFO, "Control message forwarded\n");
+ return 0;
+}
+
+int dlt_gateway_process_on_demand_request(DltGateway *gateway,
+ DltDaemonLocal *daemon_local,
+ char *node_id,
+ int connection_status,
+ int verbose)
+{
+ int i = 0;
+ DltGatewayConnection *con = NULL;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (gateway == NULL || daemon_local == NULL || node_id == NULL)
+ {
+ return -1;
+ }
+
+ /* find connection by ECU id */
+ for (i = 0; i < gateway->num_connections; i++)
+ {
+ if (strncmp(node_id, gateway->connections->ecuid, DLT_ID_SIZE) == 0)
+ {
+ con = &gateway->connections[i];
+ break;
+ }
+ }
+
+ if (con == NULL)
+ {
+ dlt_log(LOG_WARNING, "Specified ECUid not found\n");
+ return -1;
+ }
+
+ if (connection_status == 1) /* try to connect */
+ {
+ if (con->status != DLT_GATEWAY_CONNECTED)
+ {
+ if (dlt_client_connect(&con->client, verbose) == 0)
+ {
+ con->status = DLT_GATEWAY_CONNECTED;
+
+ /* setup dlt connection and add to epoll event loop here */
+ if (dlt_connection_create(daemon_local,
+ &daemon_local->pEvent,
+ con->client.sock,
+ EPOLLIN,
+ DLT_CONNECTION_GATEWAY) != 0)
+ {
+ dlt_log(LOG_ERR, "Gateway connection creation failed\n");
+ return -1;
+ }
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Could not connect to passive node\n");
+ return -1;
+ }
+ }
+ else
+ {
+ dlt_log(LOG_INFO, "Passive node already connected\n");
+ }
+ }
+ else if (connection_status == 0) /* disconnect*/
+ {
+
+ con->status = DLT_GATEWAY_DISCONNECTED;
+ if (dlt_event_handler_unregister_connection(&daemon_local->pEvent,
+ daemon_local,
+ con->client.sock,
+ DLT_CONNECTION_GATEWAY) != 0)
+ {
+ dlt_log(LOG_ERR,
+ "Remove passive node event handler connection failed\n");
+ }
+
+ if (dlt_client_cleanup(&con->client, verbose) != 0)
+ {
+ dlt_log(LOG_ERR, "Could not cleanup DltClient structure\n");
+ return -1;
+ }
+ }
+ else
+ {
+ dlt_log(LOG_ERR, "Unknown command (connection_status)\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/gateway/dlt_gateway.conf b/src/gateway/dlt_gateway.conf
new file mode 100644
index 0000000..95d8682
--- /dev/null
+++ b/src/gateway/dlt_gateway.conf
@@ -0,0 +1,9 @@
+[PassiveNode1]
+IPaddress=192.168.2.11
+Port=3490
+; passive nodes ECU identifier
+EcuID=ECU2
+; Try connect to passive Node on DLT Daemon startup
+Connect=OnStartup
+; Stop connecting to passive node, if not successful after 10 seconds
+Timeout=10
diff --git a/src/gateway/dlt_gateway.h b/src/gateway/dlt_gateway.h
new file mode 100644
index 0000000..eacdf0b
--- /dev/null
+++ b/src/gateway/dlt_gateway.h
@@ -0,0 +1,169 @@
+/*
+ * @licence app begin@
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2015 Advanced Driver Information Technology.
+ * This code is developed by Advanced Driver Information Technology.
+ * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License (MPL), v. 2.0.
+ * If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+/*!
+ * \author
+ * Christoph Lipka <clipka@jp.adit-jv.com>
+ *
+ * \copyright Copyright © 2015 Advanced Driver Information Technology. \n
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_gateway.h
+ */
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt_gateway.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** cl Christoph Lipka ADIT **
+*******************************************************************************/
+
+#ifndef DLT_GATEWAY_H_
+#define DLT_GATEWAY_H_
+
+#include "dlt-daemon.h"
+#include "dlt_gateway_types.h"
+
+/**
+ * Initialize the gateway to passive nodes
+ *
+ * TODO: Make path to configuration file configurable
+ *
+ * @param daemon_local pointer to DltDaemonLocal
+ * @param verbose verbose flag
+ * @return 0 on success, -1 on error
+ */
+int dlt_gateway_init(DltDaemonLocal *daemon_local, int verbose);
+
+/**
+ * De-initialize the gateway. All internal data will be freed.
+ *
+ * @param g DltGateway pointer
+ * @param verbose verbose flag
+ */
+void dlt_gateway_deinit(DltGateway *g, int verbose);
+
+/**
+ * Establish all connections to passive nodes that are configured to be started
+ * on daemon startup and add this connections to the main event loop.
+ *
+ * TODO: This function is called during gateway initialization and in main loop
+ * whenever the epoll returns. This may need to be improved.
+ *
+ * @param g DltGateway
+ * @param daemon_local DltDaemonLocal
+ * @param verbose verbose flag
+ * @return 0 on success, -1 on error
+ */
+int dlt_gateway_establish_connections(DltGateway *g,
+ DltDaemonLocal *daemon_local,
+ int verbose);
+
+/**
+ * Return the receiver for a given file descriptor
+ *
+ * @param g DltGateway
+ * @param fd file descriptor
+ * @return Pointer to DltReceiver on success, NULL otherwise
+ */
+DltReceiver *dlt_gateway_get_connection_receiver(DltGateway *g, int fd);
+
+
+/**
+ * Process incoming messages from passive nodes
+ *
+ * @param daemon DltDaemon
+ * @param daemon_local DltDaemonLocal
+ * @param recv DltReceiver structure
+ * @param verbose verbose flag
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_process_passive_node_messages(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *recv,
+ int verbose);
+
+/**
+ * Process gateway timer
+ *
+ * @param daemon DltDaemon
+ * @param daemon_loocal DltDaemonLocal
+ * @param verbose verbose flag
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_process_gateway_timer(DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ DltReceiver *rec,
+ int verbose);
+
+/**
+ * Forward control messages to the specified passive node DLT Daemon.
+ *
+ * @param g DltGateway
+ * @param daemon_local DltDaemonLocal
+ * @param msg DltMessage
+ * @param ecu Identifier of the passive node
+ * @param verbose verbose flag
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_forward_control_message(DltGateway *g,
+ DltDaemonLocal *daemon_local,
+ DltMessage *msg,
+ char *ecu,
+ int verbose);
+
+/**
+ * Process on demand connect/disconnect of passive nodes
+ *
+ * @param g DltGateway
+ * @param node_id Passive Node identifier
+ * @param connection_status Connection status
+ * @return 0 on success, -1 otherwise
+ */
+int dlt_gateway_process_on_demand_request(DltGateway *g,
+ DltDaemonLocal *daemon_local,
+ char *node_id,
+ int connection_status,
+ int verbose);
+
+/* _ONLY_ for development purposes */
+void print_gateway_connection_details(const DltGateway *g);
+
+#endif
diff --git a/src/gateway/dlt_gateway_types.h b/src/gateway/dlt_gateway_types.h
new file mode 100644
index 0000000..b1247dd
--- /dev/null
+++ b/src/gateway/dlt_gateway_types.h
@@ -0,0 +1,106 @@
+/*
+ * @licence app begin@
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2015 Advanced Driver Information Technology.
+ * This code is developed by Advanced Driver Information Technology.
+ * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ *
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License (MPL), v. 2.0.
+ * If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+
+/*!
+ * \author
+ * Christoph Lipka <clipka@jp.adit-jv.com>
+ *
+ * \copyright Copyright © 2015 Advanced Driver Information Technology. \n
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_gateway_types.h
+ */
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt_gateway_types.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Christoph Lipka clipka@jp.adit-jv.com **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** cl Christoph Lipka ADIT **
+*******************************************************************************/
+
+#ifndef DLT_GATEWAY_TYPES_H_
+#define DLT_GATEWAY_TYPES_H_
+
+#include "dlt_client.h"
+
+#define DLT_GATEWAY_CONFIG_PATH CONFIGURATION_FILES_DIR "/dlt_gateway.conf"
+#define DLT_GATEWAY_TIMER_INTERVAL 1
+
+typedef enum
+{
+ DLT_GATEWAY_UNINITIALIZED,
+ DLT_GATEWAY_INITIALIZED,
+ DLT_GATEWAY_CONNECTED,
+ DLT_GATEWAY_DISCONNECTED
+} connection_status;
+
+typedef enum
+{
+ DLT_GATEWAY_UNDEFINED = -1,
+ DLT_GATEWAY_ON_STARTUP, /* connect directly on startup */
+ DLT_GATEWAY_ON_DEMAND, /* connect on demand only */
+ DLT_GATEWAY_DISABLED /* disable this connection due to problems */
+} connection_trigger;
+
+/* DLT Gateway connection structure */
+typedef struct {
+ int handle; /* connection handle */
+ connection_status status; /* connected/disconnected */
+ char *ecuid; /* name of passive node */
+ char *ip_address; /* IP address */
+ int sock_domain; /* socket domain */
+ int sock_type; /* socket type */
+ int sock_protocol; /* socket protocol */
+ int port; /* port */
+ connection_trigger trigger; /* connection trigger */
+ int timeout; /* connection timeout */
+ int timeout_cnt; /* connection timeout counter */
+
+ DltClient client; /* DltClient structure */
+} DltGatewayConnection;
+
+/* DltGateway structure */
+typedef struct
+{
+ DltGatewayConnection *connections; /* pointer to connections */
+ int num_connections; /* number of connections */
+} DltGateway;
+
+#endif /* DLT_GATEWAY_TYPES_H_ */