F´ Flight Software - C/C++ Documentation NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
Loading...
Searching...
No Matches
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.