- unification of HAL with lib60870

pull/71/head
Michael Zillgith 7 years ago
parent c36050f455
commit dc4fbd76ad

@ -1,7 +1,7 @@
/* /*
* socket_hal.h * socket_hal.h
* *
* Copyright 2013, 2014 Michael Zillgith * Copyright 2013-2018 Michael Zillgith
* *
* This file is part of libIEC61850. * This file is part of libIEC61850.
* *
@ -27,11 +27,21 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
/**
* \file hal_socket.h
* \brief Abstraction layer TCP/IP sockets
* Has to be implemented for CS 104 TCP/IP.
*/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/*! \addtogroup hal Platform (Hardware/OS) abstraction layer /*! \defgroup hal Platform (Hardware/OS) abstraction layer
*
* Platform abstraction layer. These functions have to be implemented when the library is
* to be ported to new platforms. It might not be required to implement all interfaces
* depending on the required library features.
* *
* @{ * @{
*/ */
@ -40,7 +50,7 @@ extern "C" {
* @defgroup HAL_SOCKET Interface to the TCP/IP stack (abstract socket layer) * @defgroup HAL_SOCKET Interface to the TCP/IP stack (abstract socket layer)
* *
* Thread and Socket abstraction layer. This functions have to be implemented to * Thread and Socket abstraction layer. This functions have to be implemented to
* port libIEC61850 to a new hardware/OS platform. * port lib60870 to a new hardware/OS platform when TCP/IP is required.
* *
* @{ * @{
*/ */
@ -63,7 +73,13 @@ HandleSet
Handleset_new(void); Handleset_new(void);
/** /**
* \brief add a socket to an existing handle set * \brief Reset the handle set for reuse
*/
void
Handleset_reset(HandleSet self);
/**
* \brief add a soecket to an existing handle set
* *
* \param self the HandleSet instance * \param self the HandleSet instance
* \param sock the socket to add * \param sock the socket to add
@ -75,7 +91,10 @@ Handleset_addSocket(HandleSet self, const Socket sock);
* \brief wait for a socket to become ready * \brief wait for a socket to become ready
* *
* This function is corresponding to the BSD socket select function. * This function is corresponding to the BSD socket select function.
* The function will return after \p timeoutMs ms if no data is pending. * It returns the number of sockets on which data is pending or 0 if no data is pending
* on any of the monitored connections. The function will return after "timeout" ms if no
* data is pending.
* The function shall return -1 if a socket error occures.
* *
* \param self the HandleSet instance * \param self the HandleSet instance
* \param timeout in milliseconds (ms) * \param timeout in milliseconds (ms)
@ -188,7 +207,7 @@ Socket_setConnectTimeout(Socket self, uint32_t timeoutInMs);
* \param address the IP address or hostname as C string * \param address the IP address or hostname as C string
* \param port the TCP port of the application to connect to * \param port the TCP port of the application to connect to
* *
* \return a new client socket instance. * \return true if the connection was established successfully, false otherwise
*/ */
bool bool
Socket_connect(Socket self, const char* address, int port); Socket_connect(Socket self, const char* address, int port);
@ -229,7 +248,7 @@ Socket_write(Socket self, uint8_t* buf, int size);
* *
* The peer address has to be returned as * The peer address has to be returned as
* *
* Implementation of this function is MANDATORY * Implementation of this function is MANDATORY (libiec61850)
* *
* \param self the client, connection or server socket instance * \param self the client, connection or server socket instance
* *
@ -238,6 +257,23 @@ Socket_write(Socket self, uint8_t* buf, int size);
char* char*
Socket_getPeerAddress(Socket self); Socket_getPeerAddress(Socket self);
/**
* \brief Get the address of the peer application (IP address and port number)
*
* The peer address has to be returned as
*
* Implementation of this function is MANDATORY (lib60870)
*
* \param self the client, connection or server socket instance
* \param peerAddressString a string to store the peer address (the string should have space
* for at least 60 characters)
*
* \return the IP address and port number as strings separated by the ':' character. If the
* address is an IPv6 address the IP part is encapsulated in square brackets.
*/
char*
Socket_getPeerAddressStatic(Socket self, char* peerAddressString);
/** /**
* \brief destroy a socket (close the socket if a connection is established) * \brief destroy a socket (close the socket if a connection is established)
* *

@ -32,6 +32,10 @@
extern "C" { extern "C" {
#endif #endif
/**
* \file hal_thread.h
* \brief Abstraction layer for threading and synchronization
*/
/*! \addtogroup hal /*! \addtogroup hal
* *

@ -28,6 +28,10 @@
extern "C" { extern "C" {
#endif #endif
/**
* \file hal_time.h
* \brief Abstraction layer for system time access
*/
/*! \addtogroup hal /*! \addtogroup hal
* *
@ -48,7 +52,8 @@ extern "C" {
* *
* \return the system time with millisecond resolution. * \return the system time with millisecond resolution.
*/ */
uint64_t Hal_getTimeInMs(void); uint64_t
Hal_getTimeInMs(void);
/*! @} */ /*! @} */

@ -70,6 +70,14 @@ Handleset_new(void)
return result; return result;
} }
void
Handleset_reset(HandleSet self)
{
FD_ZERO(&self->handles);
self->maxHandle = -1;
}
void void
Handleset_addSocket(HandleSet self, const Socket sock) Handleset_addSocket(HandleSet self, const Socket sock)
{ {
@ -105,6 +113,7 @@ Handleset_destroy(HandleSet self)
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
} }
#if (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1)
static void static void
activateKeepAlive(int sd) activateKeepAlive(int sd)
{ {
@ -127,6 +136,7 @@ activateKeepAlive(int sd)
#endif /* SO_KEEPALIVE */ #endif /* SO_KEEPALIVE */
} }
#endif /* (CONFIG_ACTIVATE_TCP_KEEPALIVE == 1) */
static bool static bool
prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr) prepareServerAddress(const char* address, int port, struct sockaddr_in* sockaddr)
@ -348,11 +358,45 @@ Socket_getPeerAddress(Socket self)
return clientConnection; return clientConnection;
} }
char*
Socket_getPeerAddressStatic(Socket self, char* peerAddressString)
{
struct sockaddr_storage addr;
socklen_t addrLen = sizeof(addr);
getpeername(self->fd, (struct sockaddr*) &addr, &addrLen);
char addrString[INET6_ADDRSTRLEN + 7];
int port;
bool isIPv6;
if (addr.ss_family == AF_INET) {
struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr;
port = ntohs(ipv4Addr->sin_port);
inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN);
isIPv6 = false;
}
else if (addr.ss_family == AF_INET6) {
struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr;
port = ntohs(ipv6Addr->sin6_port);
inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN);
isIPv6 = true;
}
else
return NULL ;
if (isIPv6)
sprintf(peerAddressString, "[%s]:%i", addrString, port);
else
sprintf(peerAddressString, "%s:%i", addrString, port);
return peerAddressString;
}
int int
Socket_read(Socket self, uint8_t* buf, int size) Socket_read(Socket self, uint8_t* buf, int size)
{ {
assert(self != NULL);
if (self->fd == -1) if (self->fd == -1)
return -1; return -1;

@ -24,6 +24,7 @@
#include "hal_socket.h" #include "hal_socket.h"
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/select.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
@ -70,6 +71,13 @@ Handleset_new(void)
return result; return result;
} }
void
Handleset_reset(HandleSet self)
{
FD_ZERO(&self->handles);
self->maxHandle = -1;
}
void void
Handleset_addSocket(HandleSet self, const Socket sock) Handleset_addSocket(HandleSet self, const Socket sock)
{ {
@ -197,7 +205,7 @@ TcpServerSocket_create(const char* address, int port)
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &optionReuseAddr, sizeof(int)); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &optionReuseAddr, sizeof(int));
if (bind(fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) >= 0) { if (bind(fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) >= 0) {
serverSocket = GLOBAL_MALLOC(sizeof(struct sServerSocket)); serverSocket = (ServerSocket) GLOBAL_MALLOC(sizeof(struct sServerSocket));
serverSocket->fd = fd; serverSocket->fd = fd;
serverSocket->backLog = 0; serverSocket->backLog = 0;
@ -281,7 +289,7 @@ ServerSocket_destroy(ServerSocket self)
Socket Socket
TcpSocket_create() TcpSocket_create()
{ {
Socket self = GLOBAL_MALLOC(sizeof(struct sSocket)); Socket self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket));
self->fd = -1; self->fd = -1;
self->connectTimeout = 5000; self->connectTimeout = 5000;
@ -374,7 +382,7 @@ Socket_getPeerAddress(Socket self)
else else
return NULL ; return NULL ;
char* clientConnection = GLOBAL_MALLOC(strlen(addrString) + 9); char* clientConnection = (char*) GLOBAL_MALLOC(strlen(addrString) + 9);
if (isIPv6) if (isIPv6)
@ -385,11 +393,45 @@ Socket_getPeerAddress(Socket self)
return clientConnection; return clientConnection;
} }
char*
Socket_getPeerAddressStatic(Socket self, char* peerAddressString)
{
struct sockaddr_storage addr;
socklen_t addrLen = sizeof(addr);
getpeername(self->fd, (struct sockaddr*) &addr, &addrLen);
char addrString[INET6_ADDRSTRLEN + 7];
int port;
bool isIPv6;
if (addr.ss_family == AF_INET) {
struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr;
port = ntohs(ipv4Addr->sin_port);
inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN);
isIPv6 = false;
}
else if (addr.ss_family == AF_INET6) {
struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr;
port = ntohs(ipv6Addr->sin6_port);
inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN);
isIPv6 = true;
}
else
return NULL ;
if (isIPv6)
sprintf(peerAddressString, "[%s]:%i", addrString, port);
else
sprintf(peerAddressString, "%s:%i", addrString, port);
return peerAddressString;
}
int int
Socket_read(Socket self, uint8_t* buf, int size) Socket_read(Socket self, uint8_t* buf, int size)
{ {
assert(self != NULL);
if (self->fd == -1) if (self->fd == -1)
return -1; return -1;

@ -70,6 +70,13 @@ Handleset_new(void)
return result; return result;
} }
void
Handleset_reset(HandleSet self)
{
FD_ZERO(&self->handles);
self->maxHandle = INVALID_SOCKET;
}
void void
Handleset_addSocket(HandleSet self, const Socket sock) Handleset_addSocket(HandleSet self, const Socket sock)
{ {
@ -396,6 +403,47 @@ Socket_getPeerAddress(Socket self)
return clientConnection; return clientConnection;
} }
char*
Socket_getPeerAddressStatic(Socket self, char* peerAddressString)
{
struct sockaddr_storage addr;
int addrLen = sizeof(addr);
getpeername(self->fd, (struct sockaddr*) &addr, &addrLen);
char addrString[INET6_ADDRSTRLEN + 7];
int addrStringLen = INET6_ADDRSTRLEN + 7;
int port;
bool isIPv6;
if (addr.ss_family == AF_INET) {
struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr;
port = ntohs(ipv4Addr->sin_port);
ipv4Addr->sin_port = 0;
WSAAddressToString((LPSOCKADDR) ipv4Addr, sizeof(struct sockaddr_storage), NULL,
(LPSTR) addrString, (LPDWORD) & addrStringLen);
isIPv6 = false;
}
else if (addr.ss_family == AF_INET6) {
struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr;
port = ntohs(ipv6Addr->sin6_port);
ipv6Addr->sin6_port = 0;
WSAAddressToString((LPSOCKADDR) ipv6Addr, sizeof(struct sockaddr_storage), NULL,
(LPSTR) addrString, (LPDWORD) & addrStringLen);
isIPv6 = true;
}
else
return NULL;
if (isIPv6)
sprintf(peerAddressString, "[%s]:%i", addrString, port);
else
sprintf(peerAddressString, "%s:%i", addrString, port);
return peerAddressString;
}
int int
Socket_read(Socket self, uint8_t* buf, int size) Socket_read(Socket self, uint8_t* buf, int size)
{ {

Loading…
Cancel
Save