From d0efdf0c214efdee9d3684b77077ec21a104fc83 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 31 Jan 2023 16:26:12 -0500 Subject: [PATCH] Fix #361, add option for trailer bytes in CFDP PDUs Adds an option to insert platform-specific padding at the end of CFDP PDU encapsulation. The padding area may be utilized by the deployment to add arbitrary verification information to the PDU. --- fsw/inc/cf_platform_cfg.h | 22 ++++++++++++++++++++++ fsw/src/cf_cfdp_sbintf.c | 14 +++++++++++++- unit-test/cf_cfdp_sbintf_tests.c | 13 ++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/fsw/inc/cf_platform_cfg.h b/fsw/inc/cf_platform_cfg.h index 5b356b76..c01746cc 100644 --- a/fsw/inc/cf_platform_cfg.h +++ b/fsw/inc/cf_platform_cfg.h @@ -348,6 +348,28 @@ typedef uint32 CF_TransactionSeq_t; */ #define CF_STARTUP_SEM_TASK_DELAY 100 +/** + * @brief Number of trailing bytes to add to CFDP PDU + * + * @par Description + *    Additional padding bytes to be appended to the tail of CFDP PDUs + * This reserves extra space to the software bus encapsulation buffer for every + * CFDP PDU such that platform-specific trailer information may be added. This + * includes, but is not limited to a separate CRC or error control field in addition + * to the error control field(s) within the the nominal CFDP protocol. + * + * These extra bytes are added at the software bus encapsulation layer, they are not + * part of the CFDP PDU itself. + * + * Set to 0 to disable this feature, such that the software bus buffer + * encapsulates only the CFDP PDU and no extra bytes are added. + * + *  @par Limits: + * Maximum value is the difference between the maximum size of a CFDP PDU and the + * maximum size of an SB message. + */ +#define CF_PDU_ENCAPSULATION_EXTRA_TRAILING_BYTES 0 + /** * \brief Mission specific version number * diff --git a/fsw/src/cf_cfdp_sbintf.c b/fsw/src/cf_cfdp_sbintf.c index b42eba77..7388191a 100644 --- a/fsw/src/cf_cfdp_sbintf.c +++ b/fsw/src/cf_cfdp_sbintf.c @@ -100,7 +100,8 @@ CF_Logical_PduBuffer_t *CF_CFDP_MsgOutGet(const CF_Transaction_t *t, bool silent /* Allocate message buffer on success */ if (os_status == OS_SUCCESS) { - CF_AppData.engine.out.msg = CFE_SB_AllocateMessageBuffer(offsetof(CF_PduTlmMsg_t, ph) + CF_MAX_PDU_SIZE); + CF_AppData.engine.out.msg = CFE_SB_AllocateMessageBuffer(offsetof(CF_PduTlmMsg_t, ph) + CF_MAX_PDU_SIZE + + CF_PDU_ENCAPSULATION_EXTRA_TRAILING_BYTES); } if (!CF_AppData.engine.out.msg) @@ -153,6 +154,7 @@ void CF_CFDP_Send(uint8 chan_num, const CF_Logical_PduBuffer_t *ph) sb_msgsize = offsetof(CF_PduTlmMsg_t, ph); sb_msgsize += ph->pdu_header.header_encoded_length; sb_msgsize += ph->pdu_header.data_encoded_length; + sb_msgsize += CF_PDU_ENCAPSULATION_EXTRA_TRAILING_BYTES; CFE_MSG_SetSize(&CF_AppData.engine.out.msg->Msg, sb_msgsize); CFE_MSG_SetMsgTime(&CF_AppData.engine.out.msg->Msg, CFE_TIME_GetTime()); @@ -198,6 +200,16 @@ void CF_CFDP_ReceiveMessage(CF_Channel_t *c) CFE_ES_PerfLogEntry(CF_PERF_ID_PDURCVD(chan_num)); CFE_MSG_GetSize(&bufptr->Msg, &msg_size); CFE_MSG_GetType(&bufptr->Msg, &msg_type); + if (msg_size > CF_PDU_ENCAPSULATION_EXTRA_TRAILING_BYTES) + { + /* Ignore/subtract any fixed trailing bytes */ + msg_size -= CF_PDU_ENCAPSULATION_EXTRA_TRAILING_BYTES; + } + else + { + /* bad message size - not supposed to happen */ + msg_size = 0; + } if (msg_type == CFE_MSG_Type_Tlm) { CF_CFDP_DecodeStart(&CF_AppData.engine.in.decode, bufptr, ph, offsetof(CF_PduTlmMsg_t, ph), msg_size); diff --git a/unit-test/cf_cfdp_sbintf_tests.c b/unit-test/cf_cfdp_sbintf_tests.c index 15ff10ff..df91c868 100644 --- a/unit-test/cf_cfdp_sbintf_tests.c +++ b/unit-test/cf_cfdp_sbintf_tests.c @@ -67,7 +67,7 @@ static void UT_CFDP_SetupBasicRxState(CF_Logical_PduBuffer_t *pdu_buffer) UT_SetDataBuffer(UT_KEY(CFE_SB_ReceiveBuffer), &bufptr, sizeof(bufptr), true); /* setup for a potential call to CFE_MSG_GetSize() */ - sz = sizeof(UT_r_msg); + sz = sizeof(UT_r_msg) + CF_PDU_ENCAPSULATION_EXTRA_TRAILING_BYTES; UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &sz, sizeof(sz), true); /* setup for a potential call to CFE_MSG_GetType() */ @@ -218,6 +218,7 @@ void Test_CF_CFDP_ReceiveMessage(void) CF_Transaction_t * t; CF_Logical_PduBuffer_t *ph; CFE_MSG_Type_t msg_type = CFE_MSG_Type_Tlm; + size_t * msg_size_buf; /* no-config - the max per wakeup will be 0, and this is a noop */ UT_CFDP_SetupBasicTestState(UT_CF_Setup_NONE, NULL, &c, NULL, NULL, NULL); @@ -229,6 +230,16 @@ void Test_CF_CFDP_ReceiveMessage(void) UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_NO_MESSAGE); UtAssert_VOIDCALL(CF_CFDP_ReceiveMessage(c)); + /* Set up with a zero size input message, this should fail decoding */ + msg_size_buf = 0; + UT_SetDeferredRetcode(UT_KEY(CF_CFDP_RecvPh), 1, -1); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &msg_size_buf, sizeof(msg_size_buf), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetType), &msg_type, sizeof(msg_type), false); + UtAssert_VOIDCALL(CF_CFDP_ReceiveMessage(c)); + UT_ResetState(UT_KEY(CF_CFDP_RecvPh)); + UT_ResetState(UT_KEY(CFE_MSG_GetSize)); + UT_ResetState(UT_KEY(CFE_MSG_GetType)); + /* * - CF_CFDP_RecvPh() succeeds * - CF_FindTransactionBySequenceNumber() returns NULL