F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 <Fw/Types/BasicTypes.hpp>
16 #include <Fw/Types/StringUtils.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 <string.h>
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 <string.h>
39 
40 namespace Drv {
41 
42 struct SocketState {
43  struct sockaddr_in m_addr_send;
44  struct sockaddr_in m_addr_recv;
45 
47  ::memset(&m_addr_send, 0, sizeof(m_addr_send));
48  ::memset(&m_addr_recv, 0, sizeof(m_addr_recv));
49  }
50 };
51 
52 UdpSocket::UdpSocket() : IpSocket(), m_state(new SocketState), m_recv_port(0) {}
53 
55  FW_ASSERT(m_state);
56  delete m_state;
57 }
58 
59 SocketIpStatus UdpSocket::configureSend(const char* const hostname, const U16 port, const U32 timeout_seconds, const U32 timeout_microseconds) {
60  //Timeout is for the send, so configure send will work with the base class
61  return this->IpSocket::configure(hostname, port, timeout_seconds, timeout_microseconds);
62 }
63 
64 SocketIpStatus UdpSocket::configureRecv(const char* hostname, const U16 port) {
65  this->m_recv_port = port;
66  (void) Fw::StringUtils::string_copy(this->m_recv_hostname, hostname, SOCKET_MAX_HOSTNAME_SIZE);
67  return SOCK_SUCCESS;
68 }
69 
70 
72  struct sockaddr_in address;
73  FW_ASSERT(-1 != fd);
74  FW_ASSERT(0 != m_recv_port);
75 
76  // Set up the address port and name
77  address.sin_family = AF_INET;
78  address.sin_port = htons(m_recv_port);
79  // OS specific settings
80 #if defined TGT_OS_TYPE_VXWORKS || TGT_OS_TYPE_DARWIN
81  address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
82 #endif
83 
84  // First IP address to socket sin_addr
85  if (IpSocket::addressToIp4(m_recv_hostname, &address.sin_addr) != SOCK_SUCCESS) {
87  };
88  // UDP (for receiving) requires bind to an address to the socket
89  if (::bind(fd, reinterpret_cast<struct sockaddr*>(&address), sizeof(address)) < 0) {
90  return SOCK_FAILED_TO_BIND;
91  }
92  FW_ASSERT(sizeof(this->m_state->m_addr_recv) == sizeof(address), sizeof(this->m_state->m_addr_recv), sizeof(address));
93  memcpy(&this->m_state->m_addr_recv, &address, sizeof(this->m_state->m_addr_recv));
94  return SOCK_SUCCESS;
95 }
96 
99  NATIVE_INT_TYPE socketFd = -1;
100  struct sockaddr_in address;
101 
102  // Ensure configured for at least send or receive
103  if (m_port == 0 && m_recv_port == 0) {
104  return SOCK_INVALID_IP_ADDRESS; // Consistent with port = 0 behavior in TCP
105  }
106 
107  // Acquire a socket, or return error
108  if ((socketFd = ::socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
110  }
111 
112  // May not be sending in all cases
113  if (this->m_port != 0) {
114  // Set up the address port and name
115  address.sin_family = AF_INET;
116  address.sin_port = htons(this->m_port);
117 
118  // OS specific settings
119 #if defined TGT_OS_TYPE_VXWORKS || TGT_OS_TYPE_DARWIN
120  address.sin_len = static_cast<U8>(sizeof(struct sockaddr_in));
121 #endif
122 
123  // First IP address to socket sin_addr
124  if ((status = IpSocket::addressToIp4(m_hostname, &(address.sin_addr))) != SOCK_SUCCESS) {
125  ::close(socketFd);
126  return status;
127  };
128 
129  // Now apply timeouts
130  if ((status = IpSocket::setupTimeouts(socketFd)) != SOCK_SUCCESS) {
131  ::close(socketFd);
132  return status;
133  }
134 
135  FW_ASSERT(sizeof(this->m_state->m_addr_send) == sizeof(address), sizeof(this->m_state->m_addr_send),
136  sizeof(address));
137  memcpy(&this->m_state->m_addr_send, &address, sizeof(this->m_state->m_addr_send));
138  }
139 
140  // When we are setting up for receiving as well, then we must bind to a port
141  if ((m_recv_port != 0) && ((status = this->bind(socketFd)) != SOCK_SUCCESS)) {
142  ::close(socketFd);
143  return status; // Not closing FD as it is still a valid send FD
144  }
145  const char* actions = (m_recv_port != 0 && m_port != 0) ? "send and receive" : ((m_port != 0) ? "send": "receive");
146  Fw::Logger::logMsg("Setup to %s udp to %s:%hu\n", reinterpret_cast<POINTER_CAST>(actions),
147  reinterpret_cast<POINTER_CAST>(m_hostname), m_port);
148  FW_ASSERT(status == SOCK_SUCCESS, status);
149  fd = socketFd;
150  return status;
151 }
152 
153 I32 UdpSocket::sendProtocol(const U8* const data, const U32 size) {
154  FW_ASSERT(this->m_state->m_addr_send.sin_family != 0); // Make sure the address was previously setup
155  return ::sendto(this->m_fd, data, size, SOCKET_IP_SEND_FLAGS,
156  reinterpret_cast<struct sockaddr *>(&this->m_state->m_addr_send), sizeof(this->m_state->m_addr_send));
157 }
158 
159 I32 UdpSocket::recvProtocol(U8* const data, const U32 size) {
160  FW_ASSERT(this->m_state->m_addr_recv.sin_family != 0); // Make sure the address was previously setup
161  return ::recvfrom(this->m_fd, data, size, SOCKET_IP_RECV_FLAGS, NULL, NULL);
162 }
163 
164 } // namespace Drv
Drv::SocketState::m_addr_recv
struct sockaddr_in m_addr_recv
UDP server address, maybe unused.
Definition: UdpSocket.cpp:44
Drv::SOCK_SUCCESS
@ SOCK_SUCCESS
Socket operation successful.
Definition: IpSocket.hpp:24
Drv::UdpSocket::sendProtocol
I32 sendProtocol(const U8 *const data, const U32 size)
Protocol specific implementation of send. Called directly with retry from send.
Definition: UdpSocket.cpp:153
Drv::SocketState::m_addr_send
struct sockaddr_in m_addr_send
UDP server address, maybe unused.
Definition: UdpSocket.cpp:43
Drv::IpSocket::configure
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:52
Drv::UdpSocket::openProtocol
SocketIpStatus openProtocol(NATIVE_INT_TYPE &fd)
udp specific implementation for opening a socket.
Definition: UdpSocket.cpp:97
Drv::IpSocket::setupTimeouts
SocketIpStatus setupTimeouts(NATIVE_INT_TYPE socketFd)
setup the socket timeout properties of the opened outgoing socket
Definition: IpSocket.cpp:62
SOCKET_IP_SEND_FLAGS
@ SOCKET_IP_SEND_FLAGS
Definition: IpCfg.hpp:19
Drv::UdpSocket::bind
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:71
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Drv::IpSocket
Helper base-class for setting up Berkley sockets.
Definition: IpSocket.hpp:45
Drv
Definition: BlockDriverImpl.cpp:5
Drv::SOCK_INVALID_IP_ADDRESS
@ SOCK_INVALID_IP_ADDRESS
Bad IP address supplied.
Definition: IpSocket.hpp:27
Drv::IpSocket::m_hostname
char m_hostname[SOCKET_MAX_HOSTNAME_SIZE]
Hostname to supply.
Definition: IpSocket.hpp:181
StringUtils.hpp
Assert.hpp
Drv::SOCK_FAILED_TO_GET_SOCKET
@ SOCK_FAILED_TO_GET_SOCKET
Socket open failed.
Definition: IpSocket.hpp:25
Fw::StringUtils::string_copy
char * string_copy(char *destination, const char *source, U32 num)
copy string with null-termination guaranteed
Definition: StringUtils.cpp:4
Drv::SocketState
Definition: UdpSocket.cpp:42
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Drv::SocketState::SocketState
SocketState()
Definition: UdpSocket.cpp:46
Drv::UdpSocket::configureSend
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:59
Drv::UdpSocket::recvProtocol
I32 recvProtocol(U8 *const data, const U32 size)
Protocol specific implementation of recv. Called directly with error handling from recv.
Definition: UdpSocket.cpp:159
Fw::Logger::logMsg
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
Drv::SocketIpStatus
SocketIpStatus
Status enumeration for socket return values.
Definition: IpSocket.hpp:23
Drv::SOCK_FAILED_TO_BIND
@ SOCK_FAILED_TO_BIND
Failed to bind to socket.
Definition: IpSocket.hpp:33
SOCKET_IP_RECV_FLAGS
@ SOCKET_IP_RECV_FLAGS
Definition: IpCfg.hpp:20
BasicTypes.hpp
Declares ISF basic types.
Drv::UdpSocket::~UdpSocket
virtual ~UdpSocket()
to cleanup state created at instantiation
Definition: UdpSocket.cpp:54
Drv::IpSocket::addressToIp4
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:79
SOCKET_MAX_HOSTNAME_SIZE
@ SOCKET_MAX_HOSTNAME_SIZE
Definition: IpCfg.hpp:23
Drv::UdpSocket::configureRecv
SocketIpStatus configureRecv(const char *hostname, const U16 port)
configure the udp socket for incoming transmissions
Definition: UdpSocket.cpp:64
Drv::IpSocket::m_fd
NATIVE_INT_TYPE m_fd
Definition: IpSocket.hpp:176
Drv::IpSocket::m_port
U16 m_port
IP address port used.
Definition: IpSocket.hpp:179
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
NULL
#define NULL
NULL.
Definition: BasicTypes.hpp:100
Drv::IpSocket::close
void close(void)
closes the socket
Definition: IpSocket.cpp:106
Drv::UdpSocket::UdpSocket
UdpSocket()
Constructor for client socket udp implementation.
Definition: UdpSocket.cpp:52
UdpSocket.hpp
Logger.hpp