F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
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 
7 #include <Fw/Com/ComPacket.hpp>
10 #include <string.h>
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[packet_descriptor_size];
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_remaining_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_remaining_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_remaining_size(true)) ?
215  m_in_ring.get_remaining_size(true) : 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(void)
Definition: GroundInterface.cpp:42
Types::CircularBuffer::serialize
Fw::SerializeStatus serialize(const U8 *const buffer, const NATIVE_UINT_TYPE size)
Definition: CircularBuffer.cpp:54
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:56
Fw::ComBuffer::getBuffAddr
U8 * getBuffAddr(void)
gets buffer address for data filling
Definition: ComBuffer.cpp:36
Fw::SerializeBufferBase::serialize
SerializeStatus serialize(U8 val)
serialize 8-bit unsigned int
Definition: Serializable.cpp:67
FwPacketDescriptorType
#define FwPacketDescriptorType
Type representation for a packet descriptor.
Definition: FpConfig.hpp:58
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Fw::ComPacket::FW_PACKET_FILE
@ FW_PACKET_FILE
Definition: ComPacket.hpp:25
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:565
Fw::ComPacket::FW_PACKET_COMMAND
@ FW_PACKET_COMMAND
Definition: ComPacket.hpp:22
Fw::Buffer
Definition: Buffer.hpp:43
Svc::GroundInterfaceComponentImpl::MAX_DATA_SIZE
static const U32 MAX_DATA_SIZE
Definition: GroundInterface.hpp:22
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Fw::Buffer::getSerializeRepr
SerializeBufferBase & getSerializeRepr()
Definition: Buffer.cpp:95
Types::CircularBuffer::get_remaining_size
NATIVE_UINT_TYPE get_remaining_size(bool serialization=false)
Definition: CircularBuffer.cpp:33
Fw::Buffer::getSize
U32 getSize() const
Definition: Buffer.cpp:60
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:75
Fw::SerializeBufferBase::setBuffLen
SerializeStatus setBuffLen(NATIVE_UINT_TYPE length)
sets buffer length manually after filling with data
Definition: Serializable.cpp:604
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
TOKEN_TYPE
#define TOKEN_TYPE
Definition: GroundInterface.hpp:13
Types::CircularBuffer::rotate
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
Definition: CircularBuffer.cpp:136
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Fw::SerializeBufferBase::getBuffLength
NATIVE_UINT_TYPE getBuffLength() const
returns current buffer size
Definition: Serializable.cpp:587
Svc::GroundInterfaceComponentImpl::START_WORD
static const TOKEN_TYPE START_WORD
Definition: GroundInterface.hpp:23
Types::CircularBuffer::peek
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0)
Definition: CircularBuffer.cpp:76
HEADER_SIZE
#define HEADER_SIZE
Definition: GroundInterface.hpp:14
GroundInterface.hpp
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
Svc::GroundInterfaceComponentImpl::END_WORD
static const U32 END_WORD
Definition: GroundInterface.hpp:24
BasicTypes.hpp
Declares ISF basic types.
Svc::GroundInterfaceComponentImpl::init
void init(const NATIVE_INT_TYPE instance=0)
Definition: GroundInterface.cpp:34
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Fw::ComBuffer
Definition: ComBuffer.hpp:21
ComPacket.hpp
GND_BUFFER_SIZE
#define GND_BUFFER_SIZE
Definition: GroundInterface.hpp:12