mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
* Format Svc and add to CI * Fix comlogger include * fix assert UTs * Fix static analysis warning * formatting
246 lines
9.7 KiB
C++
246 lines
9.7 KiB
C++
// ======================================================================
|
|
// \title DpCatalog.hpp
|
|
// \author tcanham
|
|
// \brief hpp file for DpCatalog component implementation class
|
|
// ======================================================================
|
|
|
|
#ifndef Svc_DpCatalog_HPP
|
|
#define Svc_DpCatalog_HPP
|
|
|
|
#include "Svc/DpCatalog/DpCatalogComponentAc.hpp"
|
|
#include "Svc/DpCatalog/DpRecordSerializableAc.hpp"
|
|
|
|
#include <Fw/Types/MemAllocator.hpp>
|
|
|
|
#include <Fw/Types/FileNameString.hpp>
|
|
#include <config/DpCatalogCfg.hpp>
|
|
#include <config/DpCfg.hpp>
|
|
|
|
namespace Svc {
|
|
|
|
class DpCatalog final : public DpCatalogComponentBase {
|
|
friend class DpCatalogTester;
|
|
|
|
public:
|
|
// ----------------------------------------------------------------------
|
|
// Component construction and destruction
|
|
// ----------------------------------------------------------------------
|
|
|
|
/// @brief DpCatalog constructor
|
|
/// @param compName component name
|
|
DpCatalog(const char* const compName //!< The component name
|
|
);
|
|
|
|
/// @brief DpCatalog destructor
|
|
~DpCatalog();
|
|
|
|
/// @brief Configure the DpCatalog
|
|
/// @param maxDpFiles The max number of data product files to track
|
|
/// @param directories list of directories to scan
|
|
/// @param numDirs number of supplied directories
|
|
/// @param stateFile file to store transmit state. Provide a zero-length string if no state tracking
|
|
/// @param memId memory ID for allocator
|
|
/// @param allocator Allocator to supply memory for catalog.
|
|
/// Instance must survive for shutdown to use for reclaiming memory
|
|
void configure(Fw::FileNameString directories[DP_MAX_DIRECTORIES],
|
|
FwSizeType numDirs,
|
|
Fw::FileNameString& stateFile,
|
|
FwEnumStoreType memId,
|
|
Fw::MemAllocator& allocator);
|
|
|
|
// @brief clean up component.
|
|
// Deallocates memory.
|
|
void shutdown();
|
|
|
|
private:
|
|
// ----------------------------------------------------------------------
|
|
// Handler implementations for user-defined typed input ports
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! Handler implementation for fileDone
|
|
//!
|
|
//! File Downlink send complete port
|
|
void fileDone_handler(FwIndexType portNum, //!< The port number
|
|
const Svc::SendFileResponse& resp) override;
|
|
|
|
//! Handler implementation for pingIn
|
|
//!
|
|
//! Ping input port
|
|
void pingIn_handler(FwIndexType portNum, //!< The port number
|
|
U32 key //!< Value to return to pinger
|
|
) override;
|
|
|
|
private:
|
|
// ----------------------------------------------------------------------
|
|
// Handler implementations for commands
|
|
// ----------------------------------------------------------------------
|
|
|
|
//! Handler implementation for command BUILD_CATALOG
|
|
//!
|
|
//! Build catalog from data product directory
|
|
void BUILD_CATALOG_cmdHandler(FwOpcodeType opCode, //!< The opcode
|
|
U32 cmdSeq //!< The command sequence number
|
|
) override;
|
|
|
|
//! Handler implementation for command START_XMIT_CATALOG
|
|
//!
|
|
//! Start transmitting catalog
|
|
void START_XMIT_CATALOG_cmdHandler(
|
|
FwOpcodeType opCode, //!< The opcode
|
|
U32 cmdSeq, //!< The command sequence number
|
|
Fw::Wait wait //!< have START_XMIT command wait for catalog to complete transmitting
|
|
) override;
|
|
|
|
//! Handler implementation for command STOP_XMIT_CATALOG
|
|
//!
|
|
//! Stop transmitting catalog
|
|
void STOP_XMIT_CATALOG_cmdHandler(FwOpcodeType opCode, //!< The opcode
|
|
U32 cmdSeq //!< The command sequence number
|
|
) override;
|
|
|
|
//! Handler implementation for command CLEAR_CATALOG
|
|
//!
|
|
//! clear existing catalog
|
|
void CLEAR_CATALOG_cmdHandler(FwOpcodeType opCode, //!< The opcode
|
|
U32 cmdSeq //!< The command sequence number
|
|
) override;
|
|
|
|
// ----------------------------------
|
|
// Private data structures
|
|
// ----------------------------------
|
|
|
|
struct DpStateEntry {
|
|
friend class DpCatalogTester;
|
|
FwIndexType dir; //!< index to m_directories entry that has directory name where DP exists
|
|
DpRecord record; //!< data product metadata
|
|
};
|
|
|
|
struct DpDstateFileEntry {
|
|
bool used; //!< if the entry is used
|
|
bool visited; //!< used for state file state; indicates that the entry was found in the search of current data
|
|
//!< products
|
|
DpStateEntry entry; //!< state entry from file
|
|
};
|
|
|
|
/// @brief A list sorted in priority order for downlink
|
|
struct DpBtreeNode {
|
|
DpStateEntry entry; //!< pointer to DP record
|
|
DpBtreeNode* left; //!< left child. Also used for free list
|
|
DpBtreeNode* right; //!< right child
|
|
};
|
|
|
|
// ----------------------------------
|
|
// Private helpers
|
|
// ----------------------------------
|
|
|
|
/// @brief insert an entry into the sorted list; if it exists, update the metadata
|
|
/// @param entry new entry
|
|
/// @return failed if couldn't find a slot FIXME: Should we just assert? We should never run out.
|
|
bool insertEntry(DpStateEntry& entry);
|
|
|
|
/// @brief delete an entry from the sorted list
|
|
/// @param entry new entry
|
|
void deleteEntry(DpStateEntry& entry);
|
|
|
|
/// @brief enumeration for check and insert function
|
|
enum CheckStat {
|
|
CHECK_OK, //!< check passed and inserted. Can break loop
|
|
CHECK_CONT, //!< check passed and find another node to check
|
|
CHECK_ERROR, //!< check failed to allocate an entry. Quit function
|
|
};
|
|
|
|
/// @brief check for left/right insertion
|
|
CheckStat checkLeftRight(bool condition, DpBtreeNode*& node, const DpStateEntry& newEntry);
|
|
|
|
/// @brief reset the free list
|
|
void resetBinaryTree();
|
|
|
|
/// #brief fill the binary tree from DP files
|
|
Fw::CmdResponse fillBinaryTree();
|
|
|
|
/// @brief reset the tree stack
|
|
void resetTreeStack();
|
|
|
|
/// @brief reset the state file data
|
|
void resetStateFileData();
|
|
|
|
/// @brief get file state from the stored state file
|
|
/// @param entry entry to update from file state
|
|
void getFileState(DpStateEntry& entry);
|
|
|
|
/// @brief prune the state file data and write the remaining entries back
|
|
void pruneAndWriteStateFile();
|
|
|
|
/// @brief load state data from file
|
|
Fw::CmdResponse loadStateFile();
|
|
|
|
/// @brief get file state from the stored state file
|
|
/// @param entry entry to add to state file
|
|
void appendFileState(const DpStateEntry& entry);
|
|
|
|
/// @brief add an entry to the tree
|
|
/// @param entry entry to add
|
|
/// @return true if a node could be allocated
|
|
bool allocateNode(DpBtreeNode*& newNode, const DpStateEntry& newEntry);
|
|
|
|
/// @brief send the next entry to file downlink
|
|
void sendNextEntry();
|
|
|
|
/// @brief find the next entry in the tree
|
|
/// @return pointer if an entry was found, nullptr if no more entries
|
|
/// @param entry entry to return
|
|
DpBtreeNode* findNextTreeNode();
|
|
|
|
/// @brief check to see if component successfully initialized
|
|
/// @return bool if it was initialized
|
|
bool checkInit();
|
|
|
|
/// @brief build catalog. Shared between command and port
|
|
/// @return command response for pass/fail
|
|
Fw::CmdResponse doCatalogBuild();
|
|
|
|
/// @brief start transmitting catalog. Shared between command and port
|
|
/// @return command response for pass/fail
|
|
Fw::CmdResponse doCatalogXmit();
|
|
|
|
// ----------------------------------
|
|
// Private data
|
|
// ----------------------------------
|
|
bool m_initialized; //!< set when the component has been initialized
|
|
|
|
DpBtreeNode* m_dpTree; //!< The head of the binary tree
|
|
DpBtreeNode* m_freeListHead; //!< The head of the free list
|
|
DpBtreeNode* m_freeListFoot; //!< The foot of the free list
|
|
DpBtreeNode** m_traverseStack; //!< pointer to memory for stack for traversing tree
|
|
DpBtreeNode* m_currentNode; //!< current node for traversing tree
|
|
DpBtreeNode* m_currentXmitNode; //!< node being currently transmitted
|
|
|
|
FwSizeType m_numDpRecords; //!< Stores the actual number of records.
|
|
FwSizeType m_numDpSlots; //!< Stores the available number of record slots.
|
|
|
|
Fw::FileNameString m_directories[DP_MAX_DIRECTORIES]; //!< List of supplied DP directories
|
|
FwSizeType m_numDirectories; //!< number of supplied directories
|
|
Fw::String m_fileList[DP_MAX_FILES]; //!< working array of files/directory
|
|
|
|
Fw::FileNameString m_stateFile; //!< file to store transmit state
|
|
DpDstateFileEntry* m_stateFileData; //!< DP state loaded from file
|
|
FwSizeType m_stateFileEntries; //!< size of state file data
|
|
|
|
FwSizeType m_memSize; //!< size of allocated buffer
|
|
void* m_memPtr; //!< stored for shutdown
|
|
FwEnumStoreType m_allocatorId; //!< stored for shutdown
|
|
Fw::MemAllocator* m_allocator; //!< stored for shutdown
|
|
|
|
bool m_xmitInProgress; //!< set if DP files are in the process of being sent
|
|
FwIndexType m_currStackEntry; //!< current stack entry for traversing tree
|
|
Fw::FileNameString m_currXmitFileName; //!< current file being transmitted
|
|
bool m_xmitCmdWait; //!< true if waiting for transmission complete to complete xmit command
|
|
U64 m_xmitBytes; //!< bytes transmitted for downlink session
|
|
FwOpcodeType m_xmitOpCode; //!< stored xmit command opcode
|
|
U32 m_xmitCmdSeq; //!< stored command sequence id
|
|
};
|
|
|
|
} // namespace Svc
|
|
|
|
#endif
|