diff --git a/docs/ds_FunctionalRequirements.csv b/docs/ds_FunctionalRequirements.csv index 3b0fa2f..0599d9b 100644 --- a/docs/ds_FunctionalRequirements.csv +++ b/docs/ds_FunctionalRequirements.csv @@ -72,6 +72,7 @@ a) Send an event message b) Increment total number of file write errors c) Close the destination file d) Disable the destination",Notify operators of error and prevent ongoing future errors caused by writing to the same destination file. +DS3006,DS3006,DS shall send a file information telemetry message when closing a data storage file.,Provides file information telemetry packet containing the current status for a closed destination file. DS5000,DS5000,"Upon receipt of a Disable command, DS shall stop filtering and storing messages. Note: This command will set the Packet Processing State to DISABLED.",Operational control of packet processing state (message storage) DS5001,DS5001,"Upon receipt of an Enable command, DS shall begin filtering and storing messages. diff --git a/fsw/platform_inc/ds_msgids.h b/fsw/platform_inc/ds_msgids.h index a2c7584..3068285 100644 --- a/fsw/platform_inc/ds_msgids.h +++ b/fsw/platform_inc/ds_msgids.h @@ -41,6 +41,7 @@ #define DS_HK_TLM_MID 0x08B8 /**< \brief DS Hk Telemetry Message ID ****/ #define DS_DIAG_TLM_MID 0x08B9 /**< \brief DS File Info Telemetry Message ID ****/ +#define DS_COMP_TLM_MID 0x08BA /**< \brief DS Completed File Info Telemetry Message ID ****/ /**\}*/ diff --git a/fsw/src/ds_file.c b/fsw/src/ds_file.c index e19e04c..768bb78 100644 --- a/fsw/src/ds_file.c +++ b/fsw/src/ds_file.c @@ -29,6 +29,7 @@ #include "ds_verify.h" #include "ds_appdefs.h" +#include "ds_msgids.h" #include "ds_msg.h" #include "ds_app.h" @@ -960,6 +961,11 @@ void DS_FileCloseDest(int32 FileIndex) "FILE MOVE error: dir name = '%s', filename = '%s'", PathName, FileName); } } + + /* + ** Get the directory name... + */ + strncpy(FileStatus->FileName, PathName, sizeof(PathName)); #else /* ** Close the file... @@ -967,6 +973,11 @@ void DS_FileCloseDest(int32 FileIndex) OS_close(FileStatus->FileHandle); #endif + /* + ** Transmit file information telemetry... + */ + DS_FileTransmit(FileStatus); + /* ** Reset status for this destination file... */ @@ -1025,6 +1036,65 @@ void DS_FileTestAge(uint32 ElapsedSeconds) } /* End of DS_FileTestAge() */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* */ +/* DS_FileTransmit() - transmit file info */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void DS_FileTransmit(DS_AppFileStatus_t *FileStatus) +{ + DS_FileCompletePktBuf_t *PktBuf; + + /* + ** Get a Message block of memory and initialize it + */ + PktBuf = (DS_FileCompletePktBuf_t *)CFE_SB_AllocateMessageBuffer(sizeof(*PktBuf)); + + /* + ** Process destination file info data... + */ + if (PktBuf != NULL) + { + CFE_MSG_Init(&PktBuf->Pkt.TlmHeader.Msg, CFE_SB_ValueToMsgId(DS_COMP_TLM_MID), sizeof(*PktBuf)); + + /* + ** Set file age and size... + */ + PktBuf->Pkt.FileInfo.FileAge = FileStatus->FileAge; + PktBuf->Pkt.FileInfo.FileSize = FileStatus->FileSize; + /* + ** Set file growth rate (computed when process last HK request)... + */ + PktBuf->Pkt.FileInfo.FileRate = FileStatus->FileRate; + /* + ** Set current filename sequence count... + */ + PktBuf->Pkt.FileInfo.SequenceCount = FileStatus->FileCount; + /* + ** Set file enable/disable state... + */ + PktBuf->Pkt.FileInfo.EnableState = FileStatus->FileState; + /* + ** Set file closed state... + */ + PktBuf->Pkt.FileInfo.OpenState = DS_CLOSED; + /* + ** Set current open filename... + */ + strcpy(PktBuf->Pkt.FileInfo.FileName, FileStatus->FileName); + + /* + ** Timestamp and send file info telemetry... + */ + CFE_SB_TimeStampMsg(&PktBuf->Pkt.TlmHeader.Msg); + CFE_SB_TransmitBuffer(&PktBuf->SBBuf, true); + } + + return; + +} /* End of DS_CmdGetCompleteFileInfo() */ + /************************/ /* End of File Comment */ /************************/ diff --git a/fsw/src/ds_file.h b/fsw/src/ds_file.h index 605f0e3..76dae64 100644 --- a/fsw/src/ds_file.h +++ b/fsw/src/ds_file.h @@ -288,6 +288,22 @@ void DS_FileCloseDest(int32 FileIndex); */ void DS_FileTestAge(uint32 ElapsedSeconds); +/** + * \brief Transmit file information telemetry handler + * + * \par Description + * Create and send a telemetry packet containing the current + * status for a closed destination file. + * + * \par Assumptions, External Events, and Notes: + * (none) + * + * \param[in] FileStatus Current state of destination file + * + * \sa #DS_FileCompletePktBuf_t + */ +void DS_FileTransmit(DS_AppFileStatus_t *FileStatus); + /** * \brief Determine whether Software Bus message packet is filtered * diff --git a/fsw/src/ds_msg.h b/fsw/src/ds_msg.h index 9e2d9c3..3e8c54a 100644 --- a/fsw/src/ds_msg.h +++ b/fsw/src/ds_msg.h @@ -356,6 +356,28 @@ typedef struct DS_FileInfo_t FileInfo[DS_DEST_FILE_CNT]; /**< \brief Current state of destination files */ } DS_FileInfoPkt_t; +/** + * \brief Single application file info packet + */ +typedef struct +{ + CFE_MSG_TelemetryHeader_t TlmHeader; /**< \brief cFE Software Bus telemetry message header */ + + DS_FileInfo_t FileInfo; /**< \brief Current state of destination file */ +} DS_FileCompletePkt_t; + +/** + * \brief Single application file info packet buffer + * + * This typedef supports CFE_SB_AllocateMessageBuffer use with a DS_FileCompletePkt_t + * that compiles with the alignment constraints of a CFE_SB_Buffer_t + */ +typedef union +{ + CFE_SB_Buffer_t SBBuf; /**< \brief Message buffer for alignment */ + DS_FileCompletePkt_t Pkt; /**< \brief Single application file info packet */ +} DS_FileCompletePktBuf_t; + /**\}*/ #endif diff --git a/unit-test/ds_file_tests.c b/unit-test/ds_file_tests.c index e0abfe7..6399188 100644 --- a/unit-test/ds_file_tests.c +++ b/unit-test/ds_file_tests.c @@ -1739,6 +1739,37 @@ void DS_IsPacketFiltered_Test_TimeFilter3(void) UtAssert_BOOL_TRUE(Result); } +void DS_FileTransmit_Test_Nominal(void) +{ + DS_FileCompletePktBuf_t PktBuf; + DS_FileCompletePktBuf_t *PktBufPtr = &PktBuf; + + /* setup for a call to CFE_SB_AllocateMessageBuffer() */ + memset(PktBufPtr, 0, sizeof(*PktBufPtr)); + UT_SetDataBuffer(UT_KEY(CFE_SB_AllocateMessageBuffer), &PktBufPtr, sizeof(PktBufPtr), true); + + /* Execute the function being tested */ + UtAssert_VOIDCALL(DS_FileTransmit(&DS_AppData.FileStatus[0])); + + /* Verify results */ + UtAssert_STUB_COUNT(CFE_SB_AllocateMessageBuffer, 1); + UtAssert_STUB_COUNT(CFE_MSG_Init, 1); + UtAssert_STUB_COUNT(CFE_SB_TimeStampMsg, 1); + UtAssert_STUB_COUNT(CFE_SB_TransmitBuffer, 1); +} + +void DS_FileTransmit_Test_NoBuf(void) +{ + /* Execute the function being tested */ + UtAssert_VOIDCALL(DS_FileTransmit(&DS_AppData.FileStatus[0])); + + /* Verify results */ + UtAssert_STUB_COUNT(CFE_SB_AllocateMessageBuffer, 1); + UtAssert_STUB_COUNT(CFE_MSG_Init, 0); + UtAssert_STUB_COUNT(CFE_SB_TimeStampMsg, 0); + UtAssert_STUB_COUNT(CFE_SB_TransmitBuffer, 0); +} + void UtTest_Setup(void) { UtTest_Add(DS_FileStorePacket_Test_Nominal, DS_Test_Setup, DS_Test_TearDown, "DS_FileStorePacket_Test_Nominal"); @@ -1855,6 +1886,9 @@ void UtTest_Setup(void) UtTest_Add(DS_IsPacketFiltered_Test_TimeFilter3, DS_Test_Setup, DS_Test_TearDown, "DS_IsPacketFiltered_Test_TimeFilter3"); + UtTest_Add(DS_FileTransmit_Test_Nominal, DS_Test_Setup, DS_Test_TearDown, "DS_FileTransmit_Test_Nominal"); + UtTest_Add(DS_FileTransmit_Test_NoBuf, DS_Test_Setup, DS_Test_TearDown, "DS_FileTransmit_Test_NoBuf"); + } /* end DS_File_Test_AddTestCases */ /************************/