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
GroundInterface.cpp
Go to the documentation of this file.
1// ======================================================================
2// \title GroundInterface.cpp
3// \author lestarch
4// \brief cpp file for GroundInterface component implementation class
5// ======================================================================
6
9#include <FpConfig.hpp>
10#include <cstring>
11
12namespace Svc {
13
15 const TOKEN_TYPE GroundInterfaceComponentImpl::START_WORD = static_cast<TOKEN_TYPE>(0xdeadbeef);
16 const U32 GroundInterfaceComponentImpl::END_WORD = static_cast<U32>(0xcafecafe);
17
18 // ----------------------------------------------------------------------
19 // Construction, initialization, and destruction
20 // ----------------------------------------------------------------------
21
22 GroundInterfaceComponentImpl ::
23 GroundInterfaceComponentImpl(
24 const char *const compName
25 ) : GroundInterfaceComponentBase(compName),
26 m_ext_buffer(m_buffer, GND_BUFFER_SIZE),
27 m_data_size(0),
28 m_in_ring(m_in_buffer, GND_BUFFER_SIZE)
29 {
30
31 }
32
33 void GroundInterfaceComponentImpl ::
34 init(
35 const NATIVE_INT_TYPE instance
36 )
37 {
38 GroundInterfaceComponentBase::init(instance);
39 }
40
41 GroundInterfaceComponentImpl ::
42 ~GroundInterfaceComponentImpl()
43 {
44
45 }
46
47 // ----------------------------------------------------------------------
48 // Handler implementations for user-defined typed input ports
49 // ----------------------------------------------------------------------
50
51 void GroundInterfaceComponentImpl ::
52 downlinkPort_handler(
53 const NATIVE_INT_TYPE portNum,
54 Fw::ComBuffer &data,
55 U32 context
56 )
57 {
58 FW_ASSERT(data.getBuffLength() <= MAX_DATA_SIZE);
59 frame_send(data.getBuffAddr(), data.getBuffLength());
60 }
61
62 void GroundInterfaceComponentImpl ::
63 fileDownlinkBufferSendIn_handler(
64 const NATIVE_INT_TYPE portNum,
65 Fw::Buffer &fwBuffer
66 )
67 {
68 FW_ASSERT(fwBuffer.getSize() <= MAX_DATA_SIZE);
69 frame_send(fwBuffer.getData(), fwBuffer.getSize(), Fw::ComPacket::FW_PACKET_FILE);
70 fileDownlinkBufferSendOut_out(0, fwBuffer);
71 }
72
73 void GroundInterfaceComponentImpl ::
74 readCallback_handler(
75 const NATIVE_INT_TYPE portNum,
76 Fw::Buffer &buffer
77 )
78 {
79 processBuffer(buffer);
80 }
81
82 void GroundInterfaceComponentImpl ::
83 schedIn_handler(
84 const NATIVE_INT_TYPE portNum,
85 NATIVE_UINT_TYPE context
86 )
87 {
88 // TODO: replace with a call to a buffer manager
89 Fw::Buffer buffer = m_ext_buffer;
90 // Call read poll if it is hooked up
91 if (isConnected_readPoll_OutputPort(0)) {
92 readPoll_out(0, buffer);
93 processBuffer(buffer);
94 }
95 }
96
97 void GroundInterfaceComponentImpl::frame_send(U8 *data, TOKEN_TYPE size, TOKEN_TYPE packet_type) {
98 // TODO: replace with a call to a buffer manager
99 Fw::Buffer buffer = m_ext_buffer;
100 Fw::SerializeBufferBase& buffer_wrapper = buffer.getSerializeRepr();
101 buffer_wrapper.resetSer();
102 // True size is supplied size plus sizeof(TOKEN_TYPE) if a packet_type other than "UNKNOWN" was supplied.
103 // This is because if not UNKNOWN, the packet_type is serialized too. Otherwise it is assumed the PACKET_TYPE is
104 // already the first token in the UNKNOWN typed buffer.
105 U32 true_size = (packet_type != Fw::ComPacket::FW_PACKET_UNKNOWN) ? size + sizeof(TOKEN_TYPE) : size;
106 U32 total_size = sizeof(TOKEN_TYPE) + sizeof(TOKEN_TYPE) + true_size + sizeof(U32);
107 // Serialize data
108 FW_ASSERT(GND_BUFFER_SIZE >= total_size, GND_BUFFER_SIZE, total_size);
109 buffer_wrapper.serialize(START_WORD);
110 buffer_wrapper.serialize(static_cast<TOKEN_TYPE>(true_size));
111 // Explicitly set the packet type, if it didn't come with the data already
112 if (packet_type != Fw::ComPacket::FW_PACKET_UNKNOWN) {
113 buffer_wrapper.serialize(packet_type);
114 }
115 buffer_wrapper.serialize(data, size, true);
116 buffer_wrapper.serialize(static_cast<TOKEN_TYPE>(END_WORD));
117
118 // Setup for sending by truncating unused data
119 buffer.setSize(buffer_wrapper.getBuffLength());
120 FW_ASSERT(buffer.getSize() == total_size, buffer.getSize(), total_size);
121 write_out(0, buffer);
122 }
123
124 void GroundInterfaceComponentImpl ::
125 routeComData()
126 {
127 // Read the packet type from the data buffer
129
130 //read packet descriptor in size agnostic way
131 U8 packet_descriptor_size = sizeof(FwPacketDescriptorType);
132 U8 packet_type_bytes[sizeof(FwPacketDescriptorType)];
133 Fw::SerializeStatus stat = m_in_ring.peek(packet_type_bytes, packet_descriptor_size, HEADER_SIZE);
134 //m_in_ring.peek(packet_type, HEADER_SIZE); // this way is only valid for 4byte packet descriptors
135 if(stat == Fw::FW_SERIALIZE_OK)
136 {
137 // unpack Big Endian encoded bytes
138 packet_type = 0;
139 for(int i = 0; i < packet_descriptor_size; i++)
140 {
141 packet_type <<= 8;
142 packet_type |= packet_type_bytes[i];
143 }
144 }
145
146 // Process variable type
147 switch (packet_type) {
149 Fw::ComBuffer com;
150 m_in_ring.peek(com.getBuffAddr(), m_data_size, HEADER_SIZE);
151 // Reset com buffer for sending out data
152 com.setBuffLen(m_data_size);
153 uplinkPort_out(0, com, 0);
154 break;
155 }
157 // If file uplink is possible, handle files. Otherwise ignore.
158 if (isConnected_fileUplinkBufferGet_OutputPort(0) &&
159 isConnected_fileDownlinkBufferSendOut_OutputPort(0)) {
160 Fw::Buffer buffer = fileUplinkBufferGet_out(0, m_data_size);
161 m_in_ring.peek(buffer.getData(), m_data_size - sizeof(packet_type), HEADER_SIZE + sizeof(packet_type));
162 buffer.setSize(m_data_size - sizeof(packet_type));
163 fileUplinkBufferSendOut_out(0, buffer);
164 }
165 break;
166 }
167 default:
168 return;
169 }
170 }
171
172 void GroundInterfaceComponentImpl ::
173 processRing()
174 {
175 // Header items for the packet
176 TOKEN_TYPE start;
177 U32 checksum; //TODO: make this run a CRC32
178 // Inner-loop, process ring buffer looking for at least the header
179 while (m_in_ring.get_allocated_size() >= HEADER_SIZE) {
180 m_data_size = 0;
181 // Peek into the header and read out values
182 Fw::SerializeStatus status = m_in_ring.peek(start, 0);
183 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
184 status = m_in_ring.peek(m_data_size, sizeof(TOKEN_TYPE));
185 FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
186 // Check the header for correctness
187 if (start != START_WORD || m_data_size >= MAX_DATA_SIZE) {
188 m_in_ring.rotate(1);
189 continue;
190 }
191 // Check for enough data to deserialize everything otherwise break and wait for more.
192 else if (m_in_ring.get_allocated_size() < (HEADER_SIZE + m_data_size + sizeof(END_WORD))) {
193 break;
194 }
195 // Continue with the data portion and checksum
196 m_in_ring.peek(checksum, HEADER_SIZE + m_data_size);
197 // Check checksum
198 if (checksum == END_WORD) {
199 routeComData();
200 m_in_ring.rotate(HEADER_SIZE + m_data_size + sizeof(U32));
201 }
202 // Failed checksum, keep looking for valid message
203 else {
204 m_in_ring.rotate(1);
205 }
206 }
207 }
208
209 void GroundInterfaceComponentImpl ::
210 processBuffer(Fw::Buffer& buffer)
211 {
212 NATIVE_UINT_TYPE buffer_offset = 0;
213 while (buffer_offset < buffer.getSize()) {
214 NATIVE_UINT_TYPE ser_size = (buffer.getSize() >= m_in_ring.get_free_size()) ?
215 m_in_ring.get_free_size() : static_cast<NATIVE_UINT_TYPE>(buffer.getSize());
216 m_in_ring.serialize(buffer.getData() + buffer_offset, ser_size);
217 buffer_offset = buffer_offset + ser_size;
218 processRing();
219 }
220 }
221} // end namespace Svc
#define FW_ASSERT(...)
Definition Assert.hpp:7
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
U32 FwPacketDescriptorType
Definition FpConfig.h:53
C++-compatible configuration header for fprime configuration.
#define HEADER_SIZE
#define TOKEN_TYPE
#define GND_BUFFER_SIZE
U8 * getData() const
Definition Buffer.cpp:60
U32 getSize() const
Definition Buffer.cpp:64
void setSize(U32 size)
Definition Buffer.cpp:79
SerializeBufferBase & getSerializeRepr()
Definition Buffer.cpp:99
U8 * getBuffAddr()
gets buffer address for data filling
Definition ComBuffer.cpp:40
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length)
sets buffer length manually after filling with data
void resetSer()
reset to beginning of buffer to reuse for serialization
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
static const TOKEN_TYPE START_WORD
SerializeStatus
forward declaration for string
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.