F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
TcDeframer.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title TcDeframer.cpp
3 // \author thomas-bc
4 // \brief cpp file for TcDeframer component implementation class
5 // ======================================================================
6 
12 #include "config/FpConfig.hpp"
13 
14 namespace Svc {
15 namespace Ccsds {
16 
17 // ----------------------------------------------------------------------
18 // Component construction and destruction
19 // ----------------------------------------------------------------------
20 
21 TcDeframer ::TcDeframer(const char* const compName)
22  : TcDeframerComponentBase(compName), m_spacecraftId(ComCfg::SpacecraftId) {}
23 
25 
26 void TcDeframer::configure(U16 vcId, U16 spacecraftId, bool acceptAllVcid) {
27  this->m_vcId = vcId;
28  this->m_spacecraftId = spacecraftId;
29  this->m_acceptAllVcid = acceptAllVcid;
30 }
31 // ----------------------------------------------------------------------
32 // Handler implementations for user-defined typed input ports
33 // ----------------------------------------------------------------------
34 
35 void TcDeframer ::dataIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
36  // CCSDS TC Format:
37  // 5 octets - TC Primary Header
38  // Up to 1019 octets - Data Field (including optional 2 octets frame error control field)
39 
40  // Note: F Prime uses Type-BD
41  // CCSDS TC Primary Header:
42  // 2b - 00 - TF Version Number
43  // 1b - 0/1 - Bypass Flag (0 = Type-A FARM checks enabled, 1 = Type-B FARM checks bypassed)
44  // 1b - 0/1 - Control Command Flag (0 = Type-D data, 1 = Type-C control command)
45  // 2b - 00 - Reserved Spare (set to 00)
46  // 10b- XX - Spacecraft ID
47  // 6b - XX - Virtual Channel ID
48  // 10b- XX - Frame Length
49  // 8b - XX - Frame Sequence Number (unused for Type-B frames)
50 
51  // CCSDS TC Trailer:
52  // 16b - Frame Error Control Field (FECF): CRC16
53 
55  static_cast<FwAssertArgType>(data.getSize()));
56 
57  TCHeader header;
58  Fw::SerializeStatus status = data.getDeserializer().deserializeTo(header);
59  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
60  // TC protocol defines the Frame Length as number of bytes minus 1, so we add 1 back to get length in bytes
61  U16 total_frame_length = static_cast<U16>((header.get_vcIdAndLength() & TCSubfields::FrameLengthMask) + 1);
62  U8 vc_id = static_cast<U8>((header.get_vcIdAndLength() & TCSubfields::VcIdMask) >> TCSubfields::VcIdOffset);
63  U16 spacecraft_id = header.get_flagsAndScId() & TCSubfields::SpacecraftIdMask;
64 
65  if (spacecraft_id != this->m_spacecraftId) {
66  this->log_WARNING_LO_InvalidSpacecraftId(spacecraft_id, this->m_spacecraftId);
67  this->errorNotifyHelper(Ccsds::FrameError::TC_INVALID_SCID);
68  this->dataReturnOut_out(0, data, context); // drop the frame
69  return;
70  }
71  if (data.getSize() < static_cast<Fw::Buffer::SizeType>(total_frame_length)) {
72  FwSizeType maxDataAvailable = static_cast<FwSizeType>(data.getSize());
73  this->log_WARNING_HI_InvalidFrameLength(total_frame_length, maxDataAvailable);
74  this->errorNotifyHelper(Ccsds::FrameError::TC_INVALID_LENGTH);
75  this->dataReturnOut_out(0, data, context); // drop the frame
76  return;
77  }
78  if (not this->m_acceptAllVcid && vc_id != this->m_vcId) {
79  this->log_ACTIVITY_LO_InvalidVcId(vc_id, this->m_vcId);
80  this->errorNotifyHelper(Ccsds::FrameError::TC_INVALID_VCID);
81  this->dataReturnOut_out(0, data, context); // drop the frame
82  return;
83  }
84  // Note: F Prime uses TC Type-BD frames for now, so the FARM checks are not ran
85  // This means there is no sequence count checks at the TC level (there are at the Space Packet level)
86 
87  // -------------------------------------------------
88  // CRC Check
89  // -------------------------------------------------
90  // Compute CRC over the entire frame buffer minus the FECF trailer
91  U16 computed_crc = Ccsds::Utils::CRC16::compute(data.getData(), total_frame_length - TCTrailer::SERIALIZED_SIZE);
92  TCTrailer trailer;
93  auto deserializer = data.getDeserializer();
94  deserializer.moveDeserToOffset(total_frame_length - TCTrailer::SERIALIZED_SIZE);
95  status = deserializer.deserializeTo(trailer);
96  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
97 
98  U16 transmitted_crc = trailer.get_fecf();
99  if (transmitted_crc != computed_crc) {
100  this->log_WARNING_HI_InvalidCrc(computed_crc, transmitted_crc);
101  this->errorNotifyHelper(Ccsds::FrameError::TC_INVALID_CRC);
102  this->dataReturnOut_out(0, data, context); // drop the frame
103  return;
104  }
105 
106  // Point to the start of the data field and set appropriate size
108  // Shrink size to that of the encapsulated data field ( header | data | trailer )
109  data.setSize(total_frame_length - TCHeader::SERIALIZED_SIZE - TCTrailer::SERIALIZED_SIZE);
110 
111  this->dataOut_out(0, data, context);
112 }
113 
114 void TcDeframer ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffer, const ComCfg::FrameContext& context) {
115  this->dataReturnOut_out(0, fwBuffer, context);
116 }
117 
118 void TcDeframer::errorNotifyHelper(Ccsds::FrameError error) {
119  if (this->isConnected_errorNotify_OutputPort(0)) {
120  this->errorNotify_out(0, error);
121  }
122 }
123 
124 } // namespace Ccsds
125 } // namespace Svc
Serialization/Deserialization operation was successful.
static U16 compute(const U8 *buffer, U32 length)
compute CRC16 for a buffer
Definition: CRC16.hpp:43
void setData(U8 *data)
Definition: Buffer.cpp:68
TcDeframer(const char *const compName)
Construct TcDeframer object.
Definition: TcDeframer.cpp:21
bool isConnected_errorNotify_OutputPort(FwIndexType portNum)
void dataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataOut.
void configure(U16 vcId, U16 spacecraftId, bool acceptAllVcid)
Configure the TcDeframer to deframe only a specific VCID and spacecraft ID.
Definition: TcDeframer.cpp:26
PlatformSizeType FwSizeType
void setSize(FwSizeType size)
Definition: Buffer.cpp:75
U8 * getData() const
Definition: Buffer.cpp:56
SerializeStatus
forward declaration for string
void log_ACTIVITY_LO_InvalidVcId(U16 transmitted, U16 configured) const
ExternalSerializeBufferWithMemberCopy getDeserializer()
Definition: Buffer.cpp:105
~TcDeframer()
Destroy TcDeframer object.
Definition: TcDeframer.cpp:24
void log_WARNING_HI_InvalidCrc(U16 transmitted, U16 computed) const
U16 get_flagsAndScId() const
Get member flagsAndScId.
The size of the serial representation.
Describes the frame header format for a Telecommand (TC) Transfer Frame header.
U16 get_vcIdAndLength() const
Get member vcIdAndLength.
SerializeStatus moveDeserToOffset(FwSizeType offset)
Moves deserialization to the specified offset.
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:53
void log_WARNING_LO_InvalidSpacecraftId(U16 transmitted, U16 configured) const
FwSizeType getSize() const
Definition: Buffer.cpp:60
void errorNotify_out(FwIndexType portNum, const Svc::Ccsds::FrameError &errorCode)
Invoke output port errorNotify.
PlatformIndexType FwIndexType
FwSizeType SizeType
The size type for a buffer - for backwards compatibility.
Definition: Buffer.hpp:52
Type used to pass context info between components during framing/deframing.
RateGroupDivider component implementation.
The size of the serial representation.
void dataReturnOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataReturnOut.
#define FW_ASSERT(...)
Definition: Assert.hpp:14
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
Auto-generated base for TcDeframer component.
void log_WARNING_HI_InvalidFrameLength(U16 transmitted, FwSizeType actual) const
SerializeStatus deserializeTo(U8 &val)
deserialize 8-bit unsigned int