diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index f237a0f26..83f7a3da1 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,6 +1,7 @@ #include +#include -TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, +TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, double timeoutSeconds): SystemObject(objectId), tmtcBridgeId(tmtcUnixUdpBridge) { @@ -23,23 +24,13 @@ TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, else { receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); } - - // Set receive timeout. - int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, - &receptionTimeout, sizeof(receptionTimeout)); - if(result == -1) { - sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting receive" - "timeout failed with " << strerror(errno) << std::endl; - return; - } } -TcSocketPollingTask::~TcSocketPollingTask() { +TcUnixUdpPollingTask::~TcUnixUdpPollingTask() { } -ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) { - // Poll for new data permanently. The call will block until the specified - // length of bytes has been received or a timeout occured. +ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { + // Poll for new UDP datagrams in permanent loop. while(1) { //! Sender Address is cached here. struct sockaddr_in senderAddress; @@ -48,21 +39,34 @@ ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) { receptionBuffer.data(), frameSize, receptionFlags, reinterpret_cast(&senderAddress), &senderSockLen); if(bytesReceived < 0) { - //handle error + // handle error sif::error << "TcSocketPollingTask::performOperation: recvfrom " "failed with " << strerror(errno) << std::endl; + if(errno == EAGAIN or errno == EWOULDBLOCK) { + sif::info << "timeout" << std::endl; + } continue; } sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived << " bytes received" << std::endl; - ReturnValue_t result = handleSuccessfullTcRead(); + ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); + if(result != HasReturnvaluesIF::RETURN_FAILED) { + + } tmtcBridge->checkAndSetClientAddress(senderAddress); } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t TcSocketPollingTask::initialize() { +ReturnValue_t TcUnixUdpPollingTask::initialize() { + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == nullptr) { + sif::error << "TcSerialPollingTask::initialize: TC Store uninitialized!" + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + tmtcBridge = objectManager->get(tmtcBridgeId); if(tmtcBridge == nullptr) { sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" @@ -70,10 +74,41 @@ ReturnValue_t TcSocketPollingTask::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } + targetTcDestination = tmtcBridge->getReportReceptionQueue(); + serverUdpSocket = tmtcBridge->serverSocket; + + // Set receive timeout. +// int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, +// &receptionTimeout, sizeof(receptionTimeout)); +// if(result == -1) { +// sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " +// "receive timeout failed with " << strerror(errno) << std::endl; +// return ObjectManagerIF::CHILD_INIT_FAILED; +// } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t TcSocketPollingTask::handleSuccessfullTcRead() { - return HasReturnvaluesIF::RETURN_OK; +ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { + store_address_t storeId = 0; + ReturnValue_t result = tcStore->addData(&storeId, + receptionBuffer.data(), bytesRead); + // arrayprinter::print(receptionBuffer.data(), bytesRead); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "TcSerialPollingTask::transferPusToSoftwareBus: Data " + "storage failed" << std::endl; + sif::debug << "Packet size: " << bytesRead << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + TmTcMessage message(storeId); + result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Serial Polling: Sending message to queue failed" + << std::endl; + tcStore->deleteData(storeId); + } + return result; } + + diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index a6b0e9d47..3503d5056 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -1,5 +1,6 @@ #ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ #define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ + #include #include #include @@ -16,7 +17,7 @@ * This class caches the IP address of the sender. It is assumed there * is only one sender for now. */ -class TcSocketPollingTask: public SystemObject, +class TcUnixUdpPollingTask: public SystemObject, public ExecutableObjectIF { friend class TmTcUnixUdpBridge; public: @@ -24,17 +25,21 @@ public: //! 0.5 default milliseconds timeout for now. static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500}; - TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize = 0, double timeoutSeconds = -1); - virtual~ TcSocketPollingTask(); + virtual~ TcUnixUdpPollingTask(); virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual ReturnValue_t initialize() override; +protected: + StorageManagerIF* tcStore = nullptr; + private: //! TMTC bridge is cached. object_id_t tmtcBridgeId = objects::NO_OBJECT; TmTcUnixUdpBridge* tmtcBridge = nullptr; + MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; //! Reception flags: https://linux.die.net/man/2/recvfrom. int receptionFlags = 0; @@ -47,7 +52,7 @@ private: size_t frameSize = 0; timeval receptionTimeout; - ReturnValue_t handleSuccessfullTcRead(); + ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); }; diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 710761b44..a337b8ae2 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -101,7 +101,7 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { void TmTcUnixUdpBridge::handleBindError() { // See: https://man7.org/linux/man-pages/man2/bind.2.html switch(errno) { - case(EACCES): + case(EACCES): { /* Ephermeral ports can be shown with following command: sysctl -A | grep ip_local_port_range @@ -110,7 +110,8 @@ void TmTcUnixUdpBridge::handleBindError() { "Ports 1-1024 are reserved on UNIX systems and require root " "rights while ephermeral ports should not be used as well." << std::endl; - break; + } + break; case(EADDRINUSE): case(EBADF): case(EINVAL): @@ -122,15 +123,17 @@ void TmTcUnixUdpBridge::handleBindError() { case(ENOENT): case(ENOMEM): case(ENOTDIR): - case(EROFS): + case(EROFS): { sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" - << " with " << strerror(errno) << std::endl; + << " with " << strerror(errno) << std::endl; break; - default: + } + default: { sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" - << std::endl; + << std::endl; break; } + } } diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index 15d256cd4..2fb606b0e 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -7,7 +7,7 @@ #include class TmTcUnixUdpBridge: public TmTcBridge { - friend class TcSocketPollingTask; + friend class TcUnixUdpPollingTask; public: // The ports chosen here should not be used by any other process. // List of used ports on Linux: /etc/services diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index 878b8f7d5..199e2ed15 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -2,30 +2,37 @@ #include #include -CCSDSDistributor::CCSDSDistributor( uint16_t setDefaultApid, object_id_t setObjectId ) : - TcDistributor( setObjectId ), default_apid( setDefaultApid ), tcStore(NULL) { +CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, + object_id_t setObjectId): + TcDistributor(setObjectId), defaultApid( setDefaultApid ) { } -CCSDSDistributor::~CCSDSDistributor() { +CCSDSDistributor::~CCSDSDistributor() {} -} - -iterator_t CCSDSDistributor::selectDestination() { -// debug << "CCSDSDistributor::selectDestination received: " << this->currentMessage.getStorageId().pool_index << ", " << this->currentMessage.getStorageId().packet_index << std::endl; - const uint8_t* p_packet = NULL; +TcDistributor::TcMessageQueueMapIter CCSDSDistributor::selectDestination() { +// sif::debug << "CCSDSDistributor::selectDestination received: " << +// this->currentMessage.getStorageId().pool_index << ", " << +// this->currentMessage.getStorageId().packet_index << std::endl; + const uint8_t* packet = nullptr; size_t size = 0; - //TODO check returncode? - this->tcStore->getData( this->currentMessage.getStorageId(), &p_packet, &size ); - SpacePacketBase current_packet( p_packet ); -// info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << current_packet.getAPID() << std::dec << std::endl; - iterator_t position = this->queueMap.find( current_packet.getAPID() ); + ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(), + &packet, &size ); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "CCSDSDistributor::selectDestination: Getting data from" + "store failed!" << std::endl; + } + SpacePacketBase currentPacket(packet); + +// sif:: info << "CCSDSDistributor::selectDestination has packet with APID " +// << std::hex << currentPacket.getAPID() << std::dec << std::endl; + TcMessageQueueMapIter position = this->queueMap.find(currentPacket.getAPID()); if ( position != this->queueMap.end() ) { return position; } else { - //The APID was not found. Forward packet to main SW-APID anyway to create acceptance failure report. - return this->queueMap.find( this->default_apid ); + //The APID was not found. Forward packet to main SW-APID anyway to + // create acceptance failure report. + return this->queueMap.find( this->defaultApid ); } - } MessageQueueId_t CCSDSDistributor::getRequestQueue() { diff --git a/tcdistribution/CCSDSDistributor.h b/tcdistribution/CCSDSDistributor.h index 9dce34f2b..22025f760 100644 --- a/tcdistribution/CCSDSDistributor.h +++ b/tcdistribution/CCSDSDistributor.h @@ -1,58 +1,69 @@ -#ifndef CCSDSDISTRIBUTOR_H_ -#define CCSDSDISTRIBUTOR_H_ +#ifndef FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ +#define FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ #include #include #include #include #include + /** - * An instantiation of the CCSDSDistributorIF. - * It receives Space Packets, and selects a destination depending on the APID of the telecommands. + * @brief An instantiation of the CCSDSDistributorIF. + * @details + * It receives Space Packets, and selects a destination depending on the + * APID of the telecommands. * The Secondary Header (with Service/Subservice) is ignored. - * \ingroup tc_distribution + * @ingroup tc_distribution */ -class CCSDSDistributor : public TcDistributor, public CCSDSDistributorIF, public AcceptsTelecommandsIF { -protected: - /** - * This implementation checks if an Application with fitting APID has registered and forwards the - * packet to the according message queue. - * If the packet is not found, it returns the queue to \c default_apid, where a Acceptance Failure - * message should be generated. - * @return Iterator to map entry of found APID or iterator to default APID. - */ - iterator_t selectDestination(); - /** - * The default APID, where packets with unknown APID are sent to. - */ - uint16_t default_apid; - /** - * A reference to the TC storage must be maintained, as this class handles pure Space Packets and there - * exists no SpacePacketStored class. - */ - StorageManagerIF* tcStore; - /** - * The callback here handles the generation of acceptance success/failure messages. - */ - ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); +class CCSDSDistributor : public TcDistributor, + public CCSDSDistributorIF, + public AcceptsTelecommandsIF { public: /** - * The constructor sets the default APID and calls the TcDistributor ctor with a certain object id. - * \c tcStore is set in the \c initialize method. - * @param set_default_apid The default APID, where packets with unknown destination are sent to. + * @brief The constructor sets the default APID and calls the + * TcDistributor ctor with a certain object id. + * @details + * @c tcStore is set in the @c initialize method. + * @param set_default_apid The default APID, where packets with unknown + * destination are sent to. */ CCSDSDistributor( uint16_t setDefaultApid, object_id_t setObjectId ); /** * The destructor is empty. */ ~CCSDSDistributor(); - MessageQueueId_t getRequestQueue(); - ReturnValue_t registerApplication( uint16_t apid, MessageQueueId_t id ); - ReturnValue_t registerApplication( AcceptsTelecommandsIF* application ); + + MessageQueueId_t getRequestQueue() override; + ReturnValue_t registerApplication( uint16_t apid, + MessageQueueId_t id) override; + ReturnValue_t registerApplication( + AcceptsTelecommandsIF* application) override; uint16_t getIdentifier(); - ReturnValue_t initialize(); + ReturnValue_t initialize() override; + +protected: + /** + * This implementation checks if an application with fitting APID has + * registered and forwards the packet to the according message queue. + * If the packet is not found, it returns the queue to @c defaultApid, + * where a Acceptance Failure message should be generated. + * @return Iterator to map entry of found APID or iterator to default APID. + */ + TcMessageQueueMapIter selectDestination(); + /** + * The default APID, where packets with unknown APID are sent to. + */ + uint16_t defaultApid; + /** + * A reference to the TC storage must be maintained, as this class handles + * pure Space Packets and there exists no SpacePacketStored class. + */ + StorageManagerIF* tcStore = nullptr; + /** + * The callback here handles the generation of acceptance + * success/failure messages. + */ + ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); }; - - -#endif /* CCSDSDISTRIBUTOR_H_ */ +#endif /* FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index bcf6d5717..f13b5f8de 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -12,9 +12,9 @@ PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, PUSDistributor::~PUSDistributor() {} -iterator_t PUSDistributor::selectDestination() { +TcDistributor::TcMessageQueueMapIter PUSDistributor::selectDestination() { // debug << "PUSDistributor::handlePacket received: " << this->current_packet_id.store_index << ", " << this->current_packet_id.packet_index << std::endl; - iterator_t queueMapIt = this->queueMap.end(); + TcMessageQueueMapIter queueMapIt = this->queueMap.end(); this->currentPacket.setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket.getWholeData() != NULL) { tcStatus = checker.checkPacket(¤tPacket); diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index 8d7746626..3d6717bd4 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -1,5 +1,5 @@ -#ifndef PUSDISTRIBUTOR_H_ -#define PUSDISTRIBUTOR_H_ +#ifndef FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ +#define FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ #include #include @@ -9,37 +9,42 @@ #include /** - * This class accepts PUS Telecommands and forwards them to Application services. - * In addition, the class performs a formal packet check and sends acceptance success - * or failure messages. - * \ingroup tc_distribution + * This class accepts PUS Telecommands and forwards them to Application + * services. In addition, the class performs a formal packet check and + * sends acceptance success or failure messages. + * @ingroup tc_distribution */ class PUSDistributor: public TcDistributor, public PUSDistributorIF, public AcceptsTelecommandsIF { public: /** - * The ctor passes \c set_apid to the checker class and calls the TcDistribution ctor with a certain object id. + * The ctor passes @c set_apid to the checker class and calls the + * TcDistribution ctor with a certain object id. * @param setApid The APID of this receiving Application. * @param setObjectId Object ID of the distributor itself - * @param setPacketSource Object ID of the source of TC packets. Must implement CCSDSDistributorIF. + * @param setPacketSource Object ID of the source of TC packets. + * Must implement CCSDSDistributorIF. */ - PUSDistributor(uint16_t setApid, object_id_t setObjectId, object_id_t setPacketSource); + PUSDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource); /** * The destructor is empty. */ virtual ~PUSDistributor(); - ReturnValue_t registerService(AcceptsTelecommandsIF* service); - MessageQueueId_t getRequestQueue(); - uint16_t getIdentifier(); - ReturnValue_t initialize(); + ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t initialize() override; + uint16_t getIdentifier() override; + protected: /** * This attribute contains the class, that performs a formal packet check. */ TcPacketCheck checker; /** - * With this class, verification messages are sent to the TC Verification service. + * With this class, verification messages are sent to the + * TC Verification service. */ VerificationReporter verifyChannel; /** @@ -47,21 +52,26 @@ protected: */ TcPacketStored currentPacket; /** - * With this variable, the current check status is stored to generate acceptance messages later. + * With this variable, the current check status is stored to generate + * acceptance messages later. */ ReturnValue_t tcStatus; const object_id_t packetSource; /** - * This method reads the packet service, checks if such a service is registered and forwards the packet to the destination. - * It also initiates the formal packet check and sending of verification messages. - * @return Iterator to map entry of found service id or iterator to \c map.end(). + * This method reads the packet service, checks if such a service is + * registered and forwards the packet to the destination. + * It also initiates the formal packet check and sending of verification + * messages. + * @return Iterator to map entry of found service id + * or iterator to @c map.end(). */ - iterator_t selectDestination(); + TcMessageQueueMapIter selectDestination(); /** - * The callback here handles the generation of acceptance success/failure messages. + * The callback here handles the generation of acceptance + * success/failure messages. */ ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus); }; -#endif /* PUSDISTRIBUTOR_H_ */ +#endif /* FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/TcDistributor.cpp b/tcdistribution/TcDistributor.cpp index 579214593..7bebbb9c7 100644 --- a/tcdistribution/TcDistributor.cpp +++ b/tcdistribution/TcDistributor.cpp @@ -15,7 +15,6 @@ TcDistributor::~TcDistributor() { ReturnValue_t TcDistributor::performOperation(uint8_t opCode) { ReturnValue_t status = RETURN_OK; -// debug << "TcDistributor: performing Operation." << std::endl; for (status = tcQueue->receiveMessage(¤tMessage); status == RETURN_OK; status = tcQueue->receiveMessage(¤tMessage)) { status = handlePacket(); @@ -29,7 +28,7 @@ ReturnValue_t TcDistributor::performOperation(uint8_t opCode) { ReturnValue_t TcDistributor::handlePacket() { - iterator_t queueMapIt = this->selectDestination(); + TcMessageQueueMapIter queueMapIt = this->selectDestination(); ReturnValue_t returnValue = RETURN_FAILED; if (queueMapIt != this->queueMap.end()) { returnValue = this->tcQueue->sendMessage(queueMapIt->second, @@ -41,7 +40,7 @@ ReturnValue_t TcDistributor::handlePacket() { void TcDistributor::print() { sif::debug << "Distributor content is: " << std::endl << "ID\t| message queue id" << std::endl; - for (iterator_t it = this->queueMap.begin(); it != this->queueMap.end(); + for (TcMessageQueueMapIter it = this->queueMap.begin(); it != this->queueMap.end(); it++) { sif::debug << it->first << "\t| 0x" << std::hex << it->second << std::dec << std::endl; diff --git a/tcdistribution/TcDistributor.h b/tcdistribution/TcDistributor.h index b80f08e68..5c958de08 100644 --- a/tcdistribution/TcDistributor.h +++ b/tcdistribution/TcDistributor.h @@ -1,5 +1,6 @@ -#ifndef TCDISTRIBUTOR_H_ -#define TCDISTRIBUTOR_H_ +#ifndef FRAMEWORK_TMTCSERVICES_TCDISTRIBUTOR_H_ +#define FRAMEWORK_TMTCSERVICES_TCDISTRIBUTOR_H_ + #include #include #include @@ -9,16 +10,12 @@ #include #include - /** - * \defgroup tc_distribution Telecommand Distribution - * All classes associated with Routing and Distribution of Telecommands belong to this group. + * @defgroup tc_distribution Telecommand Distribution + * All classes associated with Routing and Distribution of Telecommands + * belong to this group. */ -/** - * This typedef simplifies writing down the \c map iterator. - */ -typedef std::map::iterator iterator_t; /** * This is the base class to implement distributors for Space Packets. @@ -28,59 +25,15 @@ typedef std::map::iterator iterator_t; * message queue ids to some identifier. The process of unpacking the * destination information from the packet is handled by the child class * implementations. - * \ingroup tc_distribution + * @ingroup tc_distribution */ -class TcDistributor : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { -private: - /** - * This constant sets the maximum number of packets distributed per call. - */ - static const uint8_t DISTRIBUTER_MAX_PACKETS = 128; -protected: - /** - * This is the receiving queue for incoming Telecommands. - * The child classes must make its queue id public. - */ - MessageQueueIF* tcQueue; - /** - * The last received incoming packet information is stored in this - * member. - * As different child classes unpack the incoming packet differently - * (i.e. as a CCSDS Space Packet or as a PUS Telecommand Packet), it - * is not tried to unpack the packet information within this class. - */ - TmTcMessage currentMessage; - /** - * The map that links certain packet information to a destination. - * The packet information may be the APID of the packet or the service - * identifier. Filling of the map is under control of the different child - * classes. - */ - std::map queueMap; - /** - * This method shall unpack the routing information from the incoming - * packet and select the map entry which represents the packet's target. - * @return An iterator to the map element to forward to or queuMap.end(). - */ - virtual iterator_t selectDestination() = 0; - /** - * The handlePacket method calls the child class's selectDestination method - * and forwards the packet to its destination, if found. - * @return The message queue return value or \c RETURN_FAILED, in case no - * destination was found. - */ - ReturnValue_t handlePacket(); - /** - * This method gives the child class a chance to perform some kind of operation - * after the parent tried to forward the message. - * A typically application would be sending success/failure messages. - * The default implementation just returns \c RETURN_OK. - * @param queueStatus The status of the message queue after an attempt to send the TC. - * @return - \c RETURN_OK on success - * - \c RETURN_FAILED on failure - */ - virtual ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); +class TcDistributor : public SystemObject, + public ExecutableObjectIF, + public HasReturnvaluesIF { public: + using TcMessageQueueMap = std::map; + using TcMessageQueueMapIter = std::map::iterator; + static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_DISTRIBUTION; static const ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE( 1 ); static const ReturnValue_t DESTINATION_NOT_FOUND = MAKE_RETURN_CODE( 2 ); @@ -110,6 +63,57 @@ public: * queueMap. */ void print(); + +protected: + /** + * This is the receiving queue for incoming Telecommands. + * The child classes must make its queue id public. + */ + MessageQueueIF* tcQueue; + /** + * The last received incoming packet information is stored in this + * member. + * As different child classes unpack the incoming packet differently + * (i.e. as a CCSDS Space Packet or as a PUS Telecommand Packet), it + * is not tried to unpack the packet information within this class. + */ + TmTcMessage currentMessage; + /** + * The map that links certain packet information to a destination. + * The packet information may be the APID of the packet or the service + * identifier. Filling of the map is under control of the different child + * classes. + */ + TcMessageQueueMap queueMap; + /** + * This method shall unpack the routing information from the incoming + * packet and select the map entry which represents the packet's target. + * @return An iterator to the map element to forward to or queuMap.end(). + */ + virtual TcMessageQueueMapIter selectDestination() = 0; + /** + * The handlePacket method calls the child class's selectDestination method + * and forwards the packet to its destination, if found. + * @return The message queue return value or \c RETURN_FAILED, in case no + * destination was found. + */ + ReturnValue_t handlePacket(); + /** + * This method gives the child class a chance to perform some kind of operation + * after the parent tried to forward the message. + * A typically application would be sending success/failure messages. + * The default implementation just returns \c RETURN_OK. + * @param queueStatus The status of the message queue after an attempt to send the TC. + * @return - \c RETURN_OK on success + * - \c RETURN_FAILED on failure + */ + virtual ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); + +private: + /** + * This constant sets the maximum number of packets distributed per call. + */ + static const uint8_t DISTRIBUTER_MAX_PACKETS = 128; }; diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index 82e5ff5cc..cb1e633f6 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -41,9 +41,14 @@ void PusServiceBase::handleRequestQueue() { ReturnValue_t result = RETURN_FAILED; for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { ReturnValue_t status = this->requestQueue->receiveMessage(&message); - // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " - // << std::hex << this->requestQueue.getId() - // << std::dec << " returned: " << status << std::endl; +// if(status != MessageQueueIF::EMPTY) { +// sif::debug << "PusServiceBase::performOperation: Receiving from " +// << "MQ ID: " << std::hex << "0x" << std::setw(8) +// << std::setfill('0') << this->requestQueue->getId() +// << std::dec << " returned: " << status << std::setfill(' ') +// << std::endl; +// } + if (status == RETURN_OK) { this->currentPacket.setStoreAddress(message.getStorageId()); //info << "Service " << (uint16_t) this->serviceId << diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 5b933c793..a009c9622 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -62,7 +62,7 @@ public: * @param virtualChannel * @return */ - MessageQueueId_t getReportReceptionQueue( + virtual MessageQueueId_t getReportReceptionQueue( uint8_t virtualChannel = 0) override; protected: //! Used to send and receive TMTC messages.