27 const bool frameErrorControlField,
28 const U16 spacecraftId,
37 static_cast<FwAssertArgType>(fixedFrameSize));
40 FW_ASSERT((spacecraftId & 0xFC00) == 0, static_cast<FwAssertArgType>(spacecraftId));
43 FW_ASSERT((vcId & 0xC0) == 0, static_cast<FwAssertArgType>(vcId));
51 this->m_fecf = frameErrorControlField;
52 this->m_spacecraftId = spacecraftId;
55 for (
U8 ind = 0; ind <
sizeof(this->m_vcs) /
sizeof(AosVc); ind++) {
56 AosVc& currentVc = this->m_vcs[ind];
59 currentVc.vc_struct_index = ind;
60 currentVc.virtualChannelId = vcId;
61 currentVc.frame.buffer = {currentVc.frame.backer, fixedFrameSize};
63 currentVc.idle_packet_types = idlePvns;
74 AosVc& currentVc = this->get_vc_struct(context);
75 FW_ASSERT(currentVc.virtualChannelId == vcId);
79 FW_ASSERT(currentVc.frame.state == BufferOwnershipState::OWNED,
80 static_cast<FwAssertArgType>(currentVc.frame.state));
84 if (!currentVc.past_first_fresh_packet) {
86 setup_header(context);
87 setup_m_pdu_header(context);
90 currentVc.past_first_fresh_packet =
true;
94 pack_pad_send(data, context);
97 void AosFramer::compute_and_inject_fecf(AosVc& currentVc) {
107 trailer.set_fecf(crc);
110 auto frameSerializer = currentVc.frame.buffer.getSerializer();
114 status = frameSerializer.serializeFrom(trailer);
127 void AosFramer ::dataReturnIn_handler(
FwIndexType portNum,
131 AosVc& currentVc = this->get_vc_struct(context);
134 FW_ASSERT(buffer_belongs(frameBuffer, currentVc.frame.backer,
sizeof(currentVc.frame.backer)));
135 currentVc.frame.state = BufferOwnershipState::OWNED;
138 if (currentVc.outstanding.packet.isValid()) {
139 this->pack_pad_send(currentVc.outstanding.packet, currentVc.outstanding.context, currentVc.outstanding.offset);
147 AosVc& currentVc = this->m_vcs[ind];
150 FW_ASSERT(currentVc.vc_struct_index == ind);
157 AosVc& currentVc = this->get_vc_struct(context);
170 U32 frameCountAndSignaling =
static_cast<U32
>((currentVc.virtualFrameCount & 0x00FFFFFFU)
177 frameCountAndSignaling |=
181 frameCountAndSignaling |=
static_cast<U32
>((currentVc.virtualFrameCount & 0x0F000000) >> 24);
183 header.set_globalVcId(globalVcId);
184 header.set_frameCountAndSignaling(frameCountAndSignaling);
187 currentVc.virtualFrameCount++;
196 auto frameSerializer = currentVc.frame.buffer.getSerializer();
198 status = frameSerializer.moveSerToOffset(0);
201 status = frameSerializer.serializeFrom(header);
207 AosVc& currentVc = this->get_vc_struct(context);
209 M_PDUHeader muxedPdu;
212 muxedPdu.set_firstHeaderPointer(0xFFFF);
216 muxedPdu.set_firstHeaderPointer(currentVc.current_payload_offset);
219 auto frameSerializer = currentVc.frame.buffer.getSerializer();
223 status = frameSerializer.serializeFrom(muxedPdu);
232 return (buffer.
getData() >= start && buffer.
getData() < start + size);
235 void AosFramer::check_and_send_vc(AosFramer::AosVc& currentVc) {
236 const FwSizeType maxPayload = currentVc.frame.buffer.getSize() - get_min_size();
239 if (currentVc.current_payload_offset == maxPayload) {
241 if (!currentVc.past_first_fresh_packet) {
243 setup_header(currentVc.outstanding.context);
246 setup_m_pdu_header(currentVc.outstanding.context,
true);
251 compute_and_inject_fecf(currentVc);
255 FW_ASSERT(currentVc.frame.state == BufferOwnershipState::OWNED);
256 currentVc.frame.state = BufferOwnershipState::NOT_OWNED;
259 currentVc.current_payload_offset = 0;
260 currentVc.past_first_fresh_packet =
false;
263 this->
dataOut_out(0, currentVc.frame.buffer, currentVc.outstanding.context);
273 pack_packet(data, context, dataOffset);
276 AosVc& currentVc = this->get_vc_struct(context);
283 FW_ASSERT(currentVc.frame.buffer.getSize() >= min_size,
285 static_cast<FwAssertArgType>(min_size));
286 const FwSizeType maxPayload = currentVc.frame.buffer.getSize() - min_size;
288 if (currentVc.current_payload_offset < maxPayload) {
290 fill_with_idle_packet(currentVc, context);
295 check_and_send_vc(currentVc);
303 AosVc& currentVc = this->get_vc_struct(context);
305 const FwSizeType maxPayload = currentVc.frame.buffer.getSize() - min_size;
306 const FwSizeType bytesAvailable = maxPayload - currentVc.current_payload_offset;
307 FW_ASSERT(bytesAvailable < currentVc.frame.buffer.getSize(),
308 static_cast<FwAssertArgType>(min_size + currentVc.current_payload_offset));
315 auto frameSerializer = currentVc.frame.buffer.getSerializer();
316 status = frameSerializer.moveSerToOffset(START_OF_PAYLOAD + currentVc.current_payload_offset);
319 const U8* dataStart = data.
getData() + dataOffset;
324 if (dataSize <= bytesAvailable) {
326 currentVc.outstanding.offset = 0;
329 dataSize = bytesAvailable;
332 currentVc.outstanding.offset = dataOffset + dataSize;
333 currentVc.outstanding.packet = data;
340 currentVc.current_payload_offset =
static_cast<U16
>(currentVc.current_payload_offset + dataSize);
343 currentVc.outstanding.context = context;
346 if (currentVc.outstanding.offset == 0) {
348 const bool isSppIdleBuffer = buffer_belongs(data, currentVc.spp_idle.backer,
sizeof(currentVc.spp_idle.backer));
349 if (!isSppIdleBuffer) {
354 currentVc.outstanding.packet = {};
355 currentVc.outstanding.offset = 0;
366 SpacePacketHeader header;
367 header.set_packetIdentification(idleApid);
368 header.set_packetSequenceControl(
370 header.set_packetDataLength(lengthToken);
387 FW_ASSERT(vc.frame.buffer.getSize() < std::numeric_limits<U16>::max(),
389 const U16 pduSize =
static_cast<U16
>(vc.frame.buffer.getSize() - overhead);
392 const U16 idlePacketSize =
static_cast<U16
>(pduSize - vc.current_payload_offset);
395 auto frameSerializer = vc.frame.buffer.getSerializer();
396 Fw::SerializeStatus status = frameSerializer.moveSerToOffset(START_OF_PAYLOAD + vc.current_payload_offset);
401 if (!vc.past_first_fresh_packet) {
403 setup_header(context);
404 setup_m_pdu_header(context);
407 vc.past_first_fresh_packet =
true;
416 else if (idlePacketSize < 7) {
420 FW_ASSERT(!vc.outstanding.packet.isValid());
423 vc.outstanding.packet = {vc.spp_idle.backer, MIN_SPP_LENGTH};
426 auto pduSerializer = vc.outstanding.packet.getSerializer();
427 serialize_idle_spp_packet(pduSerializer, MIN_SPP_LENGTH);
436 pack_packet(vc.outstanding.packet, filtered_context);
439 serialize_idle_spp_packet(frameSerializer, idlePacketSize);
442 vc.current_payload_offset =
static_cast<U16
>(vc.current_payload_offset + idlePacketSize);
void configure(U32 fixedFixedSize, bool frameErrorControlField, U16 spacecraftId=ComCfg::SpacecraftId, U8 vcId=1, U8 idlePvns=PvnBitfield::SPP_MASK)
Serialization/Deserialization operation was successful.
static U16 compute(const U8 *buffer, U32 length)
compute CRC16 for a buffer
Advanced Orbiting Systems SDL.
PlatformSizeType FwSizeType
void dataOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context) const
Invoke output port dataOut.
~AosFramer()
Destroy AosFramer object.
Auto-generated base for AosFramer component.
void set_sendNow(bool sendNow)
Set member sendNow.
virtual SerializeStatus serializeFrom(U8 val, Endianness mode=Endianness::BIG)=0
Serialize an 8-bit unsigned integer value.
AosFramer(const char *const compName)
Construct AosFramer object.
void comStatusOut_out(FwIndexType portNum, Fw::Success &condition) const
Invoke output port comStatusOut.
SerializeStatus
forward declaration for string
void dataReturnOut_out(FwIndexType portNum, Fw::Buffer &data, const ComCfg::FrameContext &context) const
Invoke output port dataReturnOut.
bool get_sendNow() const
Get member sendNow.
Omit length from serialization.
U8 get_vcId() const
Get member vcId.
bool isConnected_comStatusOut_OutputPort(FwIndexType portNum) const
uint8_t U8
8-bit unsigned integer
FwSizeType getSize() const
PlatformIndexType FwIndexType
The size of the serial representation.
Type used to pass context info between components during framing/deframing.
RateGroupDivider component implementation.
Per Space Packet Standard, all 1s (11bits) is reserved for Idle Packets.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.