diff --git a/CMakeLists.txt b/CMakeLists.txt index c4d457a7..c5c53a15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,15 +126,8 @@ set(WITH_MBEDTLS 1) endif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/third_party/mbedtls/mbedtls-2.6.0) if(WITH_MBEDTLS) -include_directories( - ${CMAKE_CURRENT_LIST_DIR}/src/tls/mbedtls - ${CMAKE_CURRENT_LIST_DIR}/third_party/mbedtls/mbedtls-2.6.0/include -) - -file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/third_party/mbedtls/mbedtls-2.6.0/library/*.c) add_definitions(-DCONFIG_MMS_SUPPORT_TLS=1) -add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h") endif(WITH_MBEDTLS) diff --git a/hal/CMakeLists.txt b/hal/CMakeLists.txt index a225a92b..1441d5ac 100644 --- a/hal/CMakeLists.txt +++ b/hal/CMakeLists.txt @@ -13,6 +13,14 @@ set(LIBHAL_VERSION_MAJOR "2") set(LIBHAL_VERSION_MINOR "0") set(LIBHAL_VERSION_PATCH "0") +# feature checks +include(CheckLibraryExists) +check_library_exists(rt clock_gettime "time.h" CONFIG_SYSTEM_HAS_CLOCK_GETTIME) + +# check if we are on a little or a big endian +include (TestBigEndian) +test_big_endian(PLATFORM_IS_BIGENDIAN) + if(WIN32) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib") diff --git a/hal/filesystem/linux/file_provider_linux.c b/hal/filesystem/linux/file_provider_linux.c index 23805da1..e9f03e87 100644 --- a/hal/filesystem/linux/file_provider_linux.c +++ b/hal/filesystem/linux/file_provider_linux.c @@ -31,7 +31,6 @@ #include #include "hal_filesystem.h" -#include "stack_config.h" #include "lib_memory.h" struct sDirectoryHandle { diff --git a/hal/filesystem/win32/file_provider_win32.c b/hal/filesystem/win32/file_provider_win32.c index 8b9a8f98..1a08e8d1 100644 --- a/hal/filesystem/win32/file_provider_win32.c +++ b/hal/filesystem/win32/file_provider_win32.c @@ -32,7 +32,6 @@ #include "hal_filesystem.h" #include "platform_endian.h" -#include "stack_config.h" #include "lib_memory.h" #include diff --git a/hal/inc/hal_socket.h b/hal/inc/hal_socket.h index 41ec55de..e1d02bb6 100644 --- a/hal/inc/hal_socket.h +++ b/hal/inc/hal_socket.h @@ -147,9 +147,21 @@ ServerSocket_listen(ServerSocket self); Socket ServerSocket_accept(ServerSocket self); +/** + * \brief active TCP keep alive for socket and set keep alive parameters + * + * NOTE: implementation is mandatory for IEC 61850 MMS + * + * \param self server socket instance + * \param idleTime time (in s) between last received message and first keep alive message + * \param interval time (in s) between subsequent keep alive messages if no ACK received + * \param count number of not missing keep alive ACKs until socket is considered dead + */ +void +Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count); /** - * \brief set the maximum number of pending connection in the queue + * \brief set the maximum number of pending connections in the queue * * Implementation of this function is OPTIONAL. * diff --git a/hal/inc/hal_time.h b/hal/inc/hal_time.h index 12164901..5ac8080e 100644 --- a/hal/inc/hal_time.h +++ b/hal/inc/hal_time.h @@ -28,6 +28,8 @@ extern "C" { #endif +#include + /** * \file hal_time.h * \brief Abstraction layer for system time access diff --git a/hal/inc/platform_endian.h b/hal/inc/platform_endian.h index 9bc7a5af..76c410af 100644 --- a/hal/inc/platform_endian.h +++ b/hal/inc/platform_endian.h @@ -1,7 +1,7 @@ /* - * endian.h + * platform_endian.h * - * Copyright 2013 Michael Zillgith + * Copyright 2013-2018 Michael Zillgith * * This file is part of libIEC61850. * @@ -24,8 +24,6 @@ #ifndef ENDIAN_H_ #define ENDIAN_H_ -#include "stack_config.h" - #ifndef PLATFORM_IS_BIGENDIAN #ifdef __GNUC__ #ifdef __BYTE_ORDER__ diff --git a/hal/socket/bsd/socket_bsd.c b/hal/socket/bsd/socket_bsd.c index 6207c71a..18079db7 100644 --- a/hal/socket/bsd/socket_bsd.c +++ b/hal/socket/bsd/socket_bsd.c @@ -1,7 +1,8 @@ /* * socket_bsd.c * - * Copyright 2013, 2014 Michael Zillgith, contributions by Michael Clausen (School of engineering Valais). + * Copyright 2013-2018 Michael Zillgith + * contributions by Michael Clausen (School of engineering Valais). * * This file is part of libIEC61850. * @@ -36,8 +37,7 @@ #include // required for TCP keepalive #include "hal_thread.h" - -#include "libiec61850_platform_includes.h" +#include "lib_memory.h" #ifndef DEBUG_SOCKET #define DEBUG_SOCKET 0 @@ -113,30 +113,28 @@ Handleset_destroy(HandleSet self) GLOBAL_FREEMEM(self); } -#if (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1) -static void -activateKeepAlive(int sd) +void +Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count) { #if defined SO_KEEPALIVE int optval; socklen_t optlen = sizeof(optval); - optval = CONFIG_TCP_KEEPALIVE_IDLE; - setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); + optval = idleTime; + setsockopt(self->fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); optval = 1; - setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &optval, optlen); + setsockopt(self->fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, optlen); #if defined TCP_KEEPCNT - optval = CONFIG_TCP_KEEPALIVE_INTERVAL; - setsockopt(sd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen); + optval = interval; + setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen); - optval = CONFIG_TCP_KEEPALIVE_CNT; - setsockopt(sd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen); + optval = count; + setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen); #endif /* TCP_KEEPCNT */ #endif /* SO_KEEPALIVE */ } -#endif /* (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1) */ static bool prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr) @@ -196,10 +194,6 @@ TcpServerSocket_create(const char* address, int port) return NULL ; } -#if CONFIG_ACTIVATE_TCP_KEEPALIVE == 1 - activateKeepAlive(fd); -#endif - setSocketNonBlocking((Socket) serverSocket); } @@ -294,10 +288,6 @@ Socket_connect(Socket self, const char* address, int port) self->fd = socket(AF_INET, SOCK_STREAM, 0); -#if CONFIG_ACTIVATE_TCP_KEEPALIVE == 1 - activateKeepAlive(self->fd); -#endif - fd_set fdSet; FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); diff --git a/hal/socket/linux/socket_linux.c b/hal/socket/linux/socket_linux.c index 2dded754..69fca6a6 100644 --- a/hal/socket/linux/socket_linux.c +++ b/hal/socket/linux/socket_linux.c @@ -32,14 +32,10 @@ #include #include #include - #include - #include // required for TCP keepalive #include "hal_thread.h" - -#include "stack_config.h" #include "lib_memory.h" #ifndef DEBUG_SOCKET @@ -115,25 +111,25 @@ Handleset_destroy(HandleSet self) GLOBAL_FREEMEM(self); } -static void -activateKeepAlive(int sd) +void +Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count) { #if defined SO_KEEPALIVE int optval; socklen_t optlen = sizeof(optval); optval = 1; - setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); + setsockopt(self->fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); #if defined TCP_KEEPCNT - optval = CONFIG_TCP_KEEPALIVE_IDLE; - setsockopt(sd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen); + optval = idleTime; + setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen); - optval = CONFIG_TCP_KEEPALIVE_INTERVAL; - setsockopt(sd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen); + optval = interval; + setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen); - optval = CONFIG_TCP_KEEPALIVE_CNT; - setsockopt(sd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen); + optval = count; + setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen); #endif /* TCP_KEEPCNT */ #endif /* SO_KEEPALIVE */ @@ -217,10 +213,6 @@ TcpServerSocket_create(const char* address, int port) close(fd); return NULL ; } - -#if CONFIG_ACTIVATE_TCP_KEEPALIVE == 1 - activateKeepAlive(fd); -#endif } return serverSocket; @@ -326,10 +318,6 @@ Socket_connect(Socket self, const char* address, int port) activateTcpNoDelay(self); -#if (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1) - activateKeepAlive(self->fd); -#endif - fcntl(self->fd, F_SETFL, O_NONBLOCK); if (connect(self->fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { diff --git a/hal/socket/win32/socket_win32.c b/hal/socket/win32/socket_win32.c index 9cfc02c6..c686ddc7 100644 --- a/hal/socket/win32/socket_win32.c +++ b/hal/socket/win32/socket_win32.c @@ -1,7 +1,7 @@ /* * socket_win32.c * - * Copyright 2013, 2014 Michael Zillgith + * Copyright 2013-2018 Michael Zillgith * * This file is part of libIEC61850. * @@ -116,25 +116,26 @@ Handleset_destroy(HandleSet self) static bool wsaStartupCalled = false; static int socketCount = 0; -static void -activateKeepAlive(SOCKET s) +void +Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count) { - struct tcp_keepalive keepalive; - DWORD retVal=0; + struct tcp_keepalive keepalive; + DWORD retVal=0; - keepalive.onoff = 1; - keepalive.keepalivetime = CONFIG_TCP_KEEPALIVE_IDLE * 1000; - keepalive.keepaliveinterval = CONFIG_TCP_KEEPALIVE_INTERVAL * 1000; + keepalive.onoff = 1; + keepalive.keepalivetime = CONFIG_TCP_KEEPALIVE_IDLE * 1000; + keepalive.keepaliveinterval = CONFIG_TCP_KEEPALIVE_INTERVAL * 1000; - if (WSAIoctl(s, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), - NULL, 0, &retVal, NULL, NULL) == SOCKET_ERROR) - { - if (DEBUG_SOCKET) + if (WSAIoctl(self->fd, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), + NULL, 0, &retVal, NULL, NULL) == SOCKET_ERROR) + { + if (DEBUG_SOCKET) printf("WIN32_SOCKET: WSAIotcl(SIO_KEEPALIVE_VALS) failed: %d\n", WSAGetLastError()); - } + } } + static void setSocketNonBlocking(Socket self) { @@ -223,10 +224,6 @@ TcpServerSocket_create(const char* address, int port) listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); -#if CONFIG_ACTIVATE_TCP_KEEPALIVE == 1 - activateKeepAlive(listen_socket); -#endif - if (listen_socket == INVALID_SOCKET) { if (DEBUG_SOCKET) printf("WIN32_SOCKET: socket failed with error: %i\n", WSAGetLastError()); @@ -335,10 +332,6 @@ Socket_connect(Socket self, const char* address, int port) self->fd = socket(AF_INET, SOCK_STREAM, 0); -#if CONFIG_ACTIVATE_TCP_KEEPALIVE == 1 - activateKeepAlive(self->fd); -#endif - setSocketNonBlocking(self); fd_set fdSet; diff --git a/hal/time/unix/time.c b/hal/time/unix/time.c index d4a1a2cd..f7951fde 100644 --- a/hal/time/unix/time.c +++ b/hal/time/unix/time.c @@ -21,10 +21,7 @@ * See COPYING file for the complete license text. */ - -#include "libiec61850_platform_includes.h" - -#include "stack_config.h" +#include "hal_time.h" #include diff --git a/hal/time/win32/time.c b/hal/time/win32/time.c index 1af39b5f..af58793f 100644 --- a/hal/time/win32/time.c +++ b/hal/time/win32/time.c @@ -21,10 +21,7 @@ * See COPYING file for the complete license text. */ - -#include "libiec61850_platform_includes.h" - -#include "stack_config.h" +#include "hal_time.h" #include diff --git a/src/common/inc/libiec61850_platform_includes.h b/src/common/inc/libiec61850_platform_includes.h index 41e12b39..f2770139 100644 --- a/src/common/inc/libiec61850_platform_includes.h +++ b/src/common/inc/libiec61850_platform_includes.h @@ -5,6 +5,8 @@ #ifndef LIBIEC61850_PLATFORM_INCLUDES_H_ #define LIBIEC61850_PLATFORM_INCLUDES_H_ +#include "stack_config.h" + #include "libiec61850_common_api.h" #include "string_utilities.h" diff --git a/src/iec61850/client/ied_connection.c b/src/iec61850/client/ied_connection.c index 269474ad..f271dadc 100644 --- a/src/iec61850/client/ied_connection.c +++ b/src/iec61850/client/ied_connection.c @@ -21,12 +21,11 @@ * See COPYING file for the complete license text. */ +#include "stack_config.h" #include "libiec61850_platform_includes.h" #include "iec61850_client.h" -#include "stack_config.h" - #include "mms_client_connection.h" #include "ied_connection_private.h" diff --git a/src/iec61850/server/model/model.c b/src/iec61850/server/model/model.c index 0b5f84b7..c6d06c6d 100644 --- a/src/iec61850/server/model/model.c +++ b/src/iec61850/server/model/model.c @@ -23,6 +23,7 @@ #include "iec61850_model.h" +#include "stack_config.h" #include "libiec61850_platform_includes.h" static void diff --git a/src/mms/iso_client/iso_client_connection.c b/src/mms/iso_client/iso_client_connection.c index 3b2e8060..4e5a315a 100644 --- a/src/mms/iso_client/iso_client_connection.c +++ b/src/mms/iso_client/iso_client_connection.c @@ -289,6 +289,13 @@ IsoClientConnection_associate(IsoClientConnection self, IsoConnectionParameters Socket_setConnectTimeout(self->socket, connectTimeoutInMs); +#if (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1) + Socket_activateTcpKeepAlive(self->socket, + CONFIG_TCP_KEEPALIVE_IDLE, + CONFIG_TCP_KEEPALIVE_INTERVAL, + CONFIG_TCP_KEEPALIVE_CNT); +#endif + if (!Socket_connect(self->socket, params->hostname, params->tcpPort)) goto returnError; diff --git a/src/mms/iso_server/iso_server.c b/src/mms/iso_server/iso_server.c index 1b5628b9..f36af1dd 100644 --- a/src/mms/iso_server/iso_server.c +++ b/src/mms/iso_server/iso_server.c @@ -342,6 +342,13 @@ setupIsoServer(IsoServer self) goto exit_function; } +#if (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1) + Socket_activateTcpKeepAlive(self->serverSocket, + CONFIG_TCP_KEEPALIVE_IDLE, + CONFIG_TCP_KEEPALIVE_INTERVAL, + CONFIG_TCP_KEEPALIVE_CNT); +#endif + ServerSocket_setBacklog((ServerSocket) self->serverSocket, BACKLOG); ServerSocket_listen((ServerSocket) self->serverSocket);