F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
TcpServerSocket.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title TcpServerSocket.cpp
3// \author mstarch
4// \brief cpp file for TcpServerSocket core implementation classes
5//
6// \copyright
7// Copyright 2009-2020, by the California Institute of Technology.
8// ALL RIGHTS RESERVED. United States Government Sponsorship
9// acknowledged.
10//
11// ======================================================================
13#include <Fw/Logger/Logger.hpp>
14#include <Fw/Types/Assert.hpp>
15#include <FpConfig.hpp>
16
17#ifdef TGT_OS_TYPE_VXWORKS
18 #include <socket.h>
19 #include <inetLib.h>
20 #include <fioLib.h>
21 #include <hostLib.h>
22 #include <ioLib.h>
23 #include <vxWorks.h>
24 #include <sockLib.h>
25 #include <taskLib.h>
26 #include <sysLib.h>
27 #include <errnoLib.h>
28 #include <cstring>
29#elif defined TGT_OS_TYPE_LINUX || TGT_OS_TYPE_DARWIN
30 #include <sys/socket.h>
31 #include <unistd.h>
32 #include <arpa/inet.h>
33#else
34 #error OS not supported for IP Socket Communications
35#endif
36
37#include <cstring>
38
39namespace Drv {
40
42
44 U16 port = this->m_port;
45 return port;
46}
47
49 PlatformIntType serverFd = -1;
50 struct sockaddr_in address;
51 // Acquire a socket, or return error
52 if ((serverFd = ::socket(AF_INET, SOCK_STREAM, 0)) == -1) {
54 }
55 // Set up the address port and name
56 address.sin_family = AF_INET;
57 address.sin_port = htons(this->m_port);
58
59 // OS specific settings
60#if defined TGT_OS_TYPE_VXWORKS || TGT_OS_TYPE_DARWIN
61 address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
62#endif
63 // First IP address to socket sin_addr
64 if (IpSocket::addressToIp4(m_hostname, &(address.sin_addr)) != SOCK_SUCCESS) {
65 ::close(serverFd);
67 };
68
69 // TCP requires bind to an address to the socket
70 if (::bind(serverFd, reinterpret_cast<struct sockaddr*>(&address), sizeof(address)) < 0) {
71 ::close(serverFd);
73 }
74
75 socklen_t size = sizeof(address);
76 if (::getsockname(serverFd, reinterpret_cast<struct sockaddr *>(&address), &size) == -1) {
77 ::close(serverFd);
79 }
80 // TCP requires listening on the socket. Since we only expect a single client, set the TCP backlog (second argument) to 1 to prevent queuing of multiple clients.
81 if (::listen(serverFd, 1) < 0) {
82 ::close(serverFd);
83 return SOCK_FAILED_TO_LISTEN; // What we have here is a failure to communicate
84 }
85 Fw::Logger::log("Listening for single client at %s:%hu\n", m_hostname, m_port);
86 FW_ASSERT(serverFd != -1);
87 socketDescriptor.serverFd = serverFd;
88 this->m_port = ntohs(address.sin_port);
89 return SOCK_SUCCESS;
90}
91
92void TcpServerSocket::terminate(const SocketDescriptor& socketDescriptor) {
93 (void)::close(socketDescriptor.serverFd);
94}
95
97 PlatformIntType clientFd = -1;
98 PlatformIntType serverFd = socketDescriptor.serverFd;
99
100 // Check for not started yet, may be true in the case of start-up reconnect attempts
101 if (serverFd == -1) {
102 return SOCK_NOT_STARTED;
103 }
104
105 // TCP requires accepting on the socket to get the client socket file descriptor.
106 clientFd = ::accept(serverFd, nullptr, nullptr);
107 if (clientFd < 0) {
108 return SOCK_FAILED_TO_ACCEPT; // What we have here is a failure to communicate
109 }
110 // Setup client send timeouts
111 if (IpSocket::setupTimeouts(clientFd) != SOCK_SUCCESS) {
112 ::close(clientFd);
114 }
115
116 Fw::Logger::log("Accepted client at %s:%hu\n", m_hostname, m_port);
117 socketDescriptor.fd = clientFd;
118 return SOCK_SUCCESS;
119}
120
121I32 TcpServerSocket::sendProtocol(const SocketDescriptor& socketDescriptor, const U8* const data, const U32 size) {
122 return static_cast<I32>(::send(socketDescriptor.fd, data, size, SOCKET_IP_SEND_FLAGS));
123}
124
125I32 TcpServerSocket::recvProtocol(const SocketDescriptor& socketDescriptor, U8* const data, const U32 size) {
126 I32 size_buf;
127 // recv will return 0 if the client has done an orderly shutdown
128 size_buf = static_cast<I32>(::recv(socketDescriptor.fd, data, size, SOCKET_IP_RECV_FLAGS));
129 return size_buf;
130}
131
132} // namespace Drv
#define FW_ASSERT(...)
Definition Assert.hpp:14
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:30
int PlatformIntType
DefaultTypes.hpp provides fallback defaults for the platform types.
C++-compatible configuration header for fprime configuration.
@ SOCKET_IP_RECV_FLAGS
Definition IpCfg.hpp:20
@ SOCKET_IP_SEND_FLAGS
Definition IpCfg.hpp:19
Helper base-class for setting up Berkeley sockets.
Definition IpSocket.hpp:55
U16 m_port
IP address port used.
Definition IpSocket.hpp:210
char m_hostname[SOCKET_MAX_HOSTNAME_SIZE]
Hostname to supply.
Definition IpSocket.hpp:211
SocketIpStatus setupTimeouts(PlatformIntType socketFd)
setup the socket timeout properties of the opened outgoing socket
Definition IpSocket.cpp:68
static SocketIpStatus addressToIp4(const char *address, void *ip4)
converts a given address in dot form x.x.x.x to an ip address. ONLY works for IPv4.
Definition IpSocket.cpp:85
SocketIpStatus send(const SocketDescriptor &socketDescriptor, const U8 *const data, const U32 size)
send data out the IP socket from the given buffer
Definition IpSocket.cpp:131
SocketIpStatus recv(const SocketDescriptor &fd, U8 *const data, U32 &size)
receive data from the IP socket from the given buffer
Definition IpSocket.cpp:163
void close(const SocketDescriptor &socketDescriptor)
closes the socket
Definition IpSocket.cpp:106
TcpServerSocket()
Constructor for client socket tcp implementation.
SocketIpStatus startup(SocketDescriptor &socketDescriptor)
Opens the server socket and listens, does not block.
SocketIpStatus openProtocol(SocketDescriptor &socketDescriptor) override
Tcp specific implementation for opening a client socket connected to this server.
I32 sendProtocol(const SocketDescriptor &socketDescriptor, const U8 *const data, const U32 size) override
Protocol specific implementation of send. Called directly with retry from send.
I32 recvProtocol(const SocketDescriptor &socketDescriptor, U8 *const data, const U32 size) override
Protocol specific implementation of recv. Called directly with error handling from recv.
U16 getListenPort()
get the port being listened on
void terminate(const SocketDescriptor &socketDescriptor)
close the server socket created by the startup call
static void log(const char *format,...)
log a formated string with supplied arguments
Definition Logger.cpp:21
SocketIpStatus
Status enumeration for socket return values.
Definition IpSocket.hpp:29
@ SOCK_INVALID_IP_ADDRESS
Bad IP address supplied.
Definition IpSocket.hpp:33
@ SOCK_FAILED_TO_ACCEPT
Failed to accept connection.
Definition IpSocket.hpp:41
@ SOCK_SUCCESS
Socket operation successful.
Definition IpSocket.hpp:30
@ SOCK_FAILED_TO_BIND
Failed to bind to socket.
Definition IpSocket.hpp:39
@ SOCK_FAILED_TO_SET_SOCKET_OPTIONS
Failed to configure socket.
Definition IpSocket.hpp:35
@ SOCK_FAILED_TO_GET_SOCKET
Socket open failed.
Definition IpSocket.hpp:31
@ SOCK_FAILED_TO_LISTEN
Failed to listen on socket.
Definition IpSocket.hpp:40
@ SOCK_FAILED_TO_READ_BACK_PORT
Failed to read back port from connection.
Definition IpSocket.hpp:44
@ SOCK_NOT_STARTED
Socket has not been started.
Definition IpSocket.hpp:43
PlatformIntType serverFd
Used for server sockets to track the listening file descriptor.
Definition IpSocket.hpp:23
PlatformIntType fd
Used for all sockets to track the communication file descriptor.
Definition IpSocket.hpp:22