diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | include/dlt/dlt_common.h | 40 | ||||
-rw-r--r-- | include/dlt/dlt_protocol.h | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/console/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/console/dlt-passive-node-ctrl.c | 457 | ||||
-rw-r--r-- | src/daemon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/daemon/dlt-daemon.c | 365 | ||||
-rw-r--r-- | src/daemon/dlt-daemon.h | 26 | ||||
-rw-r--r-- | src/daemon/dlt.conf | 5 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_client.c | 221 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_client.h | 26 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_connection.c | 24 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_connection_types.h | 6 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_event_handler.c | 9 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_event_handler_types.h | 1 | ||||
-rw-r--r-- | src/gateway/CMakeLists.txt | 22 | ||||
-rw-r--r-- | src/gateway/dlt_gateway.c | 1052 | ||||
-rw-r--r-- | src/gateway/dlt_gateway.conf | 9 | ||||
-rw-r--r-- | src/gateway/dlt_gateway.h | 169 | ||||
-rw-r--r-- | src/gateway/dlt_gateway_types.h | 106 |
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_ */ |