diff --git a/config/default_cf_msgdefs.h b/config/default_cf_msgdefs.h index 285aedf2..274becb8 100644 --- a/config/default_cf_msgdefs.h +++ b/config/default_cf_msgdefs.h @@ -50,6 +50,8 @@ typedef struct CF_HkSent uint64 file_data_bytes; /**< \brief Sent File data bytes */ uint32 pdu; /**< \brief Sent PDUs counter */ uint32 nak_segment_requests; /**< \brief Sent NAK segment requests counter */ + uint32 files_sent; /**< \brief Files successfully sent counter */ + uint8 spare[4]; /**< \brief Alignment spare to avoid implicit padding */ } CF_HkSent_t; /** @@ -66,6 +68,8 @@ typedef struct CF_HkRecv */ uint16 dropped; /**< \brief Received PDUs dropped due to a transaction error */ uint32 nak_segment_requests; /**< \brief Received NAK segment requests counter */ + uint32 files_recv; /**< \brief Files successfully received counter */ + uint8 spare[4]; /**< \brief Alignment spare to avoid implicit padding */ } CF_HkRecv_t; /** diff --git a/cosmos/big_endian/CF/cf_tlm.txt b/cosmos/big_endian/CF/cf_tlm.txt index 1bb09420..8f64619e 100644 --- a/cosmos/big_endian/CF/cf_tlm.txt +++ b/cosmos/big_endian/CF/cf_tlm.txt @@ -9,12 +9,16 @@ TELEMETRY CF HK_TLM_PKT BIG_ENDIAN "CFDP housekeeping Packet" APPEND_ITEM SENT_FD0 64 UINT "File data bytes sent" APPEND_ITEM SENT_PDU0 32 UINT "Count of PDUs sent" APPEND_ITEM SENT_NAK_SR0 32 UINT "Count of sent segment requests" + APPEND_ITEM SENT_FILES0 32 UINT "Count of files successfully sent" + APPEND_ITEM SENT_SPARE0 32 UINT "" APPEND_ITEM RECV_FD0 64 UINT "File data bytes received" APPEND_ITEM RECV_PDU0 32 UINT "Count of PDUs received" APPEND_ITEM RECV_PDU_ERROR0 32 UINT "Count of invalid PDUs received" APPEND_ITEM RECV_PDU_SPURIOUS0 16 UINT "Count of spurious PDUs received" APPEND_ITEM RECV_PDU_DROPPED0 16 UINT "Count of dropped PDUs received" APPEND_ITEM RECV_NAK_SR0 32 UINT "Count of received segment requests" + APPEND_ITEM RECV_FILES0 32 UINT "Count of files successfully received" + APPEND_ITEM RECV_SPARE0 32 UINT "" APPEND_ITEM FAULT_FILE_OPEN0 16 UINT "Count of file open errors" APPEND_ITEM FAULT_FILE_READ0 16 UINT "Count of file read errors" APPEND_ITEM FAULT_FILE_SEEK0 16 UINT "Count of file seek errors" @@ -42,12 +46,16 @@ TELEMETRY CF HK_TLM_PKT BIG_ENDIAN "CFDP housekeeping Packet" APPEND_ITEM SENT_FD1 64 UINT "File data bytes sent" APPEND_ITEM SENT_PDU1 32 UINT "Count of PDUs sent" APPEND_ITEM SENT_NAK_SR1 32 UINT "Count of sent segment requests" + APPEND_ITEM SENT_FILES1 32 UINT "Count of files successfully sent" + APPEND_ITEM SENT_SPARE1 32 UINT "" APPEND_ITEM RECV_FD1 64 UINT "File data bytes received" APPEND_ITEM RECV_PDU1 32 UINT "Count of PDUs received" APPEND_ITEM RECV_PDU_ERROR1 32 UINT "Count of invalid PDUs received" APPEND_ITEM RECV_PDU_SPURIOUS1 16 UINT "Count of spurious PDUs received" APPEND_ITEM RECV_PDU_DROPPED1 16 UINT "Count of dropped PDUs received" APPEND_ITEM RECV_NAK_SR1 32 UINT "Count of received segment requests" + APPEND_ITEM RECV_FILES1 32 UINT "Count of files successfully received" + APPEND_ITEM RECV_SPARE1 32 UINT "" APPEND_ITEM FAULT_FILE_OPEN1 16 UINT "Count of file open errors" APPEND_ITEM FAULT_FILE_READ1 16 UINT "Count of file read errors" APPEND_ITEM FAULT_FILE_SEEK1 16 UINT "Count of file seek errors" diff --git a/cosmos/little_endian/CF/cf_tlm.txt b/cosmos/little_endian/CF/cf_tlm.txt index 4b3a3e52..2208e2dd 100644 --- a/cosmos/little_endian/CF/cf_tlm.txt +++ b/cosmos/little_endian/CF/cf_tlm.txt @@ -9,12 +9,16 @@ TELEMETRY CF HK_TLM_PKT LITTLE_ENDIAN "CFDP housekeeping Packet" APPEND_ITEM SENT_FD0 64 UINT "File data bytes sent" APPEND_ITEM SENT_PDU0 32 UINT "Count of PDUs sent" APPEND_ITEM SENT_NAK_SR0 32 UINT "Count of sent segment requests" + APPEND_ITEM SENT_FILES0 32 UINT "Count of files successfully sent" + APPEND_ITEM SENT_SPARE0 32 UINT "" APPEND_ITEM RECV_FD0 64 UINT "File data bytes received" APPEND_ITEM RECV_PDU0 32 UINT "Count of PDUs received" APPEND_ITEM RECV_PDU_ERROR0 32 UINT "Count of invalid PDUs received" APPEND_ITEM RECV_PDU_SPURIOUS0 16 UINT "Count of spurious PDUs received" APPEND_ITEM RECV_PDU_DROPPED0 16 UINT "Count of dropped PDUs received" APPEND_ITEM RECV_NAK_SR0 32 UINT "Count of received segment requests" + APPEND_ITEM RECV_FILES0 32 UINT "Count of files successfully received" + APPEND_ITEM RECV_SPARE0 32 UINT "" APPEND_ITEM FAULT_FILE_OPEN0 16 UINT "Count of file open errors" APPEND_ITEM FAULT_FILE_READ0 16 UINT "Count of file read errors" APPEND_ITEM FAULT_FILE_SEEK0 16 UINT "Count of file seek errors" @@ -42,12 +46,16 @@ TELEMETRY CF HK_TLM_PKT LITTLE_ENDIAN "CFDP housekeeping Packet" APPEND_ITEM SENT_FD1 64 UINT "File data bytes sent" APPEND_ITEM SENT_PDU1 32 UINT "Count of PDUs sent" APPEND_ITEM SENT_NAK_SR1 32 UINT "Count of sent segment requests" + APPEND_ITEM SENT_FILES1 32 UINT "Count of files successfully sent" + APPEND_ITEM SENT_SPARE1 32 UINT "" APPEND_ITEM RECV_FD1 64 UINT "File data bytes received" APPEND_ITEM RECV_PDU1 32 UINT "Count of PDUs received" APPEND_ITEM RECV_PDU_ERROR1 32 UINT "Count of invalid PDUs received" APPEND_ITEM RECV_PDU_SPURIOUS1 16 UINT "Count of spurious PDUs received" APPEND_ITEM RECV_PDU_DROPPED1 16 UINT "Count of dropped PDUs received" APPEND_ITEM RECV_NAK_SR1 32 UINT "Count of received segment requests" + APPEND_ITEM RECV_FILES1 32 UINT "Count of files successfully received" + APPEND_ITEM RECV_SPARE1 32 UINT "" APPEND_ITEM FAULT_FILE_OPEN1 16 UINT "Count of file open errors" APPEND_ITEM FAULT_FILE_READ1 16 UINT "Count of file read errors" APPEND_ITEM FAULT_FILE_SEEK1 16 UINT "Count of file seek errors" diff --git a/docs/cf_FunctionalRequirements.csv b/docs/cf_FunctionalRequirements.csv index 9c14b1d4..9c4fe001 100644 --- a/docs/cf_FunctionalRequirements.csv +++ b/docs/cf_FunctionalRequirements.csv @@ -148,7 +148,9 @@ CF6000,CF6000,"The CF Housekeeping message shall include 11. Number of Inactivity Timer-Limit Faults 12. Number of CRC Mismatch Faults 13. Number of Filestore Rejection Faults (can be split by type) -14. Number of Filesize Mismatch Faults",Operator interface that provides detailed status on operational state +14. Number of Filesize Mismatch Faults +15. Number of Files successfully sent +16. Number of Files successfully received",Operator interface that provides detailed status on operational state CF6001,CF6001,"The CF End of Transaction message shall include 1. Transaction identifier 2. Channel number diff --git a/eds/cf.xml b/eds/cf.xml index 21edcbc8..fb21c997 100644 --- a/eds/cf.xml +++ b/eds/cf.xml @@ -196,6 +196,8 @@ + + @@ -208,6 +210,8 @@ file directive FIN without matching active transaction counter" /> + + diff --git a/fsw/src/cf_cfdp_r.c b/fsw/src/cf_cfdp_r.c index a0b69092..e263bddd 100644 --- a/fsw/src/cf_cfdp_r.c +++ b/fsw/src/cf_cfdp_r.c @@ -1065,6 +1065,11 @@ void CF_CFDP_R_CheckState(CF_Transaction_t *txn) txn->flags.rx.send_fin = true; break; case CF_RxSubState_COMPLETE: + /* only a transaction that reached this point without error received a complete file */ + if (CF_CFDP_TxnIsOK(txn)) + { + ++CF_AppData.hk.Payload.channel_hk[txn->chan_num].counters.recv.files_recv; + } /* This changes the txn state such that this function is no longer called. */ CF_CFDP_FinishTransaction(txn, true); break; diff --git a/fsw/src/cf_cfdp_s.c b/fsw/src/cf_cfdp_s.c index 8ec9040f..5cdf8a26 100644 --- a/fsw/src/cf_cfdp_s.c +++ b/fsw/src/cf_cfdp_s.c @@ -868,6 +868,11 @@ void CF_CFDP_S_CheckState(CF_Transaction_t *txn) txn->flags.tx.send_eof = true; break; case CF_TxSubState_COMPLETE: + /* only a transaction that reached this point without error sent a complete file */ + if (CF_CFDP_TxnIsOK(txn)) + { + ++CF_AppData.hk.Payload.channel_hk[txn->chan_num].counters.sent.files_sent; + } /* This changes the txn state such that this function is no longer called. */ CF_CFDP_FinishTransaction(txn, true); break; diff --git a/unit-test/cf_cfdp_r_tests.c b/unit-test/cf_cfdp_r_tests.c index d4e8a2fd..364f0674 100644 --- a/unit-test/cf_cfdp_r_tests.c +++ b/unit-test/cf_cfdp_r_tests.c @@ -1214,10 +1214,13 @@ void Test_CF_CFDP_R_CheckState_FINACK(void) txn->flags.com.ack_timer_armed = false; txn->state_data.sub_state = CF_RxSubState_FINACK; UT_SetDeferredRetcode(UT_KEY(CF_CFDP_CheckAckNakCount), 1, false); + UT_SetDefaultReturnValue(UT_KEY(CF_CFDP_TxnIsOK), true); UtAssert_VOIDCALL(CF_CFDP_R_CheckState(txn)); UtAssert_UINT8_EQ(txn->state_data.sub_state, CF_RxSubState_COMPLETE); UtAssert_BOOL_FALSE(txn->flags.rx.send_fin); UtAssert_STUB_COUNT(CF_CFDP_FinishTransaction, 1); + /* the fin-ack never arrived but the file itself was received without error */ + UtAssert_UINT32_EQ(CF_AppData.hk.Payload.channel_hk[txn->chan_num].counters.recv.files_recv, 1); /* FINACK state, R2, fin sent, not acked, inactivity reached */ UT_ResetState(0); @@ -1227,10 +1230,13 @@ void Test_CF_CFDP_R_CheckState_FINACK(void) txn->flags.rx.send_fin = false; txn->flags.com.inactivity_fired = true; txn->state_data.sub_state = CF_RxSubState_FINACK; + UT_SetDefaultReturnValue(UT_KEY(CF_CFDP_TxnIsOK), false); UtAssert_VOIDCALL(CF_CFDP_R_CheckState(txn)); UtAssert_UINT8_EQ(txn->state_data.sub_state, CF_RxSubState_COMPLETE); UtAssert_BOOL_FALSE(txn->flags.rx.send_fin); UtAssert_STUB_COUNT(CF_CFDP_FinishTransaction, 1); + /* inactivity is a failure, so the count must remain at the 1 from the prior case */ + UtAssert_UINT32_EQ(CF_AppData.hk.Payload.channel_hk[txn->chan_num].counters.recv.files_recv, 1); } void Test_CF_CFDP_R_CheckState_COMPLETE(void) diff --git a/unit-test/cf_cfdp_s_tests.c b/unit-test/cf_cfdp_s_tests.c index 4c9f77f7..00fe5c37 100644 --- a/unit-test/cf_cfdp_s_tests.c +++ b/unit-test/cf_cfdp_s_tests.c @@ -1068,11 +1068,25 @@ void Test_CF_CFDP_S_CheckState_FILESTORE(void) */ CF_Transaction_t *txn; + /* nominal, transaction reached the end without error */ UT_CFDP_S_SetupBasicTestState(UT_CF_Setup_NONE, NULL, NULL, NULL, &txn, NULL); + UT_SetDefaultReturnValue(UT_KEY(CF_CFDP_TxnIsOK), true); + txn->state_data.sub_state = CF_TxSubState_FILESTORE; + UtAssert_VOIDCALL(CF_CFDP_S_CheckState(txn)); + UtAssert_UINT8_EQ(txn->state_data.sub_state, CF_TxSubState_COMPLETE); + UtAssert_STUB_COUNT(CF_CFDP_FinishTransaction, 1); + UtAssert_UINT32_EQ(CF_AppData.hk.Payload.channel_hk[txn->chan_num].counters.sent.files_sent, 1); + + /* transaction reached the end in an error state, so no file was successfully sent */ + UT_ResetState(0); + UT_CFDP_S_SetupBasicTestState(UT_CF_Setup_NONE, NULL, NULL, NULL, &txn, NULL); + UT_SetDefaultReturnValue(UT_KEY(CF_CFDP_TxnIsOK), false); txn->state_data.sub_state = CF_TxSubState_FILESTORE; UtAssert_VOIDCALL(CF_CFDP_S_CheckState(txn)); UtAssert_UINT8_EQ(txn->state_data.sub_state, CF_TxSubState_COMPLETE); UtAssert_STUB_COUNT(CF_CFDP_FinishTransaction, 1); + /* the error case must not count, so the total remains at the 1 from the prior case */ + UtAssert_UINT32_EQ(CF_AppData.hk.Payload.channel_hk[txn->chan_num].counters.sent.files_sent, 1); } void Test_CF_CFDP_S_CheckState_COMPLETE(void) diff --git a/unit-test/cf_cmd_tests.c b/unit-test/cf_cmd_tests.c index c9c7fcc2..e72a1910 100644 --- a/unit-test/cf_cmd_tests.c +++ b/unit-test/cf_cmd_tests.c @@ -267,7 +267,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_fault_ResetAllHkFaultCount UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.fault.inactivity_timer); UtAssert_MemCmpValue(&CF_AppData.hk.Payload.channel_hk[i].counters.fault, 0, - sizeof(&CF_AppData.hk.Payload.channel_hk[i].counters.fault), + sizeof(CF_AppData.hk.Payload.channel_hk[i].counters.fault), "fault channel %d was completely cleared to 0", i); } @@ -295,6 +295,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_up_AndResetAllHkRecvCountS CF_AppData.hk.Payload.channel_hk[i].counters.recv.spurious = Any_uint16_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.recv.dropped = Any_uint16_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.recv.nak_segment_requests = Any_uint32_Except(0); + CF_AppData.hk.Payload.channel_hk[i].counters.recv.files_recv = Any_uint32_Except(0); } CF_AppData.hk.Payload.counters.cmd = initial_hk_cmd_counter; @@ -314,9 +315,10 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_up_AndResetAllHkRecvCountS UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.recv.spurious); UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.recv.pdu); UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.recv.nak_segment_requests); + UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.recv.files_recv); UtAssert_MemCmpValue(&CF_AppData.hk.Payload.channel_hk[i].counters.recv, 0, - sizeof(&CF_AppData.hk.Payload.channel_hk[i].counters.recv), + sizeof(CF_AppData.hk.Payload.channel_hk[i].counters.recv), "recv channel %d was completely cleared to 0", i); } @@ -341,6 +343,7 @@ void Test_CF_ResetCountersCmd_tests_SWhenCommandByteIs_down_AndResetAllHkSentCou CF_AppData.hk.Payload.channel_hk[i].counters.sent.file_data_bytes = Any_uint64_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.sent.nak_segment_requests = Any_uint32_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.sent.pdu = Any_uint32_Except(0); + CF_AppData.hk.Payload.channel_hk[i].counters.sent.files_sent = Any_uint32_Except(0); } CF_AppData.hk.Payload.counters.cmd = initial_hk_cmd_counter; @@ -357,9 +360,10 @@ void Test_CF_ResetCountersCmd_tests_SWhenCommandByteIs_down_AndResetAllHkSentCou UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.sent.file_data_bytes); UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.sent.nak_segment_requests); UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.sent.pdu); + UtAssert_ZERO(CF_AppData.hk.Payload.channel_hk[i].counters.sent.files_sent); UtAssert_MemCmpValue(&CF_AppData.hk.Payload.channel_hk[i].counters.sent, 0, - sizeof(&CF_AppData.hk.Payload.channel_hk[i].counters.sent), + sizeof(CF_AppData.hk.Payload.channel_hk[i].counters.sent), "sent channel %d was completely cleared to 0", i); } @@ -404,6 +408,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_all_AndResetAllMemValuesSe CF_AppData.hk.Payload.channel_hk[i].counters.recv.spurious = Any_uint16_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.recv.dropped = Any_uint16_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.recv.nak_segment_requests = Any_uint32_Except(0); + CF_AppData.hk.Payload.channel_hk[i].counters.recv.files_recv = Any_uint32_Except(0); } for (i = 0; i < CF_NUM_CHANNELS; ++i) @@ -411,6 +416,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_all_AndResetAllMemValuesSe CF_AppData.hk.Payload.channel_hk[i].counters.sent.file_data_bytes = Any_uint64_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.sent.nak_segment_requests = Any_uint32_Except(0); CF_AppData.hk.Payload.channel_hk[i].counters.sent.pdu = Any_uint32_Except(0); + CF_AppData.hk.Payload.channel_hk[i].counters.sent.files_sent = Any_uint32_Except(0); } /* Act */ @@ -426,7 +432,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_all_AndResetAllMemValuesSe { UtAssert_MemCmpValue(&CF_AppData.hk.Payload.channel_hk[i].counters.fault, 0, - sizeof(&CF_AppData.hk.Payload.channel_hk[i].counters.fault), + sizeof(CF_AppData.hk.Payload.channel_hk[i].counters.fault), "fault channel %d was completely cleared to 0", i); } @@ -434,7 +440,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_all_AndResetAllMemValuesSe { UtAssert_MemCmpValue(&CF_AppData.hk.Payload.channel_hk[i].counters.recv, 0, - sizeof(&CF_AppData.hk.Payload.channel_hk[i].counters.recv), + sizeof(CF_AppData.hk.Payload.channel_hk[i].counters.recv), "recv channel %d was completely cleared to 0", i); } @@ -442,7 +448,7 @@ void Test_CF_ResetCountersCmd_tests_WhenCommandByteIs_all_AndResetAllMemValuesSe { UtAssert_MemCmpValue(&CF_AppData.hk.Payload.channel_hk[i].counters.sent, 0, - sizeof(&CF_AppData.hk.Payload.channel_hk[i].counters.sent), + sizeof(CF_AppData.hk.Payload.channel_hk[i].counters.sent), "sent channel %d was completely cleared to 0", i); }