F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
TmFramer.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title TmFramer.cpp
3 // \author thomas-bc
4 // \brief cpp file for TmFramer component implementation class
5 // ======================================================================
6 
10 
11 namespace Svc {
12 
13 namespace Ccsds {
14 
15 // ----------------------------------------------------------------------
16 // Component construction and destruction
17 // ----------------------------------------------------------------------
18 
19 TmFramer ::TmFramer(const char* const compName)
20  : TmFramerComponentBase(compName), m_masterFrameCount(0), m_virtualFrameCount(0) {}
21 
23 
24 // ----------------------------------------------------------------------
25 // Handler implementations for typed input ports
26 // ----------------------------------------------------------------------
27 
28 void TmFramer ::dataIn_handler(FwIndexType portNum, Fw::Buffer& data, const ComCfg::FrameContext& context) {
30  static_cast<FwAssertArgType>(data.getSize()));
31  FW_ASSERT(this->m_bufferState == BufferOwnershipState::OWNED, static_cast<FwAssertArgType>(this->m_bufferState));
32 
33  // -----------------------------------------------
34  // Header
35  // -----------------------------------------------
36  TMHeader header;
37 
38  // GVCID (Global Virtual Channel ID) (Standard 4.1.2.2 and 4.1.2.3)
39  U16 globalVcId = static_cast<U16>(context.get_vcId() << TMSubfields::virtualChannelIdOffset);
40  globalVcId |= static_cast<U16>(ComCfg::SpacecraftId << TMSubfields::spacecraftIdOffset);
41  globalVcId |= 0x0; // Operational Control Field: Flag set to 0 (Standard 4.1.2.4)
42 
43  // Data Field Status (Standard 4.1.2.7):
44  // - all flags to 0 except segment length id 0b11 per standard (4.1.2.7)
45  // - First Header Pointer is always 0 since we are always wrapping a single entire packet at offset 0
46  U16 dataFieldStatus = 0;
47  dataFieldStatus |= 0x3 << TMSubfields::segLengthOffset; // Seg Length Id '11' (0x3) per Standard (4.1.2.7.5)
48 
49  header.set_globalVcId(globalVcId);
50  header.set_masterFrameCount(this->m_masterFrameCount);
51  header.set_virtualFrameCount(this->m_virtualFrameCount);
52  header.set_dataFieldStatus(dataFieldStatus);
53 
54  // We use only a single Virtual Channel for now, so master and virtual frame counts are the same
55  this->m_masterFrameCount++; // U8 intended to wrap around (modulo 256)
56  this->m_virtualFrameCount++; // U8 intended to wrap around (modulo 256)
57 
58  // -------------------------------------------------
59  // Data field
60  // -------------------------------------------------
61  // Payload packet
62  Fw::SerializeStatus status;
63  // Create frame Fw::Buffer using member data field
64  Fw::Buffer frameBuffer = Fw::Buffer(this->m_frameBuffer, sizeof(this->m_frameBuffer));
65  auto frameSerializer = frameBuffer.getSerializer();
66  status = frameSerializer.serializeFrom(header);
67  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
68  status = frameSerializer.serializeFrom(data.getData(), data.getSize(), Fw::Serialization::OMIT_LENGTH);
69  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
70 
71  // As per TM Standard 4.2.2.5, fill the rest of the data field with an Idle Packet
72  this->fill_with_idle_packet(frameSerializer);
73 
74  // -------------------------------------------------
75  // Trailer (CRC)
76  // -------------------------------------------------
77  TMTrailer trailer;
78  // Compute CRC over the entire frame buffer minus the FECF trailer (Standard 4.1.6)
79  U16 crc =
80  Ccsds::Utils::CRC16::compute(frameBuffer.getData(), sizeof(this->m_frameBuffer) - TMTrailer::SERIALIZED_SIZE);
81  // Set the Frame Error Control Field (FECF)
82  trailer.set_fecf(crc);
83  // Move the serializer pointer to the end of the location where the trailer will be serialized
84  frameSerializer.moveSerToOffset(ComCfg::TmFrameFixedSize - TMTrailer::SERIALIZED_SIZE);
85  status = frameSerializer.serializeFrom(trailer);
86  FW_ASSERT(status == Fw::FW_SERIALIZE_OK, status);
87 
88  this->m_bufferState = BufferOwnershipState::NOT_OWNED;
89  this->dataOut_out(0, frameBuffer, context);
90  this->dataReturnOut_out(0, data, context); // return ownership of the original data buffer
91 }
92 
93 void TmFramer ::comStatusIn_handler(FwIndexType portNum, Fw::Success& condition) {
94  if (this->isConnected_comStatusOut_OutputPort(portNum)) {
95  this->comStatusOut_out(portNum, condition);
96  }
97 }
98 
99 void TmFramer ::dataReturnIn_handler(FwIndexType portNum,
100  Fw::Buffer& frameBuffer,
101  const ComCfg::FrameContext& context) {
102  // Assert that the returned buffer is the member, and set ownership state
103  FW_ASSERT(frameBuffer.getData() >= &this->m_frameBuffer[0]);
104  FW_ASSERT(frameBuffer.getData() < &this->m_frameBuffer[0] + sizeof(this->m_frameBuffer));
105  this->m_bufferState = BufferOwnershipState::OWNED;
106 }
107 
108 void TmFramer ::fill_with_idle_packet(Fw::SerializeBufferBase& serializer) {
109  constexpr U16 endIndex = ComCfg::TmFrameFixedSize - TMTrailer::SERIALIZED_SIZE;
110  constexpr U16 idleApid = static_cast<U16>(ComCfg::Apid::SPP_IDLE_PACKET);
111  const U16 startIndex = static_cast<U16>(serializer.getBuffLength());
112  const U16 idlePacketSize = static_cast<U16>(endIndex - startIndex);
113  // Length token is defined as the number of bytes of payload data minus 1
114  const U16 lengthToken = static_cast<U16>(idlePacketSize - SpacePacketHeader::SERIALIZED_SIZE - 1);
115 
116  FW_ASSERT(idlePacketSize >= 7, static_cast<FwAssertArgType>(idlePacketSize)); // 7 bytes minimum for idle packet
117  FW_ASSERT(idlePacketSize <= ComCfg::TmFrameFixedSize, static_cast<FwAssertArgType>(idlePacketSize));
118 
119  SpacePacketHeader header;
120  header.set_packetIdentification(idleApid);
121  header.set_packetSequenceControl(
122  0x3 << SpacePacketSubfields::SeqFlagsOffset); // Sequence Flags = 0b11 (unsegmented) & unused Seq count
123  header.set_packetDataLength(lengthToken);
124  // Serialize header and idle data into the frame
125  serializer.serializeFrom(header);
126  for (U16 i = static_cast<U16>(startIndex + SpacePacketHeader::SERIALIZED_SIZE); i < endIndex; i++) {
127  serializer.serializeFrom(IDLE_DATA_PATTERN); // Idle data
128  }
129 }
130 } // namespace Ccsds
131 } // 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 set_globalVcId(U16 globalVcId)
Set member globalVcId.
void dataReturnOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataReturnOut.
~TmFramer()
Destroy TmFramer object.
Definition: TmFramer.cpp:22
U8 * getData() const
Definition: Buffer.cpp:56
Describes the frame trailer format for a Telemetry (TM) Transfer Frame.
void comStatusOut_out(FwIndexType portNum, Fw::Success &condition)
Invoke output port comStatusOut.
The size of the serial representation.
bool isConnected_comStatusOut_OutputPort(FwIndexType portNum)
void set_fecf(U16 fecf)
Set member fecf.
The size of the serial representation.
SerializeStatus
forward declaration for string
Serializable::SizeType getBuffLength() const
returns current buffer size
Describes the frame header format for a Telemetry (TM) Transfer Frame header.
U8 get_vcId() const
Get member vcId.
void set_dataFieldStatus(U16 dataFieldStatus)
Set member dataFieldStatus.
FwSizeType getSize() const
Definition: Buffer.cpp:60
void set_virtualFrameCount(U8 virtualFrameCount)
Set member virtualFrameCount.
Omit length from serialization.
Auto-generated base for TmFramer component.
TmFramer(const char *const compName)
Construct TmFramer object.
Definition: TmFramer.cpp:19
PlatformIndexType FwIndexType
Type used to pass context info between components during framing/deframing.
RateGroupDivider component implementation.
SerializeStatus serializeFrom(U8 val)
serialize 8-bit unsigned int
Per Space Packet Standard, all 1s (11bits) is reserved for Idle Packets.
Definition: ApidEnumAc.hpp:51
void set_masterFrameCount(U8 masterFrameCount)
Set member masterFrameCount.
ExternalSerializeBufferWithMemberCopy getSerializer()
Definition: Buffer.cpp:95
#define FW_ASSERT(...)
Definition: Assert.hpp:14
Success/Failure.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.
void dataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context)
Invoke output port dataOut.