diff options
author | baduras <baduras@gmail.com> | 2018-01-12 12:21:07 +0100 |
---|---|---|
committer | Christoph Lipka <clipka@users.noreply.github.com> | 2018-01-12 12:21:07 +0100 |
commit | f355ad238fb769c295e5820eb9af6a56a7afa593 (patch) | |
tree | 126d28f1f431c0e90d9eeb8f74dbbab42ebe35de /src | |
parent | 166e6e17523051f03f79616d511a9f59d613ab97 (diff) | |
download | DLT-daemon-f355ad238fb769c295e5820eb9af6a56a7afa593.tar.gz |
Prevention for occasional corrupted messages (#26)
Prevention for occasional corrupted messages caused mostly due to system high load.
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon/dlt_daemon_connection.c | 22 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_socket.c | 46 | ||||
-rw-r--r-- | src/daemon/dlt_daemon_socket.h | 9 |
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 */ |