summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md1
-rw-r--r--doc/dlt.conf.5.md12
-rw-r--r--src/daemon/CMakeLists.txt9
-rw-r--r--src/daemon/dlt-daemon.c49
-rw-r--r--src/daemon/dlt-daemon.h5
-rw-r--r--src/daemon/dlt.conf12
-rw-r--r--src/daemon/dlt_daemon_client.c15
-rw-r--r--src/daemon/dlt_daemon_common.h9
-rw-r--r--src/daemon/udp_connection/dlt_daemon_udp_common_socket.h73
-rw-r--r--src/daemon/udp_connection/dlt_daemon_udp_socket.c258
-rw-r--r--src/daemon/udp_connection/dlt_daemon_udp_socket.h32
-rw-r--r--src/examples/CMakeLists.txt13
-rw-r--r--src/examples/dlt-example-multicast-clientmsg-view.c197
14 files changed, 684 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index baf0f34..b303f29 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,6 +78,7 @@ option(WITH_DLT_LOGSTORAGE_CTRL_UDEV "PROTOTYPE! Set to ON to build logstorage c
option(WITH_DLT_USE_IPv6 "Set to ON for IPv6 support" ON)
option(WITH_DLT_KPI "Set to ON to build src/kpi binaries" OFF)
option(WITH_DLT_FATAL_LOG_TRAP "Set to ON to enable DLT_LOG_FATAL trap(trigger segv inside dlt-user library)" OFF)
+option(WITH_UDP_CONNECTION "Set to ON to enable dlt UDP multicast SUPPORT" ON)
# RPM settings
set(GENIVI_RPM_RELEASE "1") # ${DLT_REVISION}")
@@ -262,6 +263,7 @@ message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR = ${CMAKE_HOST_SYSTEM_PROCESSOR}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "WITH_DLT_LOGSTORAGE_CTRL_UDEV = ${WITH_DLT_LOGSTORAGE_CTRL_UDEV}")
message(STATUS "DLT_IPC = ${DLT_IPC}(Path: ${DLT_USER_IPC_PATH})")
+message(STATUS "WITH_UDP_CONNECTION = ${WITH_UDP_CONNECTION}")
message(STATUS "Change a value with: cmake -D<Variable>=<Value>")
message(STATUS "-------------------------------------------------------------------------------")
message(STATUS)
diff --git a/README.md b/README.md
index b2644a7..9adf5a7 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,7 @@ DLT\_USER | genivi | Set user for process not ru
WITH\_CHECK\_CONFIG\_FILE | OFF | Set to ON to create a configure file of CheckIncludeFiles and CheckFunctionExists
CMAKE\_INSTALL\_PREFIX | /usr/local
CMAKE\_BUILD\_TYPE | RelWithDebInfo
+WITH\_UDP\_CONNECTION | ON | Set to ON to enable dlt UDP multicast SUPPORT
#### Command Line Tool Options
diff --git a/doc/dlt.conf.5.md b/doc/dlt.conf.5.md
index 5142118..6dd9ee5 100644
--- a/doc/dlt.conf.5.md
+++ b/doc/dlt.conf.5.md
@@ -321,6 +321,18 @@ Maximal used memory for log storage cache in KB.
Default: 30000 KB
+## UDPConnectionSetup
+
+Enable or disable UDP connection. 0 = disabled, 1 = enabled
+
+## UDPMulticastIPAddress
+
+The address on which daemon multicasts the log messages
+
+## UDPMulticastIPPort
+
+The Multicase IP port. Default: 3491
+
# AUTHOR
Alexander Wenzel (alexander.aw.wenzel (at) bmw (dot) de)
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index b5cca17..adddee3 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -45,8 +45,6 @@ if(WITH_DLT_SHM_ENABLE)
${PROJECT_SOURCE_DIR}/src/shared/dlt_shm.c)
endif()
-add_executable(dlt-daemon ${dlt_daemon_SRCS} ${systemd_SRCS})
-
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(RT_LIBRARY rt)
set(SOCKET_LIBRARY "")
@@ -55,6 +53,13 @@ else()
set(SOCKET_LIBRARY socket)
endif()
+if(WITH_UDP_CONNECTION)
+ include_directories(${PROJECT_SOURCE_DIR}/src/daemon/udp_connection)
+ add_definitions(-DUDP_CONNECTION_SUPPORT)
+ set(dlt_daemon_SRCS ${dlt_daemon_SRCS} ${PROJECT_SOURCE_DIR}/src/daemon/udp_connection/dlt_daemon_udp_socket.c)
+endif(WITH_UDP_CONNECTION)
+
+add_executable(dlt-daemon ${dlt_daemon_SRCS} ${systemd_SRCS})
target_link_libraries(dlt-daemon ${RT_LIBRARY} ${SOCKET_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS dlt-daemon
diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c
index a06c6ae..cbb85cc 100644
--- a/src/daemon/dlt-daemon.c
+++ b/src/daemon/dlt-daemon.c
@@ -65,6 +65,9 @@
#include "dlt_daemon_offline_logstorage.h"
#include "dlt_gateway.h"
+#ifdef UDP_CONNECTION_SUPPORT
+# include "dlt_daemon_udp_socket.h"
+#endif
#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
# include "sd-daemon.h"
#endif
@@ -289,6 +292,11 @@ int option_file_parser(DltDaemonLocal *daemon_local)
daemon_local->flags.contextLogLevel = DLT_LOG_INFO;
daemon_local->flags.contextTraceStatus = DLT_TRACE_STATUS_OFF;
daemon_local->flags.enforceContextLLAndTS = 0; /* default is off */
+#ifdef UDP_CONNECTION_SUPPORT
+ daemon_local->UDPConnectionSetup = MULTICAST_CONNECTION_ENABLED;
+ strncpy(daemon_local->UDPMulticastIPAddress, MULTICASTIPADDRESS, MULTICASTIP_MAX_SIZE - 1);
+ daemon_local->UDPMulticastIPPort = MULTICASTIPPORT;
+#endif
/* open configuration file */
if (daemon_local->flags.cvalue[0])
@@ -598,6 +606,33 @@ int option_file_parser(DltDaemonLocal *daemon_local)
daemon_local->flags.daemonFifoGroup[NAME_MAX] = 0;
}
#endif
+#ifdef UDP_CONNECTION_SUPPORT
+ else if (strcmp(token, "UDPConnectionSetup") == 0)
+ {
+ const long longval = strtol(value, NULL, 10);
+
+ if ((longval == MULTICAST_CONNECTION_DISABLED)
+ || (longval == MULTICAST_CONNECTION_ENABLED)) {
+ daemon_local->UDPConnectionSetup = longval;
+ printf("Option: %s=%s\n", token, value);
+ }
+ else {
+ daemon_local->UDPConnectionSetup = MULTICAST_CONNECTION_DISABLED;
+ fprintf(stderr,
+ "Invalid value for UDPConnectionSetup set to default %ld\n",
+ longval);
+ }
+ }
+ else if (strcmp(token, "UDPMulticastIPAddress") == 0)
+ {
+ strncpy(daemon_local->UDPMulticastIPAddress, value,
+ MULTICASTIP_MAX_SIZE - 1);
+ }
+ else if (strcmp(token, "UDPMulticastIPPort") == 0)
+ {
+ daemon_local->UDPMulticastIPPort = strtol(value, NULL, 10);
+ }
+#endif
else {
fprintf(stderr, "Unknown option: %s=%s\n", token, value);
}
@@ -1204,6 +1239,20 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon,
return DLT_RETURN_ERROR;
}
+#ifdef UDP_CONNECTION_SUPPORT
+
+ if (daemon_local->UDPConnectionSetup == MULTICAST_CONNECTION_ENABLED) {
+ if (dlt_daemon_udp_connection_setup(daemon_local) < 0) {
+ dlt_log(LOG_ERR, "UDP fd creation and register in epoll failed\n");
+ return DLT_RETURN_ERROR;
+ }
+ else {
+ dlt_log(LOG_INFO, "UDP fd creation and register in epoll success\n");
+ }
+ }
+
+#endif
+
/* create and open unix socket to receive incoming connections from
* control application
* socket access permission set to srw-rw---- (660) */
diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h
index 4702b69..2520988 100644
--- a/src/daemon/dlt-daemon.h
+++ b/src/daemon/dlt-daemon.h
@@ -157,6 +157,11 @@ typedef struct
unsigned long RingbufferMaxSize;
unsigned long RingbufferStepSize;
unsigned long daemonFifoSize;
+#ifdef UDP_CONNECTION_SUPPORT
+ int UDPConnectionSetup; /* enable/disable the UDP connection */
+ char UDPMulticastIPAddress[MULTICASTIP_MAX_SIZE]; /* multicast ip addres */
+ int UDPMulticastIPPort; /* multicast port */
+#endif
} DltDaemonLocal;
typedef struct
diff --git a/src/daemon/dlt.conf b/src/daemon/dlt.conf
index 5d61ade..47e9b6d 100644
--- a/src/daemon/dlt.conf
+++ b/src/daemon/dlt.conf
@@ -183,3 +183,15 @@ ControlSocketPath = /tmp/dlt-ctrl.sock
# Maximal used memory for Logstorage Cache in KB (Default: 30000 KB)
# OfflineLogstorageCacheSize = 30000
+
+##############################################################################
+# UDP Multicast Configuration #
+##############################################################################
+# Enable UDP connection support for daemon(Control Message/Multicast is enabled)
+UDPConnectionSetup = 1
+
+# UDP multicast address(default:225.0.0.37)
+UDPMulticastIPAddress = 225.0.0.37
+
+# UDP multicast port(default:3491)
+UDPMulticastIPPort = 3491
diff --git a/src/daemon/dlt_daemon_client.c b/src/daemon/dlt_daemon_client.c
index 0d626d7..5fe0215 100644
--- a/src/daemon/dlt_daemon_client.c
+++ b/src/daemon/dlt_daemon_client.c
@@ -81,6 +81,10 @@ static inline int8_t getStatus(uint8_t request_log, int context_log)
return (request_log <= context_log) ? request_log : context_log;
}
+#ifdef UDP_CONNECTION_SUPPORT
+# include "dlt_daemon_udp_socket.h"
+#endif
+
/** @brief Sends up to 2 messages to all the clients.
*
* Runs through the client list and sends the messages to them. If the message
@@ -284,6 +288,17 @@ int dlt_daemon_client_send(int sock,
/* send messages to daemon socket */
if ((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) {
+#ifdef UDP_CONNECTION_SUPPORT
+
+ if (daemon_local->UDPConnectionSetup == MULTICAST_CONNECTION_ENABLED)
+ dlt_daemon_udp_dltmsg_multicast(data1,
+ size1,
+ data2,
+ size2,
+ verbose);
+
+#endif
+
if ((sock == DLT_DAEMON_SEND_FORCE) || (daemon->state == DLT_DAEMON_STATE_SEND_DIRECT)) {
sent = dlt_daemon_client_send_all_multiple(daemon,
daemon_local,
diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h
index 83ac640..5e1bb1b 100644
--- a/src/daemon/dlt_daemon_common.h
+++ b/src/daemon/dlt_daemon_common.h
@@ -104,6 +104,15 @@ extern "C" {
#define DLT_DAEMON_SEM_FREE() { sem_post(&dlt_daemon_mutex); }
extern sem_t dlt_daemon_mutex;
+/* UDPMulticart Default IP and Port */
+# ifdef UDP_CONNECTION_SUPPORT
+ # define MULTICASTIPADDRESS "225.0.0.37"
+ # define MULTICASTIPPORT 3491
+ # define MULTICASTIP_MAX_SIZE 256
+ # define MULTICAST_CONNECTION_DISABLED 0
+ # define MULTICAST_CONNECTION_ENABLED 1
+# endif
+
/**
* Definitions of DLT daemon logging states
*/
diff --git a/src/daemon/udp_connection/dlt_daemon_udp_common_socket.h b/src/daemon/udp_connection/dlt_daemon_udp_common_socket.h
new file mode 100644
index 0000000..1299790
--- /dev/null
+++ b/src/daemon/udp_connection/dlt_daemon_udp_common_socket.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019 LG Electronics Inc.
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ * 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/.
+ */
+
+/*!
+ * \author
+ * Guruprasad KN <guruprasad.kn@lge.com>
+ * Sachin Sudhakar Shetty <sachin.shetty@lge.com>
+ * Sunil Kovila Sampath <sunil.s@lge.com>
+ *
+ * \Copyright (c) 2019 LG Electronics Inc.
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_daemon_udp_common_socket.h
+ */
+
+#ifndef DLT_DAEMON_UDP_COMMON_SOCKET_H
+#define DLT_DAEMON_UDP_COMMON_SOCKET_H
+
+#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
+#include <errno.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <stdlib.h> /* for atoi() and exit() */
+#include <string.h> /* for memset() */
+#include <syslog.h>
+#include <sys/socket.h> /* for socket(), connect(), (), and recv() */
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
+#include <unistd.h> /* for close() */
+
+#include "dlt_common.h"
+#include "dlt-daemon.h"
+#include "dlt_daemon_common_cfg.h"
+#include "dlt_daemon_client.h"
+#include "dlt_daemon_connection.h"
+#include "dlt_daemon_udp_socket.h"
+#include "dlt_types.h"
+
+/* #define variables */
+#define ADDRESS_VALID 1
+#define ADDRESS_INVALID 0
+#define SOCKPORT_MAX_LEN 6 /* port range 0-65535 */
+#define SYSTEM_CALL_ERROR -1
+#define ZERO_BYTE_RECIEVED 0
+#define ONE_BYTE_RECIEVED 0
+
+typedef struct sockaddr_storage CLIENT_ADDR_STRUCT;
+typedef socklen_t CLIENT_ADDR_STRUCT_SIZE;
+
+/* udp strutures */
+typedef struct
+{
+ CLIENT_ADDR_STRUCT clientaddr;
+ CLIENT_ADDR_STRUCT_SIZE clientaddr_size;
+ int isvalidflag;
+} DltDaemonClientSockInfo;
+
+/* Function prototype declaration */
+void dlt_daemon_udp_init_clientstruct(DltDaemonClientSockInfo *clientinfo_struct);
+DltReturnValue dlt_daemon_udp_socket_open(int *sock, unsigned int servPort);
+void dlt_daemon_udp_setmulticast_addr(DltDaemonLocal *daemon_local);
+
+#endif /* DLT_DAEMON_UDP_COMMON_SOCKET_H */
+
diff --git a/src/daemon/udp_connection/dlt_daemon_udp_socket.c b/src/daemon/udp_connection/dlt_daemon_udp_socket.c
new file mode 100644
index 0000000..ac99d4d
--- /dev/null
+++ b/src/daemon/udp_connection/dlt_daemon_udp_socket.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2019 LG Electronics Inc.
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ * 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/.
+ */
+
+/*!
+ * \author
+ * Guruprasad KN <guruprasad.kn@lge.com>
+ * Sachin Sudhakar Shetty <sachin.shetty@lge.com>
+ * Sunil Kovila Sampath <sunil.s@lge.com>
+ *
+ * \Copyright (c) 2019 LG Electronics Inc.
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_daemon_udp_socket.c
+ */
+
+#include "dlt_daemon_udp_common_socket.h"
+
+static void dlt_daemon_udp_clientmsg_send(DltDaemonClientSockInfo *clientinfo,
+ void *data1, int size1, void *data2, int size2, int verbose);
+static int g_udp_sock_fd = -1;
+static DltDaemonClientSockInfo g_udpmulticast_addr;
+
+/* ************************************************************************** */
+/* Function : dlt_daemon_udp_init_clientstruct */
+/* In Param : UDP client_info struct to be initilzed */
+/* Out Param : NIL */
+/* Description: client struct to be initilized to copy control/connect/disconnect */
+/* client addr */
+/* ************************************************************************** */
+void dlt_daemon_udp_init_clientstruct(DltDaemonClientSockInfo *clientinfo_struct)
+{
+ if (clientinfo_struct == NULL) {
+ dlt_vlog(LOG_ERR, "%s: NULL arg\n", __func__);
+ return;
+ }
+
+ memset(&clientinfo_struct->clientaddr, 0x00, sizeof(clientinfo_struct->clientaddr));
+ clientinfo_struct->clientaddr_size = sizeof(clientinfo_struct->clientaddr);
+ clientinfo_struct->isvalidflag = ADDRESS_INVALID; /* info is invalid */
+ dlt_vlog(LOG_DEBUG, "%s: client addr struct init success \n", __func__);
+ dlt_log(LOG_INFO, "dlt_daemon_udp_init_clientstruct: client addr struct init success \n");
+}
+
+
+/* ************************************************************************** */
+/* Function : dlt_daemon_udp_setmulticast_addr */
+/* In Param : NIL */
+/* Out Param : NIL */
+/* Description: set the multicast addr to global variables */
+/* ************************************************************************** */
+void dlt_daemon_udp_setmulticast_addr(DltDaemonLocal *daemon_local)
+{
+ if (daemon_local == NULL) {
+ dlt_vlog(LOG_ERR, "%s: NULL arg\n", __func__);
+ return;
+ }
+
+ dlt_daemon_udp_init_clientstruct(&g_udpmulticast_addr);
+
+ struct sockaddr_in clientaddr;
+ clientaddr.sin_family = AF_INET;
+ inet_pton(AF_INET, daemon_local->UDPMulticastIPAddress, &clientaddr.sin_addr);
+ clientaddr.sin_port = htons(daemon_local->UDPMulticastIPPort);
+ memcpy(&g_udpmulticast_addr.clientaddr, &clientaddr, sizeof(struct sockaddr_in));
+ g_udpmulticast_addr.clientaddr_size = sizeof(g_udpmulticast_addr.clientaddr);
+ g_udpmulticast_addr.isvalidflag = ADDRESS_VALID;
+}
+
+/* ************************************************************************** */
+/* Function : dlt_daemon_udp_connection_setup */
+/* In Param : contains daemon param values used globally */
+/* Out Param : status of udp connection setup and fd registration */
+/* Description: DataGram socket fd connection is setup */
+/* fd is registered with the epoll */
+/* ************************************************************************** */
+DltReturnValue dlt_daemon_udp_connection_setup(DltDaemonLocal *daemon_local)
+{
+ int fd = DLT_FD_INIT;
+ DltReturnValue ret_val = DLT_RETURN_WRONG_PARAMETER;
+
+ if (daemon_local == NULL)
+ return ret_val;
+
+ if ((ret_val = dlt_daemon_udp_socket_open(&fd, daemon_local->flags.port)) != DLT_RETURN_OK) {
+ dlt_log(LOG_ERR, "Could not initialize udp socket.\n");
+ }
+ else {
+ /* assign to global udp fd */
+ g_udp_sock_fd = fd;
+ /* set global multicast addr */
+ dlt_daemon_udp_setmulticast_addr(daemon_local);
+ dlt_log(LOG_DEBUG, "initialize udp socket success\n");
+ }
+
+ return ret_val;
+}
+
+/* ************************************************************************** */
+/* Function : dlt_daemon_udp_socket_open */
+/* In Param : contains udp port number */
+/* Out Param : status of udp connection setup */
+/* Description: This funtion is used to setup DGRAM connection */
+/* does socket()->bind() on udp port */
+/* ************************************************************************** */
+DltReturnValue dlt_daemon_udp_socket_open(int *sock, unsigned int servPort)
+{
+ int enable_reuse_addr = 1;
+ int sockbuffer = DLT_DAEMON_RCVBUFSIZESOCK;
+ char portnumbuffer[SOCKPORT_MAX_LEN] = { 0 };
+ struct addrinfo hints;
+ struct addrinfo *servinfo = NULL;
+ struct addrinfo *addrinfo_iterator = NULL;
+ int getaddrinfo_errorcode = -1;
+
+ if (sock == NULL)
+ return DLT_RETURN_WRONG_PARAMETER;
+
+ memset(&hints, 0, sizeof hints);
+#ifdef DLT_USE_IPv6
+ hints.ai_family = AF_INET6; /* force IPv6 - will still work with IPv4 */
+#else
+ hints.ai_family = AF_INET;
+#endif
+ hints.ai_socktype = SOCK_DGRAM;/* UDP Connection */
+ hints.ai_flags = AI_PASSIVE; /* use my IP address */
+
+ snprintf(portnumbuffer, SOCKPORT_MAX_LEN, "%d", servPort);
+
+ if ((getaddrinfo_errorcode = getaddrinfo(NULL, portnumbuffer, &hints, &servinfo)) != 0) {
+ dlt_vlog(LOG_WARNING, "[%s:%d] getaddrinfo: %s\n", __func__, __LINE__,
+ gai_strerror(getaddrinfo_errorcode));
+ return DLT_RETURN_ERROR;
+ }
+
+ for (addrinfo_iterator = servinfo; addrinfo_iterator != NULL; addrinfo_iterator = addrinfo_iterator->ai_next) {
+ if ((*sock = socket(addrinfo_iterator->ai_family, addrinfo_iterator->ai_socktype,
+ addrinfo_iterator->ai_protocol)) == SYSTEM_CALL_ERROR) {
+ dlt_log(LOG_WARNING, "socket() error\n");
+ continue;
+ }
+
+ dlt_vlog(LOG_INFO,
+ "[%s:%d] Socket created - socket_family:%i socket_type:%i, protocol:%i\n",
+ __func__, __LINE__, addrinfo_iterator->ai_family,
+ addrinfo_iterator->ai_socktype, addrinfo_iterator->ai_protocol);
+
+ if (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &enable_reuse_addr, sizeof(enable_reuse_addr))
+ == SYSTEM_CALL_ERROR) {
+ dlt_vlog(LOG_WARNING, "[%s:%d] Setsockopt error %s\n", __func__, __LINE__,
+ strerror(errno));
+ close(*sock);
+ continue;
+ }
+
+ if (setsockopt(*sock, SOL_SOCKET, SO_RCVBUF, &sockbuffer, sizeof(sockbuffer))
+ == SYSTEM_CALL_ERROR) {
+ dlt_vlog(LOG_WARNING, "[%s:%d] Setsockopt error %s\n", __func__, __LINE__,
+ strerror(errno));
+ close(*sock);
+ continue;
+ }
+
+ if (bind(*sock, addrinfo_iterator->ai_addr, addrinfo_iterator->ai_addrlen)
+ == SYSTEM_CALL_ERROR) {
+ close(*sock);
+ dlt_log(LOG_WARNING, "bind() error\n");
+ continue;
+ }
+
+ break;
+ }
+
+ if (addrinfo_iterator == NULL) {
+ dlt_log(LOG_WARNING, "failed to bind socket\n");
+ return DLT_RETURN_ERROR;
+ }
+
+ freeaddrinfo(servinfo);
+
+ return DLT_RETURN_OK; /* OK */
+}
+
+/* ************************************************************************** */
+/* Function : dlt_daemon_udp_dltmsg_multicast */
+/* In Param : data bytes in dlt format */
+/* Out Param : NIL */
+/* Description: multicast UDP dlt-message packets to dlt-client */
+/* ************************************************************************** */
+void dlt_daemon_udp_dltmsg_multicast(void *data1, int size1,
+ void *data2, int size2,
+ int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ /*
+ * When UDP Buffer is implemented then data2 would be expected to be NULL
+ * as the data comes from buffer directly. In that case data2 should
+ * not be checked for NULL
+ */
+ if ((data1 == NULL) || (data2 == NULL)) {
+ dlt_vlog(LOG_ERR, "%s: NULL arg\n", __func__);
+ return;
+ }
+
+ dlt_daemon_udp_clientmsg_send(&g_udpmulticast_addr, data1, size1,
+ data2, size2, verbose);
+}
+
+/* ************************************************************************** */
+/* Function : dlt_daemon_udp_clientmsg_send */
+/* In Param : data bytes & respective size in dlt format */
+/* Out Param : NIL */
+/* Description: common interface to send data via UDP protocol */
+/* ************************************************************************** */
+void dlt_daemon_udp_clientmsg_send(DltDaemonClientSockInfo *clientinfo,
+ void *data1, int size1, void *data2, int size2, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((clientinfo->isvalidflag == ADDRESS_VALID) &&
+ (size1 > 0) && (size2 > 0)) {
+ void *data = (void *)calloc(size1 + size2, sizeof(char));
+
+ if (data == NULL) {
+ dlt_vlog(LOG_ERR, "%s: calloc failure\n", __func__);
+ return;
+ }
+
+ memcpy(data, data1, size1);
+ memcpy(data + size1, data2, size2);
+
+ if (sendto(g_udp_sock_fd, data, size1 + size2, 0, (struct sockaddr *)&clientinfo->clientaddr,
+ clientinfo->clientaddr_size) < 0)
+ dlt_vlog(LOG_ERR, "%s: Send UDP Packet Data failed\n", __func__);
+
+ free(data);
+ data = NULL;
+
+ }
+ else {
+ if (clientinfo->isvalidflag != ADDRESS_VALID)
+ dlt_vlog(LOG_ERR, "%s: clientinfo->isvalidflag != ADDRESS_VALID %d\n", __func__, clientinfo->isvalidflag);
+
+ if (size1 <= 0)
+ dlt_vlog(LOG_ERR, "%s: size1 <= 0\n", __func__);
+
+ if (size2 <= 0)
+ dlt_vlog(LOG_ERR, "%s: size2 <= 0\n", __func__);
+ }
+}
diff --git a/src/daemon/udp_connection/dlt_daemon_udp_socket.h b/src/daemon/udp_connection/dlt_daemon_udp_socket.h
new file mode 100644
index 0000000..96d33aa
--- /dev/null
+++ b/src/daemon/udp_connection/dlt_daemon_udp_socket.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 LG Electronics Inc.
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ * 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/.
+ */
+
+/*!
+ * \author
+ * Guruprasad KN <guruprasad.kn@lge.com>
+ * Sachin Sudhakar Shetty <sachin.shetty@lge.com>
+ * Sunil Kovila Sampath <sunil.s@lge.com>
+ *
+ * \Copyright (c) 2019 LG Electronics Inc.
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt_daemon_udp_socket.h
+ */
+
+#ifndef DLT_DAEMON_UDP_SOCKET_H
+#define DLT_DAEMON_UDP_SOCKET_H
+
+#include "dlt-daemon.h"
+
+DltReturnValue dlt_daemon_udp_connection_setup(DltDaemonLocal *daemon_local);
+void dlt_daemon_udp_dltmsg_multicast(void *data1, int size1, void *data2, int size2,
+ int verbose);
+#endif /* DLT_DAEMON_UDP_SOCKET_H */
diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt
index 8e6f390..93f76a8 100644
--- a/src/examples/CMakeLists.txt
+++ b/src/examples/CMakeLists.txt
@@ -33,7 +33,18 @@ add_executable( dlt-example-filetransfer ${dlt_example_filetransfer_SRCS})
target_link_libraries(dlt-example-filetransfer dlt )
set_target_properties(dlt-example-filetransfer PROPERTIES LINKER_LANGUAGE C)
+if(WITH_UDP_CONNECTION)
+ set(dlt-example-multicast-clientmsg-view_SRCS dlt-example-multicast-clientmsg-view.c)
+ add_executable(dlt-example-multicast-clientmsg-view ${dlt-example-multicast-clientmsg-view_SRCS} ${dlt_most_SRCS})
+ target_link_libraries(dlt-example-multicast-clientmsg-view dlt )
+ set_target_properties(dlt-example-multicast-clientmsg-view PROPERTIES LINKER_LANGUAGE C)
+
+ install(TARGETS dlt-example-multicast-clientmsg-view
+ RUNTIME DESTINATION bin
+ COMPONENT base)
+
+endif(WITH_UDP_CONNECTION)
+
install(TARGETS dlt-example-user dlt-example-user-func dlt-example-user-common-api dlt-example-filetransfer
RUNTIME DESTINATION bin
COMPONENT base)
-
diff --git a/src/examples/dlt-example-multicast-clientmsg-view.c b/src/examples/dlt-example-multicast-clientmsg-view.c
new file mode 100644
index 0000000..aa3d5af
--- /dev/null
+++ b/src/examples/dlt-example-multicast-clientmsg-view.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2019 LG Electronics Inc.
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
+ * 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/.
+ */
+
+/*!
+ * \author
+ * Guruprasad KN <guruprasad.kn@lge.com>
+ * Sachin Sudhakar Shetty <sachin.shetty@lge.com>
+ * Sunil Kovila Sampath <sunil.s@lge.com>
+ *
+ * \Copyright (c) 2019 LG Electronics Inc.
+ * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
+ *
+ * \file dlt-example-multicast-clientmsg-view.c
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h> /* for isprint() */
+#include <stdlib.h> /* for atoi() */
+#include <sys/stat.h> /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */
+#include <fcntl.h> /* for open() */
+#include <sys/uio.h> /* for writev() */
+#include <errno.h>
+#include <string.h>
+#include <glob.h>
+#include <syslog.h>
+#include <linux/limits.h> /* for PATH_MAX */
+#include <inttypes.h>
+
+#include "dlt_client.h"
+#include "dlt_client_cfg.h"
+
+#define DLT_RECEIVE_TEXTBUFSIZE 10024
+
+#define HELLO_PORT 3491
+#define HELLO_GROUP "225.0.0.37"
+
+struct clientinfostruct
+{
+ int fd;
+ struct sockaddr_in addr;
+ socklen_t addlen;
+ DltReceiver receiver;
+};
+
+int dlt_receiver_receive_socket_udp(struct clientinfostruct *clientinfo, DltReceiver *receiver)
+{
+ if ((receiver == NULL) || (clientinfo == NULL)) {
+ printf("NULL receiver or clientinfo in dlt_receiver_receive_socket_udp\n");
+ return -1;
+ }
+
+ if (receiver->buffer == NULL) {
+ printf("NULL receiver->buffer in dlt_receiver_receive_socket_udp\n");
+ return -1;
+ }
+
+ receiver->buf = (char *)receiver->buffer;
+ receiver->lastBytesRcvd = receiver->bytesRcvd;
+
+ /* wait for data from socket */
+ unsigned int addrlen = sizeof(clientinfo->addr);
+
+ if ((receiver->bytesRcvd = recvfrom(clientinfo->fd,
+ receiver->buf + receiver->lastBytesRcvd,
+ receiver->buffersize - receiver->lastBytesRcvd,
+ 0,
+ (struct sockaddr *)&(clientinfo->addr), &addrlen))
+ <= 0) {
+ printf("Error\n");
+ perror("recvfrom");
+ receiver->bytesRcvd = 0;
+ return receiver->bytesRcvd;
+ } /* if */
+
+ receiver->totalBytesRcvd += receiver->bytesRcvd;
+ receiver->bytesRcvd += receiver->lastBytesRcvd;
+
+ return receiver->bytesRcvd;
+}
+
+int dlt_receive_message_callback_udp(DltMessage *message)
+{
+ static char text[DLT_RECEIVE_TEXTBUFSIZE];
+
+ if ((message == NULL)) {
+ printf("NULL message in dlt_receive_message_callback_udp\n");
+ return -1;
+ }
+
+ /* prepare storage header */
+ if (DLT_IS_HTYP_WEID(message->standardheader->htyp))
+ dlt_set_storageheader(message->storageheader, message->headerextra.ecu);
+ else
+ dlt_set_storageheader(message->storageheader, "ECU1");
+
+ dlt_message_header(message, text, DLT_RECEIVE_TEXTBUFSIZE, 0);
+
+ printf("%s ", text);
+
+ dlt_message_payload(message, text, DLT_RECEIVE_TEXTBUFSIZE, DLT_OUTPUT_ASCII, 0);
+
+ printf("[%s]\n", text);
+
+ return 0;
+}
+
+
+int main()
+{
+ struct clientinfostruct clientinfo;
+ struct ip_mreq mreq;
+
+ u_int yes = 1;
+
+ /* create what looks like an ordinary UDP socket */
+ if ((clientinfo.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ /* allow multiple sockets to use the same PORT number */
+ if (setsockopt(clientinfo.fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
+ perror("Reusing ADDR failed");
+ exit(1);
+ }
+
+ /* set up destination address */
+ memset(&clientinfo.addr, 0, sizeof(clientinfo.addr));
+ clientinfo.addr.sin_family = AF_INET;
+ clientinfo.addr.sin_addr.s_addr = htonl(INADDR_ANY); /* N.B.: differs from sender */
+ clientinfo.addr.sin_port = htons(HELLO_PORT);
+
+ /* bind to receive address */
+ if (bind(clientinfo.fd, (struct sockaddr *)&clientinfo.addr, sizeof(clientinfo.addr)) < 0) {
+ perror("bind");
+ exit(1);
+ }
+
+ /* use setsockopt() to request that the kernel join a multicast group */
+ mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP);
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if (setsockopt(clientinfo.fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
+ perror("setsockopt");
+ exit(1);
+ }
+
+ DltMessage msg;
+
+ if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
+ return DLT_RETURN_ERROR;
+
+ if (dlt_receiver_init(&(clientinfo.receiver), clientinfo.fd,
+ DLT_RECEIVE_BUFSIZE) != DLT_RETURN_OK)
+ return DLT_RETURN_ERROR;
+
+ printf("Waiting for message on ip %s port : %d\n", HELLO_GROUP, HELLO_PORT);
+
+ while (1) {
+ /* wait for data from socket */
+ dlt_receiver_receive_socket_udp(&clientinfo, &(clientinfo.receiver));
+
+ while (dlt_message_read(&msg, (unsigned char *)(clientinfo.receiver.buf),
+ clientinfo.receiver.bytesRcvd, 0, 0) == DLT_MESSAGE_ERROR_OK) {
+ dlt_receive_message_callback_udp(&msg);
+
+ if (dlt_receiver_remove(&(clientinfo.receiver),
+ msg.headersize + msg.datasize - sizeof(DltStorageHeader))
+ == DLT_RETURN_ERROR) {
+ /* Return value ignored */
+ dlt_message_free(&msg, 0);
+ return DLT_RETURN_ERROR;
+ }
+ }
+
+ if (dlt_receiver_move_to_begin(&(clientinfo.receiver)) == DLT_RETURN_ERROR) {
+ /* Return value ignored */
+ dlt_message_free(&msg, 0);
+ return DLT_RETURN_ERROR;
+ }
+ }
+}
+