From 264169e525cc8c2c552fa689adcf3381dbf51f4f Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Tue, 17 May 2016 07:38:33 +0200 Subject: [PATCH] Initial Commit: - Create single library for all Core RedA functions/classes - Working version --- CMakeLists.txt | 3 + LogCore.cpp | 45 ++++++ LogCore.h | 29 ++++ PortCore.cpp | 272 +++++++++++++++++++++++++++++++++++ PortCore.h | 40 ++++++ SelectCore.cpp | 123 ++++++++++++++++ SelectCore.h | 28 ++++ SocketCore.cpp | 375 +++++++++++++++++++++++++++++++++++++++++++++++++ SocketCore.h | 42 ++++++ TimingCore.cpp | 51 +++++++ TimingCore.h | 25 ++++ 11 files changed, 1033 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LogCore.cpp create mode 100644 LogCore.h create mode 100644 PortCore.cpp create mode 100644 PortCore.h create mode 100644 SelectCore.cpp create mode 100644 SelectCore.h create mode 100644 SocketCore.cpp create mode 100644 SocketCore.h create mode 100644 TimingCore.cpp create mode 100644 TimingCore.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f78cffb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ +PROJECT(lib_redAcore) + +ADD_LIBRARY(redAcore LogCore.cpp TimingCore.cpp PortCore.cpp SocketCore.cpp SelectCore.cpp) diff --git a/LogCore.cpp b/LogCore.cpp new file mode 100644 index 0000000..0532713 --- /dev/null +++ b/LogCore.cpp @@ -0,0 +1,45 @@ +/* + * LogCore.cpp + * + * Created on: 17 May 2016 + * Author: wentzelc + */ + +// redA Libraries +#include "LogCore.h" + +// Standard C/C++ Libraries +#include +#include +#include +#include +#include + +//--------------------------------------------------------------------------- + +void ShowOutput( const char * Name, const char * Buffer, const int Len, const long Duration ) +{ + // Show Duration delay + if (Duration) { + printf( "Delay: %ld", Duration ); + } + + // Show Hex output + if (ShowOutBytes) { + printf( "%s in (hex): ", Name ); + for (int i=0; i +#include +#include +#include + +#include +#include +#include + +//--------------------------------------------------------------------------- + +// Port Def +int PortHandle = -1; +char * PortName = NULL; + +// PortIn buffer +char PortInBuffer[500] = ""; +int PortInBufLen = 500; +int PortInLen = 0; +int PortBytesRead = 0; + +// PortIn Timer +timeval PortInStart = { 0, 0 }; +long PortInTimeout = 100; // millisecs + +//--------------------------------------------------------------------------- + +int OpenPort( const char * pPortName ) +{ + // Copy Port name + PortName = (char*)malloc( strlen(pPortName)+ 1); + strcpy( PortName, pPortName ); + + // Check if port exits + if (access( PortName, F_OK ) != 0) + { + printf( "Port: %s -> Could not find port\n", PortName ); + return -1; + } + + // Open Port + PortHandle = open( PortName, O_RDWR ); + if (PortHandle == -1) + { + printf( "Port: %s -> Could not open port\n", PortName ); + return -1; + } + + // Confirm open + printf( "Port: %s -> Port opened\n", PortName ); + return PortHandle; +} +//--------------------------------------------------------------------------- + +bool ClosePort() +{ + int result; + + // Close port + result = close( PortHandle ); + if (result) { + printf( "Port: %s -> Port not closed properly\n", PortName ); + return false; + } + + // Port closed + printf( "Port: %s -> Port closed\n", PortName ); + return true; +} +//--------------------------------------------------------------------------- + +// Set serial port configuration parameters +bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ) +{ + struct termios newtio; + int flags = 0; + speed_t _baud = 0; + int mcs = 0; + + // Flush Data from port + tcflush( PortHandle, TCIFLUSH ); + + // Set Open flags + flags = fcntl( PortHandle, F_GETFL, 0 ); + fcntl( PortHandle, F_SETFL, flags & ~O_NDELAY ); + + // Read options + if (tcgetattr( PortHandle, &newtio ) != 0) + return false; + + // Process the baud rate + switch (Baud) + { + case 921600: _baud = B921600; break; + case 576000: _baud = B576000; break; + case 460800: _baud = B460800; break; + case 230400: _baud = B230400; break; + //case 128000: _baud = B128000; break; + case 115200: _baud = B115200; break; + //case 76800: _baud = B76800; break; + case 57600: _baud = B57600; break; + case 38400: _baud = B38400; break; + //case 28800: _baud = B28800; break; + case 19200: _baud = B19200; break; + //case 14400: _baud = B14400; break; + case 9600: _baud = B9600; break; + case 4800: _baud = B4800; break; + case 2400: _baud = B2400; break; + case 1800: _baud = B1800; break; + case 1200: _baud = B1200; break; + case 600: _baud = B600; break; + case 300: _baud = B300; break; + case 200: _baud = B200; break; + case 150: _baud = B150; break; + case 134: _baud = B134; break; + case 110: _baud = B110; break; + case 75: _baud = B75; break; + case 50: _baud = B50; break; + + default: _baud = B9600; break; + } + + // Set Baud rate + cfsetospeed( &newtio, (speed_t)_baud ); + cfsetispeed( &newtio, (speed_t)_baud ); + + // Generate Mark/Space parity + if ((DataBits == 7) && ((Parity == MARK_PARITY) || (Parity == SPACE_PARITY))) + DataBits = 8; + + // Process the data bits + newtio.c_cflag &= ~CSIZE; + switch (DataBits) + { + case 5: newtio.c_cflag |= CS5; break; + case 6: newtio.c_cflag |= CS6; break; + case 7: newtio.c_cflag |= CS7; break; + case 8: newtio.c_cflag |= CS8; break; + + default: newtio.c_cflag |= CS8; break; + } + + // Set other flags + newtio.c_cflag |= CLOCAL | CREAD; + + // Process Parity + newtio.c_cflag &= ~(PARENB | PARODD); + if (Parity == EVEN_PARITY) + newtio.c_cflag |= PARENB; + else if (Parity == ODD_PARITY) + newtio.c_cflag |= (PARENB | PARODD); + + // Flow Control (for now) + newtio.c_cflag &= ~CRTSCTS; + + // Process Stop Bits + if (StopBits == 2) + newtio.c_cflag |= CSTOPB; + else + newtio.c_cflag &= ~CSTOPB; + + newtio.c_iflag = IGNBRK; + + // Software Flow Control + if (FlowCtrl == SW_FLOWCTRL) + newtio.c_iflag |= IXON | IXOFF; + else + newtio.c_iflag &= ~(IXON | IXOFF | IXANY); + + // Set RAW input & output + newtio.c_lflag=0; + newtio.c_oflag=0; + + // Set wait parameters + newtio.c_cc[VTIME] = Wait; // Blocking: Allow at least a tenth of a second to wait for data + newtio.c_cc[VMIN] = 0; // Non-blocking: Don't set min bytes to receive + + // Set Options (first time) + //tcflush( Handle, TCIFLUSH); + if (tcsetattr( PortHandle, TCSANOW, &newtio)!=0) + return false; + + // Set Terminal options + ioctl( PortHandle, TIOCMGET, &mcs); + mcs |= TIOCM_RTS; + ioctl( PortHandle, TIOCMSET, &mcs); + + // Get Options (again) + if (tcgetattr( PortHandle, &newtio) != 0) + return false; + + // Process Hardware Flow Control + if (FlowCtrl == HW_FLOWCTRL) + newtio.c_cflag |= CRTSCTS; + else + newtio.c_cflag &= ~CRTSCTS; + + // Set Options (second time) + if (tcsetattr( PortHandle, TCSANOW, &newtio ) != 0) + { + printf( "Port: %s -> Could not configure port\n", PortName ); + return false; + } + + // Port configured + printf( "Port: %s -> Port configured\n", PortName ); + return true; +} +//--------------------------------------------------------------------------- + +bool ReadPort() +{ + // Handle read event + PortBytesRead = read( PortHandle, &PortInBuffer[PortInLen], PortInBufLen-PortInLen ); + if (PortBytesRead > 0) + { + // Process Reply + PortInLen += PortBytesRead; + + // Reset timer + SetStartTime( &PortInStart ); + } + return true; +} +//--------------------------------------------------------------------------- + +bool MaintainPort( int SocketHandle ) +{ + // Misc + long Duration = 0; + int BytesWritten = 0; + int StartWrite = 0; + + if (PortInLen > 0) + { + // Check duration since last PortIn + Duration = TimePassed( PortInStart ); + if (Duration > PortInTimeout) + { + // Handle buffer as packet + PortInBuffer[ PortInLen ] = 0; + //ShowOutput( "Port", PortInBuffer, PortInLen, Duration ); + + // Write output to Port + BytesWritten = 0; + StartWrite = 0; + while (StartWrite < PortInLen) { + BytesWritten = write( SocketHandle, &PortInBuffer[StartWrite], PortInLen ); + StartWrite += BytesWritten; + } + + // Reset buffer and timer + PortInLen = 0; + SetInterval( &PortInStart, 0 ); + } + } + return true; +} + +//--------------------------------------------------------------------------- diff --git a/PortCore.h b/PortCore.h new file mode 100644 index 0000000..e9705c8 --- /dev/null +++ b/PortCore.h @@ -0,0 +1,40 @@ +/* + * PortCore.h + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +#ifndef PORTCORE_H_ +#define PORTCORE_H_ + +// redA Libraries +/* none */ + +// Standard C/C++ Libraries +/* none */ + +//--------------------------------------------------------------------------- + +// Defines required to configure port +#define NO_PARITY 0 +#define ODD_PARITY 1 +#define EVEN_PARITY 2 +#define MARK_PARITY 3 +#define SPACE_PARITY 4 + +#define NO_FLOWCTRL 0 +#define HW_FLOWCTRL 1 +#define SW_FLOWCTRL 2 +//--------------------------------------------------------------------------- + +// Port Functions +int OpenPort( const char * PortName ); +bool ClosePort(); +bool ConfigSerialPort( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ); + +bool ReadPort(); +bool MaintainPort( int SocketHandle ); +//--------------------------------------------------------------------------- + +#endif /* PORTCORE_H_ */ diff --git a/SelectCore.cpp b/SelectCore.cpp new file mode 100644 index 0000000..81d6e6f --- /dev/null +++ b/SelectCore.cpp @@ -0,0 +1,123 @@ +/* + * Select.cpp + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +// redA Libraries +#include "TimingCore.h" +#include "SelectCore.h" + +// Standard C/C++ Libraries +#include +#include +#include +#include +#include + +//--------------------------------------------------------------------------- + +// Select Variables +fd_set ReadTestFDS; +fd_set WriteTestFDS; +fd_set ReadFDS; +fd_set WriteFDS; +int MaxFD = 0; +timeval SelectTime; + +//--------------------------------------------------------------------------- + +// Clear Select File Descriptors +void SelectClear() +{ + // Clear Select sets + FD_ZERO( &ReadTestFDS ); + FD_ZERO( &WriteTestFDS ); + + // Reset maximum File Descriptor + MaxFD = 0; +} +//--------------------------------------------------------------------------- + +// Set Select timeout +void SelectConfig( long SelectTimeout ) +{ + // Set Timeout + SetInterval( &SelectTime, SelectTimeout ); +} +//--------------------------------------------------------------------------- + +// Add Select File Descriptor +void SelectAdd( int FD, bool Read, bool Write ) +{ + // Add Read select + if (Read) + FD_SET( FD, &ReadTestFDS ); + + // Add Write Select + if (Write) + FD_SET( FD, &WriteTestFDS ); + + // Check Maximum File Handle + if (MaxFD <= FD) + MaxFD = FD+1; +} +//--------------------------------------------------------------------------- + +void SelectRemove( int FD, bool Read, bool Write ) +{ + // Remove from set for select read check + if (Read) + FD_CLR( FD, &ReadTestFDS); + + // Remove from set for select write check + if (Write) + FD_CLR( FD, &WriteTestFDS); + + // Check Maximum file handle + if (FD == MaxFD) { + for (int test = MaxFD-1; test >= 0; test--) { + if (FD_ISSET( test, &ReadTestFDS ) || FD_ISSET( test, &WriteTestFDS )) { + MaxFD = test+1; + break; + } + } + } +} +//--------------------------------------------------------------------------- + +bool SelectTest() +{ + int Result = 0; + + // Set Test sets + ReadFDS = ReadTestFDS; + WriteFDS = WriteTestFDS; + + // Perform select + Result = select( MaxFD, &ReadFDS, &WriteFDS, (fd_set*)NULL, &SelectTime ); + if (Result < 0) + { + printf( "Select operation failed (%s)\n", strerror(errno) ); + return false; + } + + // return success + return (bool)Result; +} +//--------------------------------------------------------------------------- + +// Add Select File Descriptor +bool SelectCheck( int FD, bool &Read, bool &Write ) +{ + // Add Read select + Read = (bool)(FD_ISSET( FD, &ReadFDS )); + + // Add Write Select + Write = (bool)(FD_ISSET( FD, &WriteFDS )); + + return (Read || Write); +} +//--------------------------------------------------------------------------- + diff --git a/SelectCore.h b/SelectCore.h new file mode 100644 index 0000000..858cc00 --- /dev/null +++ b/SelectCore.h @@ -0,0 +1,28 @@ +/* + * Select.h + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +#ifndef SELECTCORE_H_ +#define SELECTCORE_H_ + +// redA Libraries +/* none */ + +// Standard C/C++ Libraries +/* none */ + +//--------------------------------------------------------------------------- + +void SelectConfig( long Timeout ); +void SelectClear(); +void SelectAdd( int FD, bool Read, bool Write ); +void SelectRemove( int FD, bool Read, bool Write ); +bool SelectTest(); +bool SelectCheck( int FD, bool &Read, bool &Write ); + +//--------------------------------------------------------------------------- + +#endif /* SELECTCORE_H_ */ diff --git a/SocketCore.cpp b/SocketCore.cpp new file mode 100644 index 0000000..27d158c --- /dev/null +++ b/SocketCore.cpp @@ -0,0 +1,375 @@ +/* + * SocketCore.h + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +// redA Libraries +#include "TimingCore.h" +#include "SocketCore.h" + +// Standard C/C++ Libraries +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +//--------------------------------------------------------------------------- + +// Variables +char * ServerName = NULL; +char ServerAddress[25] = ""; +int PortNo = 0; +char ClientAddress[25] = ""; + +int ServerHandle = -1; +ESocketState ServerState = ssNone; + +int ClientHandle = -1; +ESocketState ClientState = ssNone; + +char SockInBuffer[500] = ""; +int SockInBufLen = 500; +int SockInLen = 0; + +// SockIn Timer +timeval SockInStart = { 0, 0 }; +long SockInTimeout = 100; // millisecs + +int SockBytesRead = 0; +int SockBytesWaiting = 0; + +//--------------------------------------------------------------------------- + +int OpenTCPserverSocket( const char *pName, const char *pAddress, int pPortNo, bool KeepAlive ) +{ + socklen_t addr_len; + struct sockaddr_in address; + + ServerName = (char*)malloc( strlen(pName)+1 ); + strcpy( ServerName, pName ); + strcpy( ServerAddress, pAddress ); + PortNo = pPortNo; + + // Socket options + struct linger ServerLinger_opt; + ServerLinger_opt.l_onoff = 1; + ServerLinger_opt.l_linger = 5; + + int Reuse_opt = 1; + int KeepAlive_opt = 1; + int TCPidle_opt = 60; + int TCPint_opt = 15; + int TCPcnt_opt = 3; + + // Create address + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr(ServerAddress); + address.sin_port = htons(PortNo); + addr_len = sizeof(address); + + // Set default socket state + ServerState = ssNone; + + // Create socket + if ((ServerHandle = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + printf( "Server Socket: %s [%d] -> Failed to create server socket (%s)\n", ServerName, PortNo, strerror(errno) ); + ServerState = ssFailed; + return -1; + }; + + // Configure connection + if ((setsockopt( ServerHandle, SOL_SOCKET, SO_LINGER, &ServerLinger_opt, sizeof(ServerLinger_opt)) == -1) || + (setsockopt( ServerHandle, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1)) + { + printf( "Server Socket: %s [%d] -> Could not set socket options (%s)\n", ServerName, PortNo, strerror(errno) ); + ServerState = ssFailed; + return -1; + } + + // Configure TCP keep alive settings + if (KeepAlive && + ((setsockopt( ServerHandle, SOL_SOCKET, SO_KEEPALIVE, &KeepAlive_opt, sizeof(KeepAlive_opt)) == -1) || + (setsockopt( ServerHandle, SOL_TCP, TCP_KEEPIDLE, &TCPidle_opt, sizeof(TCPidle_opt)) == -1) || + (setsockopt( ServerHandle, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) || + (setsockopt( ServerHandle, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) )) + { + printf( "Server Socket: %s [%d] -> Could not set socket keepalive options (%s)\n", ServerName, PortNo, strerror(errno) ); + ServerState = ssFailed; + return -1; + } + + // Bind socket + if (bind( ServerHandle, (struct sockaddr *)&address, addr_len ) < 0) + { + printf( "Server Socket: %s [%d] -> Failed to bind server to socket (%s)\n", ServerName, PortNo, strerror(errno) ); + close( ServerHandle ); + ServerState = ssFailed; + return -1; + }; + + // Create que for 5 connections + if (listen( ServerHandle, 5 ) < 0) + { + printf( "Server Socket: %s [%d] -> Failed to create server socket listen que (%s)\n", ServerName, PortNo, strerror(errno) ); + close( ServerHandle ); + ServerState = ssFailed; + return -1; + }; + + // Server open + ServerState = ssOpen; + printf( "Server Socket: %s [%d] -> Socket binded and listening\n", ServerName, PortNo ); + return ServerHandle; +} +//--------------------------------------------------------------------------- + +int OpenTCPinClientSocket() +{ + socklen_t addr_len; + struct sockaddr_in address; + + + // Set default socket state + if (ClientHandle == -1) + { + // Accept connection on current socket + addr_len = sizeof( address ); + if ((ClientHandle = accept( ServerHandle, (struct sockaddr *)&address, &addr_len)) == -1) + { + if (errno == EWOULDBLOCK) + printf( "Remote Socket: %s [*] -> Failed to accept blocking connection (%s)\n", ServerName, strerror(errno) ); + else + printf( "Remote Socket: %s [*] -> Failed to accept connection (%s)\n", ServerName, strerror(errno) ); + close( ClientHandle ); + return -1; + } + + // Return client address + strcpy( ClientAddress, inet_ntoa(address.sin_addr) ); + ClientState = ssOpen; + printf( "Remote Socket: %s -> Server accepted connection from client (%s)\n", ServerName, ClientAddress ); + } + else if (ClientState == ssWaitingtoOpen) + { + // Clear non blocking flag + int flags = fcntl( ClientHandle, F_GETFL, 0 ); + fcntl( ClientHandle, F_SETFL, (!O_NONBLOCK)&flags ); + + // Log event + printf( "Socket: %s -> Client now connected to server (%s)\n", ServerName, ServerAddress ); + + // Trigger handler & set new state + ClientState = ssOpen; + } + + return ClientHandle; +} +//--------------------------------------------------------------------------- + +int OpenTCPoutClientSocket( const char *pName, const char *pAddress, int pPortNo, bool KeepAlive ) +{ + socklen_t addr_len; + struct sockaddr_in address; + + ServerName = (char*)malloc( strlen(pName)+1 ); + strcpy( ServerName, pName ); + strcpy( ServerAddress, pAddress ); + PortNo = pPortNo; + + // Socket options + int KeepAlive_opt = 1; + int TCPidle_opt = 5; + int TCPcnt_opt = 3; + int TCPint_opt = 2; + + // Set default socket state + ClientState = ssNone; + + // Create File descriptor + if ((ClientHandle = socket( AF_INET, SOCK_STREAM, 0 )) < 0) + { + printf( "Client Socket: %s [*] -> Failed to create Client Socket (%s)\n", ServerName, strerror(errno) ); + return -1; + }; + + // Set Non blocking open + int flags = fcntl( ClientHandle, F_GETFL, 0 ); + fcntl( ClientHandle, F_SETFL, O_NONBLOCK|flags ); + + // Configure TCP keep alive settings + if (KeepAlive && + ((setsockopt( ClientHandle, SOL_SOCKET, SO_KEEPALIVE, &KeepAlive_opt, sizeof(KeepAlive_opt)) == -1) || + (setsockopt( ClientHandle, SOL_TCP, TCP_KEEPIDLE, &TCPidle_opt, sizeof(TCPidle_opt)) == -1) || + (setsockopt( ClientHandle, SOL_TCP, TCP_KEEPCNT, &TCPcnt_opt, sizeof(TCPcnt_opt)) == -1) || + (setsockopt( ClientHandle, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) )) + { + printf( "Client Socket: %s -> Could not set socket keepalive options (%s)\n", ServerName, strerror(errno) ); + return -1; + } + + // Declare address + address.sin_family = AF_INET; + address.sin_addr.s_addr = inet_addr( ServerAddress ); + address.sin_port = htons(PortNo); + addr_len = sizeof(address); + + if (!connect( ClientHandle, (struct sockaddr *)&address, addr_len )) + { + // Set status + ClientState = ssOpen; + return ClientHandle; + } + else if (errno == EINPROGRESS) + { + // Set status + ClientState = ssWaitingtoOpen; + return ClientHandle; + } + else + { + printf( "Client Socket: %s -> Client failed to connect (%s)\n", ServerName, strerror(errno) ); + + // Set status + ClientState = ssFailed; + + // Close socket + close( ClientHandle ); + return -1; + } +} +//--------------------------------------------------------------------------- + +// Delete socket +bool CloseTCPSocket( ESockConnectType SocketType ) +{ + bool Fail; + + if (SocketType == ctServer) { + Fail = (close( ServerHandle ))? true : false; + ServerState = ((Fail)? ssFailed : ssClosed); + } + else { + Fail = (close( ClientHandle ))? true : false; + ClientState = ((Fail)? ssFailed : ssClosed); + } + + // Show action + switch (SocketType) + { + case ctServer: + printf( "Server Socket: %s -> Server %s\n", ServerName, ((Fail)? "failed" : "closed") ); + break; + + case ctRemoteClient: + printf( "Remote Client: %s -> Connection to client %s\n", ServerName, ((Fail)? "failed" : "closed") ); + break; + + case ctClient: + printf( "Client Socket: %s -> Connection to server %s\n", ServerName, ((Fail)? "failed" : "closed") ); + break; + + case ctNone: + default: + printf( "Socket : %s -> Cannot %s socket (invalid socket type)\n", ServerName, ((Fail)? "fail" : "close") ); + break; + }; + + return true; +} +//--------------------------------------------------------------------------- + +bool ReadClientSocket() +{ + // Check if anything to read + ioctl( ClientHandle, FIONREAD, &SockBytesWaiting ); + + if (SockBytesWaiting) + { + // Handle Incoming Data + // Check if socket ready (non-block open not in progress) + if (ClientState == ssWaitingtoOpen) + { + printf( "Socket: %s -> Cannot read from socket in waiting\n", ServerName ); + SockBytesWaiting = 0; + } + else + { + // Read data into buffer + SockBytesRead = read( ClientHandle, &SockInBuffer[SockInLen], SockBytesWaiting ); // SockInBufLen-SockInLen + + // Check of errors + if (SockBytesRead == -1) + { + printf( "Socket: %s -> Cannot read from socket (%s)\n", ServerName, strerror(errno) ); + SockBytesRead = 0; + + // Check of non-blocking write + // bool Blocked = ((errno == EAGAIN)? true : false ); + } + else if (SockBytesRead > 0) + { + // Process Reply + SockInLen += SockBytesRead; + + // Reset timer + SetStartTime( &SockInStart ); + } + } + } + else // if (!SockBytesWaiting) + { + // EOF from server (close connection) + CloseTCPSocket( ctRemoteClient ); + ClientHandle = -1; + } + return true; +} +//--------------------------------------------------------------------------- + +bool MaintainSocket( int PortHandle ) +{ + // Init vars + long Duration = 0; + int BytesWritten = 0; + int StartWrite = 0; + + if (SockInLen > 0) + { + // Check duration since last PortIn + Duration = TimePassed( SockInStart ); + if (Duration > SockInTimeout) + { + // Handle buffer as packet + SockInBuffer[ SockInLen ] = 0; + //ShowOutput( "Sock", SockInBuffer, SockInLen, Duration ); + + // Write output to Port + BytesWritten = 0; + StartWrite = 0; + while (StartWrite < SockInLen) { + BytesWritten = write( PortHandle, &SockInBuffer[StartWrite], SockInLen ); + StartWrite += BytesWritten; + } + + // Reset buffer and timer + SockInLen = 0; + SetInterval( &SockInStart, 0 ); + } + } + return true; +} +//--------------------------------------------------------------------------- diff --git a/SocketCore.h b/SocketCore.h new file mode 100644 index 0000000..83da6bc --- /dev/null +++ b/SocketCore.h @@ -0,0 +1,42 @@ +/* + * SocketCore.h + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +#ifndef SOCKETCORE_H_ +#define SOCKETCORE_H_ + +// redA Libraries +/* none */ + +// Standard C/C++ Libraries +/* none */ + +//--------------------------------------------------------------------------- + +// Types required for sockets +typedef enum { ctNone = 0, ctServer = 1, ctRemoteClient = 2, ctClient = 3 } ESockConnectType; +const char SockConnectTypeName[][15] = { "None", "Server", "RemoteClient", "Client" }; + +typedef enum { ssNone = 0, ssWaitingtoOpen = 1, ssOpen = 2, ssDataWaiting = 3, ssClosed = 4, ssFailed = 5 } ESocketState; +const char SocketStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" }; +//--------------------------------------------------------------------------- + +// Socket Functions +int OpenTCPserverSocket( const char *pServerName, const char *ServerAddress, int PortNo, bool KeepAlive ); +int OpenTCPinClientSocket(); +int OpenTCPoutClientSocket( const char *pServerName, const char *ServerAddress, int PortNo, bool KeepAlive ); + +ESocketState GetServerState(); +ESocketState GetClientState(); + +bool CloseTCPSocket( ESockConnectType SocketType ); + +bool ReadClientSocket(); +bool MaintainSocket( int PortHandle ); + +//--------------------------------------------------------------------------- + +#endif /* SOCKETCORE_H_ */ diff --git a/TimingCore.cpp b/TimingCore.cpp new file mode 100644 index 0000000..dbc791b --- /dev/null +++ b/TimingCore.cpp @@ -0,0 +1,51 @@ +/* + * Timing.cpp + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +// redA Librarie +#include "TimingCore.h" + +// Standard C/C++ Libraries +#include +#include +#include + +//--------------------------------------------------------------------------- + +// Set time +void SetInterval( timeval * Time, long MilliSeconds ) +{ + // milli-seconds -> seconds + Time->tv_sec = MilliSeconds / 1000; + // milli-seconds -> micro-seconds + Time->tv_usec = (MilliSeconds % 1000) * 1000; +} +//--------------------------------------------------------------------------- + +// Populated start time +void SetStartTime( timeval * StartTime ) +{ + // Get current time + gettimeofday( StartTime, NULL ); +} +//--------------------------------------------------------------------------- + +// Calculate TimePassed from Start Time (in milli-seconds) +long TimePassed( timeval StartTime ) +{ + timeval CurrTime; + long Duration; + + // Get current time + gettimeofday( &CurrTime, NULL ); + + // Get time passed in milli-seconds + Duration = (CurrTime.tv_sec - StartTime.tv_sec) * 1000 + + (CurrTime.tv_usec - StartTime.tv_usec) / 1000; + + return Duration; +} +//--------------------------------------------------------------------------- diff --git a/TimingCore.h b/TimingCore.h new file mode 100644 index 0000000..b6df75d --- /dev/null +++ b/TimingCore.h @@ -0,0 +1,25 @@ +/* + * Timing.h + * + * Created on: 13 May 2016 + * Author: wentzelc + */ + +#ifndef TIMINGCORE_H_ +#define TIMINGCORE_H_ + +// redA Libraries +/* none */ + +// Standard C/C++ Libraries +#include + +//--------------------------------------------------------------------------- + +void SetInterval( timeval *Time, long MilliSeconds ); +void SetStartTime( timeval *StartTime ); +long TimePassed( timeval StartTime ); + +//--------------------------------------------------------------------------- + +#endif /* TIMINGCORE_H_ */