summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaduras <baduras@gmail.com>2018-01-12 12:21:07 +0100
committerChristoph Lipka <clipka@users.noreply.github.com>2018-01-12 12:21:07 +0100
commitf355ad238fb769c295e5820eb9af6a56a7afa593 (patch)
tree126d28f1f431c0e90d9eeb8f74dbbab42ebe35de
parent166e6e17523051f03f79616d511a9f59d613ab97 (diff)
downloadDLT-daemon-f355ad238fb769c295e5820eb9af6a56a7afa593.tar.gz
Prevention for occasional corrupted messages (#26)
Prevention for occasional corrupted messages caused mostly due to system high load.
-rw-r--r--src/daemon/dlt_daemon_connection.c22
-rw-r--r--src/daemon/dlt_daemon_socket.c46
-rw-r--r--src/daemon/dlt_daemon_socket.h9
3 files changed, 56 insertions, 21 deletions
diff --git a/src/daemon/dlt_daemon_connection.c b/src/daemon/dlt_daemon_connection.c
index 8d2aa67..58b8a72 100644
--- a/src/daemon/dlt_daemon_connection.c
+++ b/src/daemon/dlt_daemon_connection.c
@@ -46,6 +46,7 @@
#include "dlt_daemon_common.h"
#include "dlt_common.h"
#include "dlt_gateway.h"
+#include "dlt_daemon_socket.h"
static DltConnectionId connectionId;
@@ -76,12 +77,14 @@ STATIC int dlt_connection_send(DltConnection *conn,
switch (type)
{
- case DLT_CONNECTION_CLIENT_MSG_SERIAL:
- return write(conn->receiver->fd, msg, msg_size);
+ case DLT_CONNECTION_CLIENT_MSG_SERIAL:
+ if(write(conn->receiver->fd, msg, msg_size) > 0)
+ return DLT_DAEMON_ERROR_OK;
+ return DLT_DAEMON_ERROR_UNKNOWN;
case DLT_CONNECTION_CLIENT_MSG_TCP:
- return send(conn->receiver->fd, msg, msg_size, 0);
+ return dlt_daemon_socket_sendreliable(conn->receiver->fd, msg, msg_size);
default:
- return -1;
+ return DLT_DAEMON_ERROR_UNKNOWN;
}
}
@@ -110,7 +113,7 @@ int dlt_connection_send_multiple(DltConnection *con,
if (con == NULL)
{
- return -1;
+ return DLT_DAEMON_ERROR_UNKNOWN;
}
if (sendserialheader)
@@ -120,21 +123,16 @@ int dlt_connection_send_multiple(DltConnection *con,
sizeof(dltSerialHeader));
}
- if ((data1 != NULL) && (ret >= 0))
+ if ((data1 != NULL) && (ret == DLT_RETURN_OK ))
{
ret = dlt_connection_send(con, data1, size1);
}
- if ((data2 != NULL) && (ret >= 0))
+ if ((data2 != NULL) && (ret == DLT_RETURN_OK))
{
ret = dlt_connection_send(con, data2, size2);
}
- if (ret >=0)
- {
- ret = DLT_DAEMON_ERROR_OK;
- }
-
return ret;
}
diff --git a/src/daemon/dlt_daemon_socket.c b/src/daemon/dlt_daemon_socket.c
index 686f4d6..098537f 100644
--- a/src/daemon/dlt_daemon_socket.c
+++ b/src/daemon/dlt_daemon_socket.c
@@ -145,26 +145,54 @@ int dlt_daemon_socket_close(int sock)
int dlt_daemon_socket_send(int sock,void* data1,int size1,void* data2,int size2,char serialheader)
{
/* Optional: Send serial header, if requested */
+ int ret = DLT_RETURN_OK;
if (serialheader)
{
- if ( 0 > send(sock, dltSerialHeader,sizeof(dltSerialHeader),0) )
- return DLT_DAEMON_ERROR_SEND_FAILED;
-
+ ret = dlt_daemon_socket_sendreliable(sock, (void *) dltSerialHeader, sizeof(dltSerialHeader));
+ if(ret != DLT_RETURN_OK)
+ return ret;
}
/* Send data */
- if(data1 && size1>0)
+ if(data1 != NULL && size1 > 0)
{
- if (0 > send(sock, data1,size1,0))
- return DLT_DAEMON_ERROR_SEND_FAILED;
+ ret = dlt_daemon_socket_sendreliable(sock, data1, size1);
+ if(ret != DLT_RETURN_OK)
+ return ret;
}
- if(data2 && size2>0)
+ if(data2 != NULL && size2 > 0)
{
- if (0 > send(sock, data2,size2,0))
- return DLT_DAEMON_ERROR_SEND_FAILED;
+ ret = dlt_daemon_socket_sendreliable(sock, data2, size2);
+ if(ret != DLT_RETURN_OK)
+ return ret;
}
+ return ret;
+}
+
+int dlt_daemon_socket_sendreliable(int sock, void* buffer,int message_size)
+{
+ int data_sent = 0;
+
+ while (data_sent < message_size)
+ {
+ ssize_t ret = send(sock, buffer + data_sent, message_size - data_sent, 0);
+ if (ret < 0)
+ {
+ if (errno==EINTR || errno==EAGAIN || errno==EWOULDBLOCK)
+ {
+ // Temporary error.
+ dlt_vlog(LOG_INFO,"dlt_daemon_socket_sendreliable: socket sending failed [errno: %d], trying again.\n", errno);
+ }
+ else
+ {
+ dlt_vlog(LOG_WARNING,"dlt_daemon_socket_sendreliable: socket send failed [errno: %d]!\n", errno);
+ return DLT_DAEMON_ERROR_SEND_FAILED;
+ }
+ }
+ data_sent += ret;
+ }
return DLT_DAEMON_ERROR_OK;
}
diff --git a/src/daemon/dlt_daemon_socket.h b/src/daemon/dlt_daemon_socket.h
index cc8dfb5..a7f9ca6 100644
--- a/src/daemon/dlt_daemon_socket.h
+++ b/src/daemon/dlt_daemon_socket.h
@@ -69,4 +69,13 @@ int dlt_daemon_socket_get_send_qeue_max_size(int sock);
int dlt_daemon_socket_send(int sock,void* data1,int size1,void* data2,int size2,char serialheader);
+/**
+ * @brief dlt_daemon_socket_sendreliable - sends data to socket with additional checks and resending functionality - trying to be reliable
+ * @param sock
+ * @param buffer
+ * @param message_size
+ * @return on sucess: DLT_DAEMON_ERROR_OK, on error: DLT_DAEMON_ERROR_SEND_FAILED
+ */
+int dlt_daemon_socket_sendreliable(int sock, void* buffer,int message_size);
+
#endif /* DLT_DAEMON_SOCKET_H */