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 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 const FwSizeType maxPayload = currentVc.frame.buffer.getSize() - min_size;
285 if (currentVc.current_payload_offset < maxPayload) {
287 fill_with_idle_packet(currentVc, context);
292 check_and_send_vc(currentVc);
300 AosVc& currentVc = this->get_vc_struct(context);
302 const FwSizeType maxPayload = currentVc.frame.buffer.getSize() - min_size;
303 const FwSizeType bytesAvailable = maxPayload - currentVc.current_payload_offset;
304 FW_ASSERT(bytesAvailable < currentVc.frame.buffer.getSize(),
305 static_cast<FwAssertArgType>(min_size + currentVc.current_payload_offset));
312 auto frameSerializer = currentVc.frame.buffer.getSerializer();
313 status = frameSerializer.moveSerToOffset(START_OF_PAYLOAD + currentVc.current_payload_offset);
316 const U8* dataStart = data.
getData() + dataOffset;
321 if (dataSize <= bytesAvailable) {
323 currentVc.outstanding.offset = 0;
326 dataSize = bytesAvailable;
329 currentVc.outstanding.offset = dataOffset + dataSize;
330 currentVc.outstanding.packet = data;
337 currentVc.current_payload_offset =
static_cast<U16
>(currentVc.current_payload_offset + dataSize);
340 currentVc.outstanding.context = context;
343 if (currentVc.outstanding.offset == 0) {
345 if (!buffer_belongs(data, currentVc.spp_idle.backer,
sizeof(currentVc.spp_idle.backer))) {
350 currentVc.outstanding.packet = {};
351 currentVc.outstanding.offset = 0;
362 SpacePacketHeader header;
363 header.set_packetIdentification(idleApid);
364 header.set_packetSequenceControl(
366 header.set_packetDataLength(lengthToken);
383 FW_ASSERT(vc.frame.buffer.getSize() < std::numeric_limits<U16>::max(),
385 const U16 pduSize =
static_cast<U16
>(vc.frame.buffer.getSize() - overhead);
388 const U16 idlePacketSize =
static_cast<U16
>(pduSize - vc.current_payload_offset);
391 auto frameSerializer = vc.frame.buffer.getSerializer();
392 Fw::SerializeStatus status = frameSerializer.moveSerToOffset(START_OF_PAYLOAD + vc.current_payload_offset);
397 if (!vc.past_first_fresh_packet) {
399 setup_header(context);
400 setup_m_pdu_header(context);
403 vc.past_first_fresh_packet =
true;
413 else if (idlePacketSize < 7) {
417 FW_ASSERT(!vc.outstanding.packet.isValid());
420 vc.outstanding.packet = {vc.spp_idle.backer, MIN_SPP_LENGTH};
423 auto pduSerializer = vc.outstanding.packet.getSerializer();
424 serialize_idle_spp_packet(pduSerializer, MIN_SPP_LENGTH);
433 pack_packet(vc.outstanding.packet, filtered_context);
436 serialize_idle_spp_packet(frameSerializer, idlePacketSize);
439 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
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.
The size of the serial representation.
PlatformAssertArgType FwAssertArgType
The type of arguments to assert functions.