diff --git a/CMakeLists.txt b/CMakeLists.txt index ed0457f538dbe760a589b4edf94c4f02efa739cf..915214f04071a4e45129c0012b32517f6a4f5909 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,11 @@ cmake_minimum_required(VERSION 3.9) project(Base_DAQ) - -set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++20") +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") file(GLOB INCLUDE_FILES "include/*.h") -file(GLOB TCLAP "include/tclap") set(CMAKE_INSTALL_MESSAGE LAZY) @@ -15,8 +13,3 @@ install( FILES ${INCLUDE_FILES} DESTINATION "${CMAKE_INSTALL_PREFIX}/include/Base_DAQ" ) - -install( - DIRECTORY ${TCLAP} - DESTINATION "${CMAKE_INSTALL_PREFIX}/include" -) \ No newline at end of file diff --git a/include/Base_Archiver.h b/include/Base_Archiver.h index 8af7ae1177363ff3ca294f41844f1982d275c1d6..8e7a2ca5e4db685bdcfa10a37fad30e74cab0280 100755 --- a/include/Base_Archiver.h +++ b/include/Base_Archiver.h @@ -1,28 +1,90 @@ - #pragma once #include #include +namespace inaf::oasbo::Archivers { -namespace inaf::oasbo::Archivers{ - - -class BaseArchiver{ +/** + * @brief The BaseArchiver class is an abstract base class for archivers. + * + * This class provides a common interface for archiving packets. Derived classes + * must implement the pure virtual functions defined in this class. + */ +class BaseArchiver { protected: - std::string dest; + std::string dest; /**< The destination of the archiver. */ public: - virtual int write(PacketLib::BasePacket &) = 0; - virtual int write(PacketLib::BasePacket &, std::string destination) = 0; + /** + * @brief Write a packet to the archiver. + * + * This function writes the given packet to the "archive". + * + * @param packet The packet to write. + * @return An integer indicating the success or failure of the write operation. + */ + virtual int write(Packets::BasePacket&) = 0; + /** + * @brief Write a packet to the archiver with a specified destination. + * + * This function writes the given packet to the archiver with the specified destination. + * + * @param packet The packet to write. + * @param destination The destination where the packet should be written. + * @return An integer indicating the success or failure of the write operation. + */ + virtual int write(Packets::BasePacket&, std::string destination) = 0; + /** + * @brief Open the archiver. + * + * This function opens the archiver. + * + * @return An integer indicating the success or failure of the open operation. + */ virtual int open()=0; + + /** + * @brief Close the archiver. + * + * This function closes the archiver. + * + * @return An integer indicating the success or failure of the close operation. + */ virtual int close()=0; + + /** + * @brief Check if the archiver is open. + * + * This function checks if the archiver is open. + * + * @return A boolean value indicating whether the archiver is open or not. + */ virtual bool is_open()=0; + + /** + * @brief Set the destination of the archiver. + * + * This function sets the destination of the archiver. + * + * @param dest The destination to set. + */ virtual void setDest(std::string dest) = 0; - virtual void updateDest()=0; + + /** + * @brief Get the destination of the archiver. + * + * This function gets the destination of the archiver. + * + * @return The destination of the archiver. + */ virtual std::string getDest() = 0; + + /** + * @brief Destructor for the BaseArchiver class. + */ virtual ~BaseArchiver() = default; }; diff --git a/include/Base_Configurator.h b/include/Base_Configurator.h index 97b46e9c8a8711e64a12aa13804df04ad7d343eb..46f28b70f006414974b914029d932a5c20dec8d1 100644 --- a/include/Base_Configurator.h +++ b/include/Base_Configurator.h @@ -5,21 +5,74 @@ namespace inaf::oasbo::Configurators { -class BaseConfigurator{ +/** + * @brief The BaseConfigurator class is an abstract base class for configurators in the DAQ system. + * + * It provides common functionality for reading and pushing configurations to a source, + * as well as inserting new configurations into the existing ones. + */ +class BaseConfigurator { protected: - std::map config; + std::map config; public: + /** + * @brief Read the configuration from the source. + * + * @return int Returns 0 on success, or an error code on failure. + */ virtual int readConfigFromSource() = 0; + + /** + * @brief Read the configuration for the specified target. + * + * @param target The target for which to read the configuration. + * @return int Returns 0 on success, or an error code on failure. + */ virtual int readConfigFromSource(std::string target) = 0; + + /** + * @brief Push the configuration to the source. + * + * @return int Returns 0 on success, or an error code on failure. + */ virtual int pushConfigToSource() = 0; + + /** + * @brief Push the configuration for the specified target. + * + * @param target The target for which to push the configuration. + * @return int Returns 0 on success, or an error code on failure. + */ virtual int pushConfigToSource(std::string target) = 0; - virtual int insert(std::map, std::string target) = 0; - virtual std::map getConfig() {return this->config;} - std::string toString(){ + /** + * @brief Insert new configurations into the existing ones. + * + * @param newConfig The new configurations to insert. + * @param target The target for which to insert the new configurations. + * @return int Returns 0 on success, or an error code on failure. + */ + virtual int insert(std::map newConfig, + std::string target) = 0; + + /** + * @brief Get the current configuration. + * + * @return std::map The current configuration. + */ + virtual std::map getConfig() { + return this->config; + } + + /** + * @brief Convert the configuration to a string representation. + * + * @return std::string The string representation of the configuration. + */ + std::string toString() { std::string ret = ""; - for( const std::pair n : config) { + for (const std::pair n : config) { ret += n.first + " : " + n.second + "\n"; } return ret; diff --git a/include/Base_DAQ.h b/include/Base_DAQ.h index 7852d6ad290280b5d142568ddfaac28c26041a61..6c4456044285230c28924077f3f1bcdac34900ac 100755 --- a/include/Base_DAQ.h +++ b/include/Base_DAQ.h @@ -12,6 +12,16 @@ namespace inaf::oasbo::DAQ_observers { class BaseDAQ_Observer; } +/** + * @brief The BaseDAQ class represents the base class for a Data Acquisition (DAQ) system. + * + * This class provides a common interface and functionality for a DAQ system. The DAQ system is imagined as a state machine. + * This super class defines the states, sets the receiver, archiver, provider, monitor, and packet objects, and + * manages the observers and configurations. It also provides pure virtual functions for + * starting, stopping, switching states, delivering packets, and getting the state as a string. + * + * @note This class is meant to be inherited from and should not be instantiated directly. + */ namespace inaf::oasbo::DAQ { class BaseDAQ { public: @@ -20,47 +30,105 @@ public: }; protected: - Status currentState; - Status nextState; - bool changeStateFlag = false; - Receivers::BaseReceiver *receiver = nullptr; - Archivers::BaseArchiver *archiver = nullptr; - Providers::BaseProvider *provider = nullptr; - PacketMonitors::BasePacketMonitor *monitor = nullptr; - PacketLib::BasePacket *packet = nullptr; - std::vector observers; - std::vector configurations; + Status currentState; /**< The current state of the DAQ system. */ + Status nextState; /**< The next state of the DAQ system. */ + bool changeStateFlag = false; /**< Flag indicating if the state has changed. */ + Receivers::BaseReceiver *receiver = nullptr; /**< Pointer to the receiver object. */ + Archivers::BaseArchiver *archiver = nullptr; /**< Pointer to the archiver object. */ + Providers::BaseProvider *provider = nullptr; /**< Pointer to the provider object. */ + PacketMonitors::BasePacketMonitor *monitor = nullptr; /**< Pointer to the packet monitor object. */ + Packets::BasePacket *packet = nullptr; /**< Pointer to the packet object. */ + std::vector observers; /**< Vector of observers. */ + std::vector configurations; /**< Vector of configurations. */ public: + /** + * @brief Sets the receiver object. + * + * @param receiver The receiver object to set. + */ void setReceiver(Receivers::BaseReceiver &receiver) { this->receiver = &receiver; } + + /** + * @brief Sets the archiver object. + * + * @param archiver The archiver object to set. + */ void setArchiver(Archivers::BaseArchiver &archiver) { this->archiver = &archiver; } + + /** + * @brief Sets the provider object. + * + * @param provider The provider object to set. + */ void setProvider(Providers::BaseProvider &provider) { this->provider = &provider; } + + /** + * @brief Sets the packet monitor object. + * + * @param monitor The packet monitor object to set. + */ void setMonitor(PacketMonitors::BasePacketMonitor &monitor) { this->monitor = &monitor; } - void setPacket(PacketLib::BasePacket &packet) { + + /** + * @brief Sets the packet object. + * + * @param packet The packet object to set. + */ + void setPacket(Packets::BasePacket &packet) { this->packet = &packet; } + + /** + * @brief Sets the current state of the DAQ system. + * + * @param currentState The current state to set. + */ void setCurrentState(Status currentState) { this->currentState = currentState; } + + /** + * @brief Sets the next state of the DAQ system. + * + * @param nextState The next state to set. + */ void setNextState(Status nextState) { this->nextState = nextState; } + + /** + * @brief Sets the flag indicating if the state has changed. + * + * @param flag The flag value to set. + */ void setChangeStateFlag(bool flag) { this->changeStateFlag = flag; } + + /** + * @brief Registers an observer to the DAQ system. + * + * @param observer The observer to register. + */ void registerObserver( inaf::oasbo::DAQ_observers::BaseDAQ_Observer *observer) { observers.push_back(observer); } + /** + * @brief Removes an observer from the DAQ system. + * + * @param observer The observer to remove. + */ void removeObserver( inaf::oasbo::DAQ_observers::BaseDAQ_Observer *observer) { observers.erase( @@ -68,37 +136,125 @@ public: observers.end()); } + /** + * @brief Gets a pointer to the receiver object. + * + * @return Pointer to the receiver object. + */ Receivers::BaseReceiver* getReceiverPtr() { return this->receiver; } + + /** + * @brief Gets a pointer to the archiver object. + * + * @return Pointer to the archiver object. + */ Archivers::BaseArchiver* getArchiverPtr() { return this->archiver; } + + /** + * @brief Gets a pointer to the provider object. + * + * @return Pointer to the provider object. + */ Providers::BaseProvider* getProviderPtr() { return this->provider; } + + /** + * @brief Gets a pointer to the packet monitor object. + * + * @return Pointer to the packet monitor object. + */ PacketMonitors::BasePacketMonitor* getMonitorPtr() { return this->monitor; } - PacketLib::BasePacket* getPacketPrt() { + + /** + * @brief Gets a pointer to the packet object. + * + * @return Pointer to the packet object. + */ + Packets::BasePacket* getPacketPrt() { return this->packet; } + + /** + * @brief Gets the current state of the DAQ system. + * + * @return The current state of the DAQ system. + */ Status getCurrentState() { return this->currentState; } + + /** + * @brief Gets the next state of the DAQ system. + * + * @return The next state of the DAQ system. + */ Status getNextState() { return this->nextState; } + + /** + * @brief Gets the flag indicating if the state has changed. + * + * @return The flag indicating if the state has changed. + */ int getChangeStateFlag() { return this->changeStateFlag; } + /** + * @brief Starts the DAQ system. + * + * @note This is a pure virtual function and must be implemented by derived classes. + */ virtual void start() = 0; + + /** + * @brief Stops the DAQ system. + * + * @note This is a pure virtual function and must be implemented by derived classes. + */ virtual void stop() = 0; - virtual void switchState(const Status) = 0; + + /** + * @brief Switches the state of the DAQ system. + * + * @param state The state to switch to. + * + * @note This is a pure virtual function and must be implemented by derived classes. + */ + virtual void switchState(const Status state) = 0; + + /** + * @brief Delivers a packet after received. It should probably call the provider to deliver the packet. + * + * @return The result of the packet delivery. + * + * @note This is a pure virtual function and must be implemented by derived classes. + */ virtual int deliverPacket() = 0; - virtual std::string getStateStr(const Status) = 0; + /** + * @brief Gets the string representation of a state. + * + * @param state The state to get the string representation of. + * @return The string representation of the state. + * + * @note This is a pure virtual function and must be implemented by derived classes. + */ + virtual std::string getStateStr(const Status state) = 0; + + /** + * @brief Destructor for the BaseDAQ class. + * + * Deletes the receiver, provider, archiver, monitor, packet, and observers. + */ virtual ~BaseDAQ() { delete receiver; delete provider; diff --git a/include/Base_DAQ_Observer.h b/include/Base_DAQ_Observer.h index 84a511866cbe600082abd329c706ab70089fb697..dbcffb6296d32fc8ccbc55a00a699ac049c7b8ca 100644 --- a/include/Base_DAQ_Observer.h +++ b/include/Base_DAQ_Observer.h @@ -1,31 +1,71 @@ - - #pragma once #include -namespace inaf::oasbo::DAQ_observers{ +/** + * @brief The BaseDAQ_Observer class is an abstract base class for DAQ system observers. + * + * This class defines the interface for observing the statistics and status of a BaseDAQ object. + * Subclasses of BaseDAQ_Observer must implement the pure virtual functions defined in this class. + * + */ +namespace inaf::oasbo::DAQ_observers { -class BaseDAQ_Observer{ +class BaseDAQ_Observer { protected: inaf::oasbo::DAQ::BaseDAQ *dataAcquisition; public: - BaseDAQ_Observer(inaf::oasbo::DAQ::BaseDAQ &dataAcquisition) { - this->dataAcquisition = &dataAcquisition; - } - - virtual ~BaseDAQ_Observer() { - this->dataAcquisition->removeObserver(this); - } - - virtual void updatePacketStats() = 0; - virtual void updateArchiverStats() = 0; - virtual void updateProviderStats() = 0; - virtual void updateReceiverStats() = 0; - virtual void updateAll() = 0; - virtual void start() = 0; - virtual void stop() = 0; + /** + * @brief Constructs a BaseDAQ_Observer object with the specified BaseDAQ object. + * + * @param dataAcquisition The BaseDAQ object to observe. + */ + BaseDAQ_Observer(inaf::oasbo::DAQ::BaseDAQ &dataAcquisition) { + this->dataAcquisition = &dataAcquisition; + } + + /** + * @brief Destroys the BaseDAQ_Observer object and removes itself from the observed BaseDAQ object. + */ + virtual ~BaseDAQ_Observer() { + this->dataAcquisition->removeObserver(this); + } + + /** + * @brief Updates the packet statistics of the observed BaseDAQ object. + */ + virtual void updatePacketStats() = 0; + + /** + * @brief Updates the archiver statistics of the observed BaseDAQ object. + */ + virtual void updateArchiverStats() = 0; + + /** + * @brief Updates the provider statistics of the observed BaseDAQ object. + */ + virtual void updateProviderStats() = 0; + + /** + * @brief Updates the receiver statistics of the observed BaseDAQ object. + */ + virtual void updateReceiverStats() = 0; + + /** + * @brief Updates all statistics of the observed BaseDAQ object. + */ + virtual void updateAll() = 0; + + /** + * @brief Starts the observation on the BaseDAQ object. + */ + virtual void start() = 0; + + /** + * @brief Stops the observation on the BaseDAQ object. + */ + virtual void stop() = 0; }; } diff --git a/include/Base_Monitor.h b/include/Base_Monitor.h index cd91583633b8410af9fdc75f695ff15f1d838a56..6fb91a41d85c0a3b2e6a82028ca3584f3f6f507f 100644 --- a/include/Base_Monitor.h +++ b/include/Base_Monitor.h @@ -1,30 +1,79 @@ - #pragma once #include #include #include -namespace inaf::oasbo::PacketMonitors{ +namespace inaf::oasbo::PacketMonitors { -class BasePacketMonitor{ +/** + * @brief The BasePacketMonitor class is an abstract base class for packet monitors in the DAQ system. + * + * This class provides a common interface for packet monitoring functionality. + * Derived classes must implement the monit(), printStats(), and reset() methods. + * The class also provides methods to access and retrieve statistics related to the monitored packets. + */ +class BasePacketMonitor { protected: - std::map stats; + std::map stats; /**< A map to store statistics related to the monitored packets. */ public: - virtual void monit(PacketLib::BasePacket &) = 0; - virtual void printStats()=0; + /** + * @brief Monitors a packet. + * + * This pure virtual method is used to monitor a packet. + * Derived classes must implement this method to define the monitoring behavior. + * + * @param packet The packet to be monitored. + */ + virtual void monit(Packets::BasePacket &packet) = 0; + + /** + * @brief Prints the statistics related to the monitored packets. + * + * This pure virtual method is used to print the statistics related to the monitored packets. + * Derived classes must implement this method to define the printing behavior. + */ + virtual void printStats() = 0; + + /** + * @brief Resets the statistics related to the monitored packets. + * + * This pure virtual method is used to reset the statistics related to the monitored packets. + * Derived classes must implement this method to define the resetting behavior. + */ virtual void reset() = 0; - virtual std::map getStatsMap() const { return stats;} - std::optional getStat(std::string stat) const { + + /** + * @brief Retrieves the statistics map. + * + * This method returns the map containing the statistics related to the monitored packets. + * + * @return The map containing the statistics related to the monitored packets. + */ + virtual std::map getStatsMap() const { + return stats; + } + + /** + * @brief Retrieves a specific statistic. + * + * This method retrieves a specific statistic from the statistics map. + * If the statistic is not found, it returns std::nullopt. + * + * @param stat The name of the statistic to retrieve. + * @return An optional string containing the value of the statistic, or std::nullopt if the statistic is not found. + */ + std::optional getStat(std::string stat) const { try { return this->stats.at(stat); - } catch (const std::out_of_range &) { + } catch (const std::out_of_range&) { return std::nullopt; } - } + } + /** + * @brief Default destructor. + */ virtual ~BasePacketMonitor() = default; - - }; } diff --git a/include/Base_Packet.h b/include/Base_Packet.h index 463594f3ce6b24acb77a2f52b2d8511ba60a1f8b..9e5c82381b4bd21f8f973ff35ee0d2a6ede622d0 100644 --- a/include/Base_Packet.h +++ b/include/Base_Packet.h @@ -1,4 +1,3 @@ - #pragma once #include @@ -14,37 +13,69 @@ #include #include - -namespace inaf::oasbo::PacketLib { - +namespace inaf::oasbo::Packets { + +/** + * @class BasePacketStructure + * @brief Represents the structure of a base packet. + * + * The BasePacketStructure class provides functionality to define and manipulate the structure of a base packet. + * It stores information about the fields, their sizes, offsets, and mappings between field names and indices. + * The class also provides methods to retrieve information about the structure, such as the byte size, field offsets, and field names. + * + * @note This is an abstract base class and should be derived to define specific packet structures. In particular, you should define + * the sourceReadingFunc function. + */ class BasePacketStructure { protected: - using Structure = std::vector>; - - std::string source; - Structure structure; - uint byteSize; - std::vector fieldSizes; - std::unordered_map indexToOffsetsMap; - std::unordered_map fieldNameToIndexMap; - std::unordered_map indexToFieldNameMap; - std::function sourceReadingFunc; - - void updateFieldSizes(const Structure ¶msTuple) { - std::for_each(paramsTuple.begin(), paramsTuple.end(), + /** + * @brief Type alias for the packet structure. + * + * This alias represents the structure of a packet. It is defined as a vector of tuples, where each tuple contains three elements: + * - The first element is of type uint and represents the field index. + * - The second element is of type std::string and represents the field name. + * - The third element is of type uint and represents the field bit size. + */ + using Structure = std::vector>; /**< Type alias for the packet structure. */ + + std::string source; /**< The source of the packet. */ + Structure structure; /**< The structure of the packet. */ + uint byteSize; /**< The size of the packet in bytes. */ + std::vector fieldSizes; /**< vector of the sizes of the fields in the packet. */ + std::unordered_map indexToOffsetsMap; /**< Mapping of field index to field offset. */ + std::unordered_map fieldNameToIndexMap; /**< Mapping of field name to field index. */ + std::unordered_map indexToFieldNameMap; /**< Mapping of field index to field name. */ + std::function sourceReadingFunc; /**< Function to read the packet source and return the structure. */ + + /** + * @brief Updates the field sizes based on the structure. + * @param structure The structure of the packet. + */ + void updateFieldSizes(const Structure &structure) { + std::for_each(structure.begin(), structure.end(), [&](const std::tuple &tup) { this->fieldSizes.push_back(std::get<2>(tup)); }); } - void updateFieldOffsets(const Structure ¶msTuple) { + + /** + * @brief Updates the field offsets based on the structure. + * @param structure The structure of the packet. + */ + void updateFieldOffsets(const Structure &structure) { uint offset = 0; - for (size_t i = 0; i < paramsTuple.size(); i++) { + for (size_t i = 0; i < structure.size(); i++) { indexToOffsetsMap[i] = offset; - offset += std::get<2>(paramsTuple[i]); + offset += std::get<2>(structure[i]); } } - void updateFieldNameAndIndexMap(const Structure ¶msTuple) { - std::for_each(paramsTuple.begin(), paramsTuple.end(), + + /** + * @brief Updates the field name and index maps based on the structure. + * @param structure The structure of the packet. + */ + void updateFieldNameAndIndexMap(const Structure &structure) { + std::for_each(structure.begin(), structure.end(), [&](const std::tuple &tup) { this->fieldNameToIndexMap[std::get<1>(tup)] = std::get<0>( tup); @@ -52,6 +83,11 @@ protected: tup); }); } + + /** + * @brief Updates the packet structure based on the source. + * @param source The source of the packet structure. + */ void updateStructure(std::string source) { this->source = source; this->structure = sourceReadingFunc(source); @@ -63,14 +99,26 @@ protected: } public: + /** + * @brief Destructor. + */ virtual ~BasePacketStructure() = default; + /** + * @brief Constructor. + * @param source The source of the packet structure. + * @param sourceReadingFunc The function to read the packet source and return the structure. + */ BasePacketStructure(std::string source, std::function sourceReadingFunc) : source(source), sourceReadingFunc(sourceReadingFunc) { this->updateStructure(source); } - ; + + /** + * @brief Copy constructor. + * @param other The other BasePacketStructure object to copy from. + */ BasePacketStructure(const BasePacketStructure &other) { this->source = other.source; this->byteSize = other.byteSize; @@ -81,33 +129,61 @@ public: this->sourceReadingFunc = other.sourceReadingFunc; } + /** + * @brief Changes the source of the packet and updates the structure. + * @param source The new source of the packet structure. + */ void changeSource(std::string source) { updateStructure(source); } + + /** + * @brief Gets the size of the packet in bytes. + * @return The size of the packet in bytes. + */ uint getByteSize() { return this->byteSize; } + + /** + * @brief Gets the source of the packet structure. + * @return The source of the packet structure. + */ std::string getSource() { return this->source; } + + /** + * @brief Gets the bit offset of a field in the packet structure. + * @param index The index of the field. + * @return The bit offset of the field, or std::nullopt if the field does not exist. + */ std::optional bitOffsetOf(uint index) { if (index <= this->numberOfFields()) { return indexToOffsetsMap.at(index); } else { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "No field at " << index << ", max is " << numberOfFields() << ", returning nullopt." << std::endl; return std::nullopt; } } + + /** + * @brief Gets the bit size of a field in the packet structure. + * @param index The index of the field. + * @return The bit size of the field, or std::nullopt if the field does not exist. + */ std::optional bitSizeOf(uint index) { if (index <= this->numberOfFields()) { return this->fieldSizes[index]; } else { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "No field at " << index << ", max is " << numberOfFields() << ", returning nullopt." << std::endl; @@ -115,6 +191,11 @@ public: } } + /** + * @brief Gets the index of a field in the packet structure based on its name. + * @param fieldName The name of the field. + * @return The index of the field, or std::nullopt if the field does not exist. + */ std::optional indexOfField(std::string fieldName) { std::transform(fieldName.begin(), fieldName.end(), fieldName.begin(), [](unsigned char c) { @@ -123,51 +204,103 @@ public: try { return this->fieldNameToIndexMap.at(fieldName); } catch (const std::out_of_range &oor) { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "No field of name " << fieldName << ", returning nullopt." << std::endl; return std::nullopt; } } + /** + * @brief Gets the name of a field in the packet based on its index. + * @param index The index of the field. + * @return The name of the field, or std::nullopt if the field does not exist. + */ std::optional fieldNameOfIndex(uint index) { try { return this->indexToFieldNameMap.at(index); } catch (const std::out_of_range &oor) { - time_t now = time(nullptr); - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "No field at " << index << ", max is " << numberOfFields() << ", returning nullopt." << std::endl; return std::nullopt; } } + + /** + * @brief Gets the number of fields in the packet. + * @return The number of fields in the packet. + */ uint numberOfFields() { return this->fieldSizes.size(); } + /** + * @brief Gets the field name to index map. + * @return The field name to index map. + */ std::unordered_map getFieldNameToIndexMap() const { return this->fieldNameToIndexMap; } - std::unordered_map getIndexToOffsetsMap() const{ + /** + * @brief Gets the index to offset map. + * @return The index to offset map. + */ + std::unordered_map getIndexToOffsetsMap() const { return this->indexToOffsetsMap; } + + /** + * @brief Gets the index to field name map. + * @return The index to field name map. + */ std::unordered_map getIndexToFieldNameMap() const { return this->indexToFieldNameMap; } - }; +/** + * @brief Represents an iterator that iterates over individual fields in the packet. + * + * The `bit_iterator` class provides a random access iterator interface for iterating over individual fields in the packet. + * It is templated on the value type of the packet fields. I.e. if the largest packet fields is 32-bit, then the value type should be at least uint32_t. + * + * @tparam ValueType The value type of the values returned by the iterator. The value + */ template class bit_iterator { using iterator_category = std::random_access_iterator_tag; using value_type = ValueType; using difference_type = std::ptrdiff_t; - using pointer = ValueType*; - using reference = ValueType&; + using pointer = ValueType *; + using reference = ValueType &; + +private: + + /** + * @brief Pointer to the packet data. + */ + const uint8_t *m_data; + /** + * @brief Current offset within the packet. + */ + int m_offset; + /** + * @brief Pointer to the BasePacketStructure. + */ + BasePacketStructure *m_structure; + + /** + * @brief Function to retrieve the value from data based on offset and size. + */ + std::function m_func; public: bit_iterator(const uint8_t *data, int offset, @@ -228,23 +361,31 @@ public: auto num_bits = m_structure->bitSizeOf(m_offset); return m_func(m_data, offset.value(), num_bits.value()); } - -private: - const uint8_t *m_data; - int m_offset; - BasePacketStructure *m_structure; - std::function m_func; }; +/** + * @brief Represents a template class for handling packets with a specific structure. + * + * The `BasePacketTempl` class provides a generic template for handling packets with a specified structure. + * It includes methods for reading and writing values from/to memory, as well as other utility functions. + * + * @tparam ValueType The value type of the largest packet fields. i.e The value type should be at least uint32_t if the largest packet field is 32-bit. + */ template class BasePacketTempl { protected: - BasePacketStructure *packetStructure; - uint8_t *memoryPointer; - - // This C++ function reads a binary value from a memory location pointed to by binaryPointer. - // The binary value is represented by num_bits number of bits starting from the offset-th bit in the memory. - // The function returns the value of the binary as a ValueType. + BasePacketStructure *packetStructure; /**< Pointer to the structure defining the packet. */ + uint8_t *memoryPointer; /**< Pointer to the memory containing packet data. */ + + /** + * @brief reads a binary value from a memory location pointed to by binaryPointer. + * The binary value is represented by num_bits bits starting from the offset-th bit in the memory. + * + * @param binaryPointer Pointer to the memory containing the binary value. + * @param offset The offset of the first bit of the binary value. + * @param num_bits The number of bits to read. + * @return ValueType The value read from memory. + */ static ValueType _readValueFromMemoryAt_(const uint8_t *binaryPointer, uint offset, uint num_bits) { // Calculate the bit offset from the byte offset: @@ -262,11 +403,17 @@ protected: // Create a bit mask to isolate the desired bit: uint8_t bit_mask = 1 << (7 - bit_index); // Set the corresponding bit in the return value if the retrieved bit is 1: - value |= (byte & bit_mask) ? ( bit << (num_bits - i - 1)) : 0; + value |= (byte & bit_mask) ? (bit << (num_bits - i - 1)) : 0; } return value; } + /** + * @brief Calculates the minimum number of bits required to represent a given value. + * + * @param value The value to calculate the minimum bits for. + * @return size_t The minimum number of bits required. + */ size_t minBitsRequired(size_t value) const { // Handle special cases size_t bitsNeeded = 1; @@ -280,20 +427,38 @@ protected: } public: + /** + * @brief Constructor for the BasePacketTempl class. + * + * @param structure The structure defining the packet. + */ BasePacketTempl(BasePacketStructure &structure) { this->packetStructure = new BasePacketStructure(structure); this->memoryPointer = new uint8_t[structure.getByteSize()]; } + /** + * @brief Copy constructor for the BasePacketTempl class. + * + * @param other The other BasePacketTempl object to copy. + */ BasePacketTempl(const BasePacketTempl &other) { - this->packetStructure = new BasePacketStructure(other.getPacketStructure()); + this->packetStructure = new BasePacketStructure( + other.getPacketStructure()); this->memoryPointer = new uint8_t[other.packetStructure->getByteSize()]; std::memcpy(this->memoryPointer, other.memoryPointer, other.packetStructure->getByteSize()); } + /** + * @brief Destructor for the BasePacketTempl class. + */ virtual ~BasePacketTempl() = default; + /** + * @brief Updates the packet structure. + * @param structure The new packet structure. + */ void updatePacketStructure(BasePacketStructure &structure) { size_t newSize = structure.getByteSize(); size_t oldSize = this->packetStructure->getByteSize(); @@ -309,15 +474,21 @@ public: this->packetStructure = &structure; } + /** + * @brief Reads a value from the memory at a given index. + * @param index The index of the field to read. + * @return std::optional The value read from memory, or std::nullopt if the field does not exist. + */ std::optional readValueFromMemoryAt(uint index) const { auto offset = packetStructure->bitOffsetOf(index); // offset from the beginning of the byte - auto num_bits = packetStructure->bitSizeOf(index); //remaining bits to read + auto num_bits = packetStructure->bitSizeOf(index); // remaining bits to read if (offset.has_value() && num_bits.has_value()) return _readValueFromMemoryAt_(memoryPointer, offset.value(), num_bits.value()); else { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "Error: No field at " << index << ", max is " << packetStructure->numberOfFields() << ", returning nullopt" << std::endl; @@ -325,19 +496,35 @@ public: } } + /** + * @brief Returns a pointer to the memory in which stores the packet. + * + * This function returns a constant pointer to the memory. + * + * @return A constant pointer to the memory. + */ uint8_t const* getPointerToMemory() const { return memoryPointer; } + /** + * @brief Copies data from a source memory location to the packet's memory. + * + * @param from Pointer to the source memory location. + * @param size Number of bytes to copy. + * @return int The number of bytes copied. + */ int copyToMemory(const uint8_t *from, uint size) { uint max_writable = this->packetStructure->getByteSize(); if (size > max_writable) { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "Error: you are trying to copy " << size << " byte where the max size is: " << max_writable << std::endl; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "\tI copy only until " << max_writable << " byte" << std::endl; std::memcpy(memoryPointer, from, max_writable); @@ -348,11 +535,20 @@ public: } } + /** + * Copies data from the given memory location to the packet's memory buffer. + * + * @param from Pointer to the source memory location. + * @param size Number of bytes to copy. + * @param offset Offset in the packet's memory buffer to start copying to. + * @return The number of bytes copied. + */ int copyToMemory(const uint8_t *from, uint size, uint offset) { uint max_writable = this->packetStructure->getByteSize(); if (offset > max_writable) { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "Error: you are trying to copy starting from " << offset << " byte where the max size is: " << max_writable @@ -360,12 +556,14 @@ public: return -1; } if (size + offset > max_writable) { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "Error: you are trying to copy " << size + offset << " byte where the max size is: " << max_writable << std::endl; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "\tI copy only until " << max_writable << " byte" << std::endl; int to_write = max_writable - offset; @@ -377,10 +575,22 @@ public: } } + /** + * @brief Accesses the value at the specified index in the packet. + * + * @param index The index of the value to access. + * @return An optional containing the value at the specified index, if it exists. + */ std::optional operator[](uint index) const { return readValueFromMemoryAt(index); } + /** + * @brief Accesses the value of a field in the packet by its field name. + * + * @param fieldName The name of the field to access. + * @return An optional value of the specified field type. If the field does not exist, the optional will be empty. + */ std::optional operator[](std::string fieldName) const { std::transform(fieldName.begin(), fieldName.end(), fieldName.begin(), [](unsigned char c) { @@ -393,26 +603,45 @@ public: return std::nullopt; } + /** + * @brief Returns a constant bit iterator pointing to the beginning of the packet data. + * + * @return A constant bit iterator pointing to the beginning of the packet data. + */ bit_iterator begin() const { return bit_iterator(memoryPointer, 0, packetStructure, &_readValueFromMemoryAt_); } + /** + * @brief Returns a bit_iterator pointing to the end of the container. + * + * @return A bit_iterator pointing to the end of the container. + */ bit_iterator end() const { return bit_iterator(memoryPointer, packetStructure->numberOfFields(), packetStructure, &_readValueFromMemoryAt_); } - std::optional writeValueIntoMemoryAtIndex(uint index, ValueType value) { + /** + * Writes a value into memory at the specified index. + * + * @param index The index at which to write the value. + * @param value The value to be written. + * @return An optional containing number of fits written, if any. + */ + std::optional writeValueIntoMemoryAtIndex(uint index, + ValueType value) { auto offset = this->packetStructure->bitOffsetOf(index); auto numbits = this->packetStructure->bitSizeOf(index); size_t min_req = minBitsRequired(value); if (!offset.has_value() || !numbits.has_value()) return std::nullopt; if (numbits < min_req) { - time_t now = time(nullptr) ; - std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") + time_t now = time(nullptr); + std::cerr << "[" + << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") << "]\t[Base Packet]\t" << "Error: you are trying to write " << value << " which requires at least " << min_req << " bits in a field of size " << numbits << std::endl; @@ -442,31 +671,70 @@ public: return numbits_written; } + /** + * @brief Get the byte size of the packet structure. + * + * @return The byte size of the packet structure. + */ uint getPacketStructureByteSize() const { return packetStructure->getByteSize(); } + /** + * @brief Returns the packet structure of the BasePacket. + * + * @return A reference to the packet structure. + */ BasePacketStructure& getPacketStructure() const { return *(this->packetStructure); } + /** + * @brief Checks if the packet has a recognized header. + * @note This is a pure virtual function and must be implemented by derived classes. + * @return true if the packet has a recognized header, false otherwise. + */ virtual bool hasRecognizedHeader() const = 0; + /** + * @brief Checks if the passed data has a recognized header. + * @param buff The data to check. + * @note This is a pure virtual function and must be implemented by derived classes. + * @return true if buff has a recognized header, false otherwise. + */ virtual bool isRecognizedHeader(std::vector buff) const = 0; + + /** + * @brief Get the size of the header of the packet. + * @note This is a pure virtual function and must be implemented by derived classes. + * @return The size of the header as an unsigned integer. + */ virtual uint getHeaderSize() const = 0; + /** + * @brief Get the size of the payload of the packet. + * @note This is a pure virtual function and must be implemented by derived classes. + * @return The size of the payload as an unsigned integer. + */ virtual uint getPayloadSize() const = 0; + /** + * @brief Get the size of the tail of the packet. + * @note This is a pure virtual function and must be implemented by derived classes. + * @return The size of the tail as an unsigned integer. + */ virtual uint getTailSize() const = 0; }; using valueType = size_t; +/** + * @brief Represents a concrete class derived from BasePacketTempl with a specified value type. + * + * The `BasePacket` class is a concrete class derived from `BasePacketTempl` with a value type of `size_t`. + */ class BasePacket: public BasePacketTempl { protected: - public: BasePacket(BasePacketStructure &structure) : BasePacketTempl(structure) { } virtual ~BasePacket() = default; - }; } - diff --git a/include/Base_Provider.h b/include/Base_Provider.h index 695dd0c63a82498cb7b17bbf5619a4b2c09622d3..527869679b8c545ba0db7ac7c9f1c0c5a17f6327 100644 --- a/include/Base_Provider.h +++ b/include/Base_Provider.h @@ -1,27 +1,74 @@ -/* - * - * Created on: Mar 1, 2021 - * Author: astrisw - * - */ - #pragma once #include #include namespace inaf::oasbo::Providers { -class BaseProvider{ +/** + * @brief The BaseProvider class is an abstract base class for providers in the DAQ system. + * + * This class defines the common interface for providers that write packets to a destination. + * Derived classes must implement the pure virtual functions defined in this class. + */ +class BaseProvider { protected: - std::string dest; + std::string dest; /**< The destination where packets are written to. */ + public: - virtual int write(PacketLib::BasePacket &) = 0; - virtual int write(PacketLib::BasePacket &, std::string dest) = 0; + /** + * @brief Writes a packet to the destination. + * + * @param packet The packet to be written. + * @return int Returns an integer indicating the success or failure of the write operation. + */ + virtual int write(Packets::BasePacket &packet) = 0; + + /** + * @brief Writes a packet to a specified destination. + * + * @param packet The packet to be written. + * @param dest The destination where the packet should be written to. + * @return int Returns an integer indicating the success or failure of the write operation. + */ + virtual int write(Packets::BasePacket &packet, std::string dest) = 0; - virtual int open()=0; - virtual int close()=0; + /** + * @brief Opens the provider. + * + * @return int Returns an integer indicating the success or failure of the open operation. + */ + virtual int open() = 0; + + /** + * @brief Closes the provider. + * + * @return int Returns an integer indicating the success or failure of the close operation. + */ + virtual int close() = 0; + + /** + * @brief Checks if the provider is open. + * + * @return bool Returns true if the provider is open, false otherwise. + */ virtual bool isOpen() = 0; + + /** + * @brief Sets the destination where packets should be written to. + * + * @param dest The destination to be set. + */ virtual void setDest(std::string dest) = 0; + + /** + * @brief Gets the current destination where packets are written to. + * + * @return std::string Returns the current destination. + */ virtual std::string getDest() = 0; + + /** + * @brief Default destructor. + */ virtual ~BaseProvider() = default; }; } diff --git a/include/Base_Receiver.h b/include/Base_Receiver.h index d16335be606355a0327dde20f567bfaeb656d82b..0f161ba84c5a2d6f50b42a37efea1fc0b9c44075 100755 --- a/include/Base_Receiver.h +++ b/include/Base_Receiver.h @@ -1,29 +1,70 @@ -/* - * - * Created on: Mar 1, 2021 - * Author: astrisw - * - */ - #pragma once #include #include -namespace inaf::oasbo::Receivers{ +namespace inaf::oasbo::Receivers { -class BaseReceiver{ +/** + * @brief The BaseReceiver class is an abstract base class for receivers in the DAQ system. + * + * This class provides a common interface for receiving data from clients. It defines pure virtual + * functions for getting and setting the host, connecting to and closing the connection with the client, + * checking if the receiver is connected to the client, and receiving data from the client. + * + * Derived classes must implement these functions according to their specific requirements. + */ +class BaseReceiver { protected: std::string host; public: + /** + * @brief Get the host address. + * + * @return The host address as a string. + */ virtual std::string getHost() = 0; + + /** + * @brief Set the host address. + * + * @param host The host address to set. + */ virtual void setHost(std::string host) = 0; + /** + * @brief Connect to the client. + * + * @return An integer indicating the success or failure of the operation. + */ virtual int connectToClient()=0; + + /** + * @brief Close the connection with the client. + * + * @return An integer indicating the success or failure of the operation. + */ virtual int closeConnectionToClient()=0; + + /** + * @brief Check if the receiver is connected to the client. + * + * @return true if the receiver is connected to the client, false otherwise. + */ virtual bool isConnectedToClient() const =0; - virtual int receiveFromClient(PacketLib::BasePacket &) = 0; + + /** + * @brief Receive data from the client. + * + * @param packet The received packet will be stored in this parameter. + * @return An integer indicating the success or failure of the operation. + */ + virtual int receiveFromClient(Packets::BasePacket&) = 0; + + /** + * @brief Virtual destructor. + */ virtual ~BaseReceiver() = default; }; }