F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
A framework for building embedded system applications to NASA flight quality standards.
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 
7 #include <Fw/Com/ComPacket.hpp>
9 #include "Fw/Types/BasicTypes.hpp"
10 #include <cstring>
11 
12 namespace 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 
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 
35  const NATIVE_INT_TYPE instance
36  )
37  {
38  GroundInterfaceComponentBase::init(instance);
39  }
40 
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  {
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
Svc::GroundInterfaceComponentImpl::~GroundInterfaceComponentImpl
~GroundInterfaceComponentImpl()
Definition: GroundInterface.cpp:42
Types::CircularBuffer::serialize
Fw::SerializeStatus serialize(const U8 *const buffer, const NATIVE_UINT_TYPE size)
Definition: CircularBuffer.cpp:48
FwPacketDescriptorType
#define FwPacketDescriptorType
Type representation for a packet descriptor.
Definition: FpConfig.hpp:58
Fw::SerializeBufferBase
Definition: Serializable.hpp:43
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
Fw::ComPacket::FW_PACKET_UNKNOWN
@ FW_PACKET_UNKNOWN
Definition: ComPacket.hpp:28
Fw::Buffer::getData
U8 * getData() const
Definition: Buffer.cpp:60
Fw::SerializeBufferBase::serialize
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
Definition: Serializable.cpp:69
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:73
Fw::ComPacket::FW_PACKET_FILE
@ FW_PACKET_FILE
Definition: ComPacket.hpp:25
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:28
Svc::GroundInterfaceComponentImpl::GroundInterfaceComponentImpl
GroundInterfaceComponentImpl(const char *const compName)
Definition: GroundInterface.cpp:23
Fw::SerializeBufferBase::resetSer
void resetSer(void)
reset to beginning of buffer to reuse for serialization
Definition: Serializable.cpp:572
Fw::ComPacket::FW_PACKET_COMMAND
@ FW_PACKET_COMMAND
Definition: ComPacket.hpp:22
Fw::Buffer
Definition: Buffer.hpp:43
Fw::ComBuffer::getBuffAddr
U8 * getBuffAddr()
gets buffer address for data filling
Definition: ComBuffer.cpp:36
Svc::GroundInterfaceComponentImpl::MAX_DATA_SIZE
static const U32 MAX_DATA_SIZE
Definition: GroundInterface.hpp:22
Fw::Buffer::getSerializeRepr
SerializeBufferBase & getSerializeRepr()
Definition: Buffer.cpp:99
Types::CircularBuffer::get_allocated_size
NATIVE_UINT_TYPE get_allocated_size() const
Definition: CircularBuffer.cpp:34
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:27
Fw::Buffer::getSize
U32 getSize() const
Definition: Buffer.cpp:64
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:79
Fw::SerializeBufferBase::setBuffLen
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length)
sets buffer length manually after filling with data
Definition: Serializable.cpp:611
TOKEN_TYPE
#define TOKEN_TYPE
Definition: GroundInterface.hpp:13
Types::CircularBuffer::peek
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0) const
Definition: CircularBuffer.cpp:66
Types::CircularBuffer::rotate
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
Definition: CircularBuffer.cpp:114
Fw::SerializeBufferBase::getBuffLength
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
Definition: Serializable.cpp:594
Svc::GroundInterfaceComponentImpl::START_WORD
static const TOKEN_TYPE START_WORD
Definition: GroundInterface.hpp:23
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
HEADER_SIZE
#define HEADER_SIZE
Definition: GroundInterface.hpp:14
GroundInterface.hpp
Svc
Definition: ActiveRateGroupCfg.hpp:18
Svc::GroundInterfaceComponentImpl::END_WORD
static const U32 END_WORD
Definition: GroundInterface.hpp:24
Svc::GroundInterfaceComponentImpl::init
void init(const NATIVE_INT_TYPE instance=0)
Definition: GroundInterface.cpp:34
Fw::ComBuffer
Definition: ComBuffer.hpp:21
Types::CircularBuffer::get_free_size
NATIVE_UINT_TYPE get_free_size() const
Definition: CircularBuffer.cpp:38
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
ComPacket.hpp
GND_BUFFER_SIZE
#define GND_BUFFER_SIZE
Definition: GroundInterface.hpp:12