GCC Code Coverage Report


Directory: ./
File: Drv/TcpServer/TcpServerComponentImpl.cpp
Date: 2026-09-23 22:11:34
Exec Total Coverage
Lines: 0 74 0.0%
Functions: 0 14 0.0%
Branches: 0 43 0.0%

Line Branch Exec Source
1 // ======================================================================
2 // \title TcpServerComponentImpl.cpp
3 // \author mstarch
4 // \brief cpp file for TcpServerComponentImpl component 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
13 #include <Drv/TcpServer/TcpServerComponentImpl.hpp>
14 #include <Fw/FPrimeBasicTypes.hpp>
15 #include <limits>
16 #include "Fw/Logger/Logger.hpp"
17 #include "Fw/Types/Assert.hpp"
18
19 namespace Drv {
20
21 // ----------------------------------------------------------------------
22 // Construction, initialization, and destruction
23 // ----------------------------------------------------------------------
24
25 ✗ TcpServerComponentImpl::TcpServerComponentImpl(const char* const compName) : TcpServerComponentBase(compName) {}
26
27 ✗ SocketIpStatus TcpServerComponentImpl::configure(const char* const ipv4_address,
28 const U16 port,
29 const U32 send_timeout_seconds,
30 const U32 send_timeout_microseconds,
31 FwSizeType buffer_size) {
32 ✗ m_allocation_size = buffer_size; // Store the buffer size
33 ✗ (void)m_socket.configure(ipv4_address, port, send_timeout_seconds, send_timeout_microseconds);
34 ✗ return startup();
35 }
36
37 ✗ TcpServerComponentImpl::~TcpServerComponentImpl() {}
38
39 // ----------------------------------------------------------------------
40 // Implementations for socket read task virtual methods
41 // ----------------------------------------------------------------------
42
43 ✗ U16 TcpServerComponentImpl::getListenPort() {
44 ✗ return m_socket.getListenPort();
45 }
46
47 ✗ IpSocket& TcpServerComponentImpl::getSocketHandler() {
48 ✗ return m_socket;
49 }
50
51 ✗ Fw::Buffer TcpServerComponentImpl::getBuffer() {
52 ✗ return allocate_out(0, m_allocation_size);
53 }
54
55 ✗ void TcpServerComponentImpl::sendBuffer(Fw::Buffer buffer, SocketIpStatus status) {
56 // A successful receive must have produced a buffer with backing data (size may be zero)
57 ✗ FW_ASSERT((status != SOCK_SUCCESS) || (buffer.getData() != nullptr));
58 ✗ Drv::ByteStreamStatus recvStatus = ByteStreamStatus::OTHER_ERROR;
59 ✗ if (status == SOCK_SUCCESS) {
60 ✗ recvStatus = ByteStreamStatus::OP_OK;
61 ✗ } else if (status == SOCK_NO_DATA_AVAILABLE) {
62 ✗ recvStatus = ByteStreamStatus::RECV_NO_DATA;
63 } else {
64 ✗ recvStatus = ByteStreamStatus::OTHER_ERROR;
65 }
66 ✗ this->recv_out(0, buffer, recvStatus);
67 ✗ }
68
69 ✗ void TcpServerComponentImpl::connected() {
70 ✗ if (isConnected_ready_OutputPort(0)) {
71 ✗ this->ready_out(0);
72 }
73 ✗ }
74
75 ✗ bool TcpServerComponentImpl::isStarted() {
76 ✗ Os::ScopeLock scopedLock(this->m_lock);
77 ✗ return this->m_descriptor.serverFd != -1;
78 ✗ }
79
80 ✗ SocketIpStatus TcpServerComponentImpl::startup() {
81 ✗ Os::ScopeLock scopedLock(this->m_lock);
82 ✗ Drv::SocketIpStatus status = SOCK_SUCCESS;
83 // Prevent multiple startup attempts
84 ✗ if (this->m_descriptor.serverFd == -1) {
85 ✗ status = this->m_socket.startup(this->m_descriptor);
86 }
87 ✗ return status;
88 ✗ }
89
90 ✗ void TcpServerComponentImpl::terminate() {
91 ✗ this->stop();
92 ✗ Os::ScopeLock scopedLock(this->m_lock);
93 ✗ this->m_socket.terminate(this->m_descriptor);
94 ✗ this->m_descriptor.serverFd = -1;
95 ✗ }
96
97 ✗ void TcpServerComponentImpl::readLoop() {
98 ✗ Drv::SocketIpStatus status = Drv::SocketIpStatus::SOCK_NOT_STARTED;
99 // Keep trying to reconnect until the status is good, told to stop, or reconnection is turned off
100 // @non-terminating@: retry loop bounded by stop request
101 do {
102 ✗ status = this->startup();
103 ✗ if (status != SOCK_SUCCESS) {
104 ✗ Fw::Logger::log("[WARNING] Failed to listen on port %hu with status %d\n", this->getListenPort(), status);
105 ✗ (void)Os::Task::delay(SOCKET_RETRY_INTERVAL);
106 ✗ continue;
107 }
108 ✗ } while (this->running() && status != SOCK_SUCCESS && this->getAutomaticOpen());
109 // Loop exit implies startup succeeded, a stop was requested, or reopen is disabled
110 ✗ FW_ASSERT(status == SOCK_SUCCESS || (not this->running()) || (not this->getAutomaticOpen()),
111 static_cast<FwAssertArgType>(status));
112 // If start up was successful then perform normal operations
113 ✗ if (this->running() && status == SOCK_SUCCESS) {
114 // Perform the nominal read loop
115 ✗ SocketComponentHelper::readLoop();
116 }
117 // Terminate the server
118 ✗ this->terminate();
119 ✗ }
120
121 // ----------------------------------------------------------------------
122 // Handler implementations for user-defined typed input ports
123 // ----------------------------------------------------------------------
124
125 ✗ Drv::ByteStreamStatus TcpServerComponentImpl::send_handler(const FwIndexType portNum, Fw::Buffer& fwBuffer) {
126 ✗ Drv::SocketIpStatus status = this->send(fwBuffer.getData(), fwBuffer.getSize());
127 ✗ Drv::ByteStreamStatus returnStatus;
128 ✗ switch (status) {
129 ✗ case SOCK_INTERRUPTED_TRY_AGAIN:
130 ✗ returnStatus = ByteStreamStatus::SEND_RETRY;
131 ✗ break;
132 ✗ case SOCK_SUCCESS:
133 ✗ returnStatus = ByteStreamStatus::OP_OK;
134 ✗ break;
135 ✗ default:
136 ✗ returnStatus = ByteStreamStatus::OTHER_ERROR;
137 ✗ break;
138 }
139 ✗ return returnStatus;
140 ✗ }
141
142 ✗ void TcpServerComponentImpl::recvReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer) {
143 ✗ this->deallocate_out(0, fwBuffer);
144 ✗ }
145
146 } // end namespace Drv
147