F´ Flight Software - C/C++ Documentation devel
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
SocketReadTask.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title SocketReadTask.cpp
3// \author mstarch
4// \brief cpp file for SocketReadTask implementation class
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
14#include <Fw/Logger/Logger.hpp>
15#include <Fw/Types/Assert.hpp>
16#include <cerrno>
17
18#define MAXIMUM_SIZE 0x7FFFFFFF
19
20namespace Drv {
21
22SocketReadTask::SocketReadTask() : m_reconnect(false), m_stop(false) {}
23
25
27 const bool reconnect,
28 const NATIVE_UINT_TYPE priority,
29 const NATIVE_UINT_TYPE stack,
30 const NATIVE_UINT_TYPE cpuAffinity) {
31 FW_ASSERT(not m_task.isStarted()); // It is a coding error to start this task multiple times
32 FW_ASSERT(not this->m_stop); // It is a coding error to stop the thread before it is started
33 m_reconnect = reconnect;
34 // Note: the first step is for the IP socket to open the port
35 Os::Task::TaskStatus stat = m_task.start(name, SocketReadTask::readTask, this, priority, stack, cpuAffinity);
36 FW_ASSERT(Os::Task::TASK_OK == stat, static_cast<NATIVE_INT_TYPE>(stat));
37}
38
42
44 SocketIpStatus status = this->getSocketHandler().open();
45 // Call connected any time the open is successful
46 if (Drv::SOCK_SUCCESS == status) {
47 this->connected();
48 }
49 return status;
50}
51
55
57 this->getSocketHandler().close();
58}
59
61 return m_task.join(value_ptr);
62}
63
65 this->m_stop = true;
66 this->getSocketHandler().shutdown(); // Break out of any receives and fully shutdown
67}
68
69void SocketReadTask::readTask(void* pointer) {
70 FW_ASSERT(pointer);
72 SocketReadTask* self = reinterpret_cast<SocketReadTask*>(pointer);
73 do {
74 // Open a network connection if it has not already been open
75 if ((not self->getSocketHandler().isStarted()) and (not self->m_stop) and
76 ((status = self->startup()) != SOCK_SUCCESS)) {
77 Fw::Logger::logMsg("[WARNING] Failed to open port with status %d and errno %d\n", status, errno);
79 continue;
80 }
81
82 // Open a network connection if it has not already been open
83 if ((not self->getSocketHandler().isOpened()) and (not self->m_stop) and
84 ((status = self->open()) != SOCK_SUCCESS)) {
85 Fw::Logger::logMsg("[WARNING] Failed to open port with status %d and errno %d\n", status, errno);
87 continue;
88 }
89
90 // If the network connection is open, read from it
91 if (self->getSocketHandler().isStarted() and self->getSocketHandler().isOpened() and (not self->m_stop)) {
92 Fw::Buffer buffer = self->getBuffer();
93 U8* data = buffer.getData();
94 FW_ASSERT(data);
95 I32 size = static_cast<I32>(buffer.getSize());
96 size = (size >= 0) ? size : MAXIMUM_SIZE; // Handle max U32 edge case
97 status = self->getSocketHandler().recv(data, size);
98 if ((status != SOCK_SUCCESS) && (status != SOCK_INTERRUPTED_TRY_AGAIN)) {
99 Fw::Logger::logMsg("[WARNING] Failed to recv from port with status %d and errno %d\n", status, errno);
100 self->getSocketHandler().close();
101 buffer.setSize(0);
102 } else {
103 // Send out received data
104 buffer.setSize(size);
105 }
106 self->sendBuffer(buffer, status);
107 }
108 }
109 // As long as not told to stop, and we are successful interrupted or ordered to retry, keep receiving
110 while (not self->m_stop &&
111 (status == SOCK_SUCCESS || status == SOCK_INTERRUPTED_TRY_AGAIN || self->m_reconnect));
112 self->getSocketHandler().shutdown(); // Shutdown the port entirely
113}
114} // namespace Drv
#define FW_ASSERT(...)
Definition Assert.hpp:14
PlatformIntType NATIVE_INT_TYPE
Definition BasicTypes.h:51
uint8_t U8
8-bit unsigned integer
Definition BasicTypes.h:26
PlatformUIntType NATIVE_UINT_TYPE
Definition BasicTypes.h:52
@ SOCKET_RETRY_INTERVAL_MS
Definition IpCfg.hpp:22
#define MAXIMUM_SIZE
void close()
closes the socket
Definition IpSocket.cpp:117
bool isStarted()
Returns true when the socket is started.
Definition IpSocket.cpp:101
bool isOpened()
check if IP socket has previously been opened
Definition IpSocket.cpp:109
SocketIpStatus recv(U8 *const data, I32 &size)
receive data from the IP socket from the given buffer
Definition IpSocket.cpp:195
virtual void shutdown()
shutdown the socket
Definition IpSocket.cpp:128
SocketIpStatus open()
open the IP socket for communications
Definition IpSocket.cpp:142
virtual SocketIpStatus startup()
startup the socket, a no-op on unless this is server
Definition IpSocket.cpp:135
supports a task to read a given socket adaptation
virtual void connected()=0
called when the IPv4 system has been connected
void stopSocketTask()
stop the socket read task and close the associated socket.
virtual IpSocket & getSocketHandler()=0
returns a reference to the socket handler
bool m_stop
Stops the task when set to true.
virtual Fw::Buffer getBuffer()=0
returns a buffer to fill with data
void close()
close the socket communications
static void readTask(void *pointer)
a task designed to read from the socket and output incoming data
void shutdown()
shutdown the socket communications
virtual ~SocketReadTask()
destructor of the socket read task
void startSocketTask(const Fw::StringBase &name, const bool reconnect=true, const NATIVE_UINT_TYPE priority=Os::Task::TASK_DEFAULT, const NATIVE_UINT_TYPE stack=Os::Task::TASK_DEFAULT, const NATIVE_UINT_TYPE cpuAffinity=Os::Task::TASK_DEFAULT)
start the socket read task to start producing data
bool m_reconnect
Force reconnection.
SocketIpStatus open()
open the socket for communications
virtual void sendBuffer(Fw::Buffer buffer, SocketIpStatus status)=0
sends a buffer to be filled with data
SocketIpStatus startup()
startup the socket for communications
SocketReadTask()
constructs the socket read task
Os::Task::TaskStatus joinSocketTask(void **value_ptr)
joins to the stopping read task to wait for it to close
U8 * getData() const
Definition Buffer.cpp:68
U32 getSize() const
Definition Buffer.cpp:72
void setSize(U32 size)
Definition Buffer.cpp:87
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
static TaskStatus delay(NATIVE_UINT_TYPE msecs)
delay the task
Definition Task.cpp:43
TaskStatus join(void **value_ptr)
Wait for task to finish.
Definition Task.cpp:74
TaskStatus
Definition Task.hpp:18
@ TASK_OK
message sent/received okay
Definition Task.hpp:19
bool isStarted()
check to see if task is started
TaskStatus start(const Fw::StringBase &name, taskRoutine routine, void *arg, NATIVE_UINT_TYPE priority=TASK_DEFAULT, NATIVE_UINT_TYPE stackSize=TASK_DEFAULT, NATIVE_UINT_TYPE cpuAffinity=TASK_DEFAULT, NATIVE_UINT_TYPE identifier=TASK_DEFAULT)
start the task
Definition Task.cpp:18
SocketIpStatus
Status enumeration for socket return values.
Definition IpSocket.hpp:23
@ SOCK_SUCCESS
Socket operation successful.
Definition IpSocket.hpp:24
@ SOCK_INTERRUPTED_TRY_AGAIN
Interrupted status for retries.
Definition IpSocket.hpp:30