Skip to content

Commit 9141f01

Browse files
authored
Fix Intermittent UT failure in FprimeDeframer (nasa#4177)
* Fix random UT failure in FprimeDeframer * Update UTs and docs to reflect expectations
1 parent b377be2 commit 9141f01

4 files changed

Lines changed: 28 additions & 12 deletions

File tree

Svc/FprimeDeframer/FprimeDeframer.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,20 @@ void FprimeDeframer ::dataIn_handler(FwIndexType portNum, Fw::Buffer& data, cons
5858
return;
5959
}
6060
// -------- Attempt to extract APID from Payload --------
61-
// If PacketDescriptor translates to an invalid APID, let it default to FW_PACKET_UNKNOWN
62-
// and let downstream components (e.g. custom router) handle it
63-
FwPacketDescriptorType packetDescriptor;
64-
status = deserializer.deserializeTo(packetDescriptor);
65-
FW_ASSERT(status == Fw::SerializeStatus::FW_SERIALIZE_OK, status);
6661
ComCfg::FrameContext contextCopy = context;
67-
// If a valid descriptor is deserialized, set it in the context
68-
if (packetDescriptor < ComCfg::Apid::INVALID_UNINITIALIZED) {
69-
contextCopy.set_apid(static_cast<ComCfg::Apid::T>(packetDescriptor));
62+
if (deserializer.getBuffLeft() < FprimeProtocol::FrameTrailer::SERIALIZED_SIZE + sizeof(FwPacketDescriptorType)) {
63+
// Not enough data to read a valid FwPacketDescriptor, emit event and skip attempting to read an APID
64+
this->log_WARNING_LO_PayloadTooShort();
65+
} else {
66+
// If PacketDescriptor translates to an invalid APID, let it default to FW_PACKET_UNKNOWN
67+
// and let downstream components (e.g. custom router) handle it
68+
FwPacketDescriptorType packetDescriptor;
69+
status = deserializer.deserializeTo(packetDescriptor);
70+
FW_ASSERT(status == Fw::SerializeStatus::FW_SERIALIZE_OK, status);
71+
// If a valid descriptor is deserialized, set it in the context
72+
if ((packetDescriptor < ComCfg::Apid::INVALID_UNINITIALIZED)) {
73+
contextCopy.set_apid(static_cast<ComCfg::Apid::T>(packetDescriptor));
74+
}
7075
}
7176

7277
// ---------------- Validate Frame Trailer ----------------

Svc/FprimeDeframer/FprimeDeframer.fpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ module Svc {
3030
severity warning high \
3131
format "Frame dropped: The transmitted frame checksum does not match that computed by the receiver"
3232

33+
@ An invalid frame was received (not enough data to contain a valid FwPacketDescriptor type)
34+
event PayloadTooShort \
35+
severity warning low \
36+
format "The received buffer is too short to contain a valid FwPacketDescriptor"
37+
3338
###############################################################################
3439
# Standard AC Ports for Events
3540
###############################################################################

Svc/FprimeDeframer/test/ut/FprimeDeframerTester.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ FprimeDeframerTester ::~FprimeDeframerTester() {}
2727
// ----------------------------------------------------------------------
2828

2929
void FprimeDeframerTester ::testNominalFrame() {
30+
// This tests a nominal frame with 1 byte of data - which per F Prime protocol
31+
// does not contain a valid FwPacketDescriptor (2 bytes) and therefore emits a warning event
32+
// See testNominalFrameApid() for a nominal frame with a valid FwPacketDescriptor
33+
3034
// Get random byte of data
3135
U8 randomByte = static_cast<U8>(STest::Random::lowerUpper(1, 255));
3236
// | F´ start word | Length (= 1) | Data | Checksum (4 bytes) |
@@ -41,7 +45,9 @@ void FprimeDeframerTester ::testNominalFrame() {
4145
ASSERT_EQ(this->fromPortHistory_dataOut->at(0).data.getData()[0], randomByte);
4246
// Not enough data to read a valid APID -> should default to FW_PACKET_UNKNOWN
4347
ASSERT_EQ(this->fromPortHistory_dataOut->at(0).context.get_apid(), ComCfg::Apid::FW_PACKET_UNKNOWN);
44-
ASSERT_EVENTS_SIZE(0); // no events emitted
48+
49+
ASSERT_EVENTS_SIZE(1); // one event emitted
50+
ASSERT_EVENTS_PayloadTooShort_SIZE(1); // event was emitted for payload too short
4551
}
4652

4753
void FprimeDeframerTester ::testNominalFrameApid() {
@@ -88,8 +94,8 @@ void FprimeDeframerTester ::testIncorrectStartWord() {
8894
}
8995

9096
void FprimeDeframerTester ::testIncorrectCrc() {
91-
// Frame: | F´ start word | Length = 1 | Data | INCORRECT Checksum |
92-
U8 data[13] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
97+
// Frame: | F´ start word | Length = 1 |Data (2bytes)| INCORRECT Checksum |
98+
U8 data[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
9399
this->mockReceiveData(data, sizeof(data));
94100
ASSERT_from_dataOut_SIZE(0); // nothing emitted on dataOut
95101
ASSERT_from_dataReturnOut_SIZE(1); // invalid buffer was deallocated

Svc/FprimeProtocol/docs/sdd.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The F Prime protocol is a minimal communications protocol that is used by defaul
55
A frame for F Prime protocol consists of 4 fields:
66
- Start word: A 32-bit start word that is used to identify the start of a frame. The start word is always `0xDEADBEEF`.
77
- Payload length: A 32-bit field that specifies the length of the payload data in bytes.
8-
- Payload data: A variable-length field that contains the payload data (usually an [F Prime packet](../../../Fw/Com/ComPacket.hpp)), of length specified by the payload length field.
8+
- Payload data: A variable-length field that contains the payload data in the form of an [F Prime packet](../../../Fw/Com/ComPacket.hpp), of length specified by the payload length field. Note: an F Prime packet contains always at least a (configurable width) `FwPacketDescriptorType` field, which is used to identify the type of packet.
99
- CRC: A 32-bit CRC field that is used to verify the integrity of the frame.
1010

1111
## F Prime frame format

0 commit comments

Comments
 (0)