F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UdpSocket.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title UdpSocket.cpp
3// \author mstarch
4// \brief cpp file for UdpSocket 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// ======================================================================
12#include <Drv/Ip/UdpSocket.hpp>
13#include <Fw/Logger/Logger.hpp>
14#include <Fw/Types/Assert.hpp>
15#include <FpConfig.hpp>
17
18#ifdef TGT_OS_TYPE_VXWORKS
19 #include <socket.h>
20 #include <inetLib.h>
21 #include <fioLib.h>
22 #include <hostLib.h>
23 #include <ioLib.h>
24 #include <vxWorks.h>
25 #include <sockLib.h>
26 #include <taskLib.h>
27 #include <sysLib.h>
28 #include <errnoLib.h>
29 #include <cstring>
30#elif defined TGT_OS_TYPE_LINUX || TGT_OS_TYPE_DARWIN
31 #include <sys/socket.h>
32 #include <unistd.h>
33 #include <arpa/inet.h>
34#else
35 #error OS not supported for IP Socket Communications
36#endif
37
38#include <cstring>
39#include <new>
40
41namespace Drv {
42
44 struct sockaddr_in m_addr_send;
45 struct sockaddr_in m_addr_recv;
46
48 ::memset(&m_addr_send, 0, sizeof(m_addr_send));
49 ::memset(&m_addr_recv, 0, sizeof(m_addr_recv));
50 }
51};
52
53UdpSocket::UdpSocket() : IpSocket(), m_state(new(std::nothrow) SocketState), m_recv_port(0) {
54 FW_ASSERT(m_state != nullptr);
55}
56
58 FW_ASSERT(m_state);
59 delete m_state;
60}
61
62SocketIpStatus UdpSocket::configureSend(const char* const hostname, const U16 port, const U32 timeout_seconds, const U32 timeout_microseconds) {
63 //Timeout is for the send, so configure send will work with the base class
64 return this->IpSocket::configure(hostname, port, timeout_seconds, timeout_microseconds);
65}
66
67SocketIpStatus UdpSocket::configureRecv(const char* hostname, const U16 port) {
68 this->m_recv_port = port;
69 (void) Fw::StringUtils::string_copy(this->m_recv_hostname, hostname, SOCKET_MAX_HOSTNAME_SIZE);
70 return SOCK_SUCCESS;
71}
72
73
75 struct sockaddr_in address;
76 FW_ASSERT(-1 != fd);
77 FW_ASSERT(0 != m_recv_port);
78
79 // Set up the address port and name
80 address.sin_family = AF_INET;
81 address.sin_port = htons(m_recv_port);
82 // OS specific settings
83#if defined TGT_OS_TYPE_VXWORKS || TGT_OS_TYPE_DARWIN
84 address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
85#endif
86
87 // First IP address to socket sin_addr
88 if (IpSocket::addressToIp4(m_recv_hostname, &address.sin_addr) != SOCK_SUCCESS) {
90 };
91 // UDP (for receiving) requires bind to an address to the socket
92 if (::bind(fd, reinterpret_cast<struct sockaddr*>(&address), sizeof(address)) < 0) {
94 }
95 FW_ASSERT(sizeof(this->m_state->m_addr_recv) == sizeof(address), sizeof(this->m_state->m_addr_recv), sizeof(address));
96 memcpy(&this->m_state->m_addr_recv, &address, sizeof(this->m_state->m_addr_recv));
97 return SOCK_SUCCESS;
98}
99
102 NATIVE_INT_TYPE socketFd = -1;
103 struct sockaddr_in address;
104
105 // Ensure configured for at least send or receive
106 if (m_port == 0 && m_recv_port == 0) {
107 return SOCK_INVALID_IP_ADDRESS; // Consistent with port = 0 behavior in TCP
108 }
109
110 // Acquire a socket, or return error
111 if ((socketFd = ::socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
113 }
114
115 // May not be sending in all cases
116 if (this->m_port != 0) {
117 // Set up the address port and name
118 address.sin_family = AF_INET;
119 address.sin_port = htons(this->m_port);
120
121 // OS specific settings
122#if defined TGT_OS_TYPE_VXWORKS || TGT_OS_TYPE_DARWIN
123 address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
124#endif
125
126 // First IP address to socket sin_addr
127 if ((status = IpSocket::addressToIp4(m_hostname, &(address.sin_addr))) != SOCK_SUCCESS) {
128 ::close(socketFd);
129 return status;
130 };
131
132 // Now apply timeouts
133 if ((status = IpSocket::setupTimeouts(socketFd)) != SOCK_SUCCESS) {
134 ::close(socketFd);
135 return status;
136 }
137
138 FW_ASSERT(sizeof(this->m_state->m_addr_send) == sizeof(address), sizeof(this->m_state->m_addr_send),
139 sizeof(address));
140 memcpy(&this->m_state->m_addr_send, &address, sizeof(this->m_state->m_addr_send));
141 }
142
143 // When we are setting up for receiving as well, then we must bind to a port
144 if ((m_recv_port != 0) && ((status = this->bind(socketFd)) != SOCK_SUCCESS)) {
145 ::close(socketFd);
146 return status; // Not closing FD as it is still a valid send FD
147 }
148 const char* actions = (m_recv_port != 0 && m_port != 0) ? "send and receive" : ((m_port != 0) ? "send": "receive");
149 Fw::Logger::logMsg("Setup to %s udp to %s:%hu\n", reinterpret_cast<POINTER_CAST>(actions),
150 reinterpret_cast<POINTER_CAST>(m_hostname), m_port);
151 FW_ASSERT(status == SOCK_SUCCESS, status);
152 fd = socketFd;
153 return status;
154}
155
156I32 UdpSocket::sendProtocol(const U8* const data, const U32 size) {
157 FW_ASSERT(this->m_state->m_addr_send.sin_family != 0); // Make sure the address was previously setup
158 return ::sendto(this->m_fd, data, size, SOCKET_IP_SEND_FLAGS,
159 reinterpret_cast<struct sockaddr *>(&this->m_state->m_addr_send), sizeof(this->m_state->m_addr_send));
160}
161
162I32 UdpSocket::recvProtocol(U8* const data, const U32 size) {
163 FW_ASSERT(this->m_state->m_addr_recv.sin_family != 0); // Make sure the address was previously setup
164 return ::recvfrom(this->m_fd, data, size, SOCKET_IP_RECV_FLAGS, nullptr, nullptr);
165}
166
167} // namespace Drv
#define FW_ASSERT(...)
Definition Assert.hpp:7
PlatformPointerCastType POINTER_CAST
Definition BasicTypes.h:53
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
C++-compatible configuration header for fprime configuration.
@ SOCKET_MAX_HOSTNAME_SIZE
Definition IpCfg.hpp:23
@ SOCKET_IP_RECV_FLAGS
Definition IpCfg.hpp:20
@ SOCKET_IP_SEND_FLAGS
Definition IpCfg.hpp:19
Helper base-class for setting up Berkley sockets.
Definition IpSocket.hpp:45
void close()
closes the socket
Definition IpSocket.cpp:109
U16 m_port
IP address port used.
Definition IpSocket.hpp:180
char m_hostname[SOCKET_MAX_HOSTNAME_SIZE]
Hostname to supply.
Definition IpSocket.hpp:182
SocketIpStatus configure(const char *hostname, const U16 port, const U32 send_timeout_seconds, const U32 send_timeout_microseconds)
configure the ip socket with host and transmission timeouts
Definition IpSocket.cpp:53
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:80
NATIVE_INT_TYPE m_fd
Definition IpSocket.hpp:177
SocketIpStatus setupTimeouts(NATIVE_INT_TYPE socketFd)
setup the socket timeout properties of the opened outgoing socket
Definition IpSocket.cpp:63
SocketIpStatus bind(NATIVE_INT_TYPE fd)
bind the UDP to a port such that it can receive packets at the previously configured port
Definition UdpSocket.cpp:74
I32 sendProtocol(const U8 *const data, const U32 size)
Protocol specific implementation of send. Called directly with retry from send.
UdpSocket()
Constructor for client socket udp implementation.
Definition UdpSocket.cpp:53
I32 recvProtocol(U8 *const data, const U32 size)
Protocol specific implementation of recv. Called directly with error handling from recv.
SocketIpStatus openProtocol(NATIVE_INT_TYPE &fd)
udp specific implementation for opening a socket.
SocketIpStatus configureRecv(const char *hostname, const U16 port)
configure the udp socket for incoming transmissions
Definition UdpSocket.cpp:67
SocketIpStatus configureSend(const char *hostname, const U16 port, const U32 send_timeout_seconds, const U32 send_timeout_microseconds)
configure the udp socket for outgoing transmissions
Definition UdpSocket.cpp:62
virtual ~UdpSocket()
to cleanup state created at instantiation
Definition UdpSocket.cpp:57
static void logMsg(const char *fmt, POINTER_CAST a0=0, POINTER_CAST a1=0, POINTER_CAST a2=0, POINTER_CAST a3=0, POINTER_CAST a4=0, POINTER_CAST a5=0, POINTER_CAST a6=0, POINTER_CAST a7=0, POINTER_CAST a8=0, POINTER_CAST a9=0)
Definition Logger.cpp:18
SocketIpStatus
Status enumeration for socket return values.
Definition IpSocket.hpp:23
@ SOCK_INVALID_IP_ADDRESS
Bad IP address supplied.
Definition IpSocket.hpp:27
@ SOCK_SUCCESS
Socket operation successful.
Definition IpSocket.hpp:24
@ SOCK_FAILED_TO_BIND
Failed to bind to socket.
Definition IpSocket.hpp:33
@ SOCK_FAILED_TO_GET_SOCKET
Socket open failed.
Definition IpSocket.hpp:25
char * string_copy(char *destination, const char *source, U32 num)
copy string with null-termination guaranteed
struct sockaddr_in m_addr_send
UDP server address, maybe unused.
Definition UdpSocket.cpp:44
struct sockaddr_in m_addr_recv
UDP server address, maybe unused.
Definition UdpSocket.cpp:45