summaryrefslogtreecommitdiff
path: root/src/daemon/dlt-daemon.c
diff options
context:
space:
mode:
authorChristoph Lipka <clipka@jp.adit-jv.com>2015-11-18 19:19:22 +0900
committerLutz Helwing <lutz_helwing@mentor.com>2015-11-24 09:48:41 +0100
commitda4ac57d87108d8b2690979c273c000a798a59f5 (patch)
tree45f79c0c90d3b4c9a6804d6794da5485a5f05ed3 /src/daemon/dlt-daemon.c
parent188772ea0b3479352ae93552014d45fd1bc8e804 (diff)
downloadDLT-daemon-da4ac57d87108d8b2690979c273c000a798a59f5.tar.gz
Unix socket control interface
Control applications running in the same Linux OS should be able to communicate with the DLT Daemon via a socket connection. To be able to do that, the DLT Client library need to be extended. DLT Clients connected via this UNIX socket are not handled as normal DLT Clients and no log messages will be forwarded to them. This avoids problems in situations when a control application is connected to the DLT Daemon before any other 'real' DLT Client (e.g. DLT Viewer) is connected. In this situations, all already stored log messages are flushed to the control application and therefore lost, because the control application most likely ignore all incoming messages besides the one in which it is interested in. Signed-off-by: Christoph Lipka <clipka@jp.adit-jv.com>
Diffstat (limited to 'src/daemon/dlt-daemon.c')
-rw-r--r--src/daemon/dlt-daemon.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c
index 4e6b4b4..20dda80 100644
--- a/src/daemon/dlt-daemon.c
+++ b/src/daemon/dlt-daemon.c
@@ -31,6 +31,7 @@
#include <ctype.h>
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), (), and recv() */
+#include <sys/un.h>
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
@@ -56,6 +57,7 @@
#include "dlt_daemon_common_cfg.h"
#include "dlt_daemon_socket.h"
+#include "dlt_daemon_unix_socket.h"
#include "dlt_daemon_serial.h"
#include "dlt_daemon_client.h"
@@ -229,6 +231,9 @@ int option_file_parser(DltDaemonLocal *daemon_local)
memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
daemon_local->flags.sendTimezone = 0;
daemon_local->flags.offlineLogstorageMaxDevices = 0;
+ strncpy(daemon_local->flags.ctrlSockPath,
+ DLT_DAEMON_DEFAULT_CTRL_SOCK_PATH,
+ sizeof(daemon_local->flags.ctrlSockPath) - 1);
/* open configuration file */
if(daemon_local->flags.cvalue[0])
@@ -420,6 +425,17 @@ int option_file_parser(DltDaemonLocal *daemon_local)
{
daemon_local->flags.offlineLogstorageMaxDevices = atoi(value);
}
+ else if(strcmp(token,"ControlSocketPath")==0)
+ {
+ memset(
+ daemon_local->flags.ctrlSockPath,
+ 0,
+ DLT_DAEMON_FLAG_MAX);
+ strncpy(
+ daemon_local->flags.ctrlSockPath,
+ value,
+ DLT_DAEMON_FLAG_MAX-1);
+ }
else
{
fprintf(stderr, "Unknown option: %s=%s\n",token,value);
@@ -753,6 +769,12 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in
dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
return -1;
}
+ if (dlt_receiver_init(&(daemon_local->receiverCtrlSock),
+ daemon_local->ctrlsock, DLT_DAEMON_RCVBUFSIZESOCK)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize receiver for control socket\n");
+ return -1;
+ }
if (daemon_local->flags.yvalue[0])
{
if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL) == DLT_RETURN_ERROR)
@@ -939,6 +961,16 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon,
return -1;
}
+ /* create and open unix socket to receive incoming connections from
+ * control application */
+ if (dlt_daemon_unix_socket_open(
+ &(daemon_local->ctrlsock),
+ daemon_local->flags.ctrlSockPath))
+ {
+ dlt_log(LOG_ERR, "Could not initialize control socket.\n");
+ return -1;
+ }
+
/* Init serial */
if (dlt_daemon_init_serial(daemon_local) < 0)
{
@@ -1502,6 +1534,136 @@ int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal
return 0;
}
+int dlt_daemon_process_control_connect(
+ DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ int verbose)
+{
+ socklen_t ctrl_size;
+ struct sockaddr_un ctrl;
+ int in_sock = -1;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ 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)
+ {
+ 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 */
+ /* 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);
+
+ if (dlt_connection_create(daemon_local,
+ &daemon_local->pEvent,
+ in_sock,
+ EPOLLIN,
+ DLT_CONNECTION_CONTROL_MSG))
+ {
+ dlt_log(LOG_ERR, "Failed to register new client. \n");
+ /* TODO: Perform clean-up */
+ return -1;
+ }
+
+ if (verbose)
+ {
+ snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "New connection to client established, #connections: %d\n",
+ daemon_local->client_connections);
+ dlt_log(LOG_INFO, str);
+ }
+
+ return 0;
+}
+
+// FIXME: More or less copy of dlt_daemon_process_control_messages
+int dlt_daemon_process_control_messages(
+ DltDaemon *daemon,
+ DltDaemonLocal *daemon_local,
+ int verbose)
+{
+ int bytes_to_be_removed=0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ 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)
+ {
+ dlt_daemon_close_socket(daemon_local->receiverCtrlSock.fd,
+ daemon,
+ daemon_local,
+ verbose);
+ daemon_local->receiverCtrlSock.fd = -1;
+ /* FIXME: Why the hell do we need to close the socket
+ * on control message reception ??
+ */
+ //return 0;
+ }
+
+ /* Process all received messages */
+ while (dlt_message_read(
+ &(daemon_local->msg),
+ (uint8_t*)daemon_local->receiverCtrlSock.buf,
+ daemon_local->receiverCtrlSock.bytesRcvd,
+ daemon_local->flags.nflag,
+ daemon_local->flags.vflag) == DLT_MESSAGE_ERROR_OK)
+ {
+ /* Check for control message */
+ if (daemon_local->receiverCtrlSock.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);
+ }
+
+ 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);
+ }
+ if (daemon_local->msg.resync_offset)
+ {
+ bytes_to_be_removed += daemon_local->msg.resync_offset;
+ }
+
+ if (dlt_receiver_remove(&(daemon_local->receiverCtrlSock),bytes_to_be_removed)==-1)
+ {
+ 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)
+ {
+ dlt_log(LOG_WARNING,"Can't move bytes to beginning of receiver buffer for sockets\n");
+ return -1;
+ }
+
+ return 0;
+}
+
int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
{
int offset=0;