diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp new file mode 100644 index 00000000..e7928317 --- /dev/null +++ b/tmtcservices/TmTcBridge.cpp @@ -0,0 +1,173 @@ +/** + * @file TmTcBridge.cpp + * + * @date 26.12.2019 + */ + +#include + +#include +#include +#include + +TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): + SystemObject(objectId_),tcStore(NULL), tmStore(NULL), + ccsdsPacketDistributor(ccsdsPacketDistributor_), communicationLinkUp(false), + tmStored(false) { + TmTcReceptionQueue = QueueFactory::instance()-> + createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); + +} + +TmTcBridge::~TmTcBridge() { +} + +ReturnValue_t TmTcBridge::initialize() { + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == NULL) { + return RETURN_FAILED; + } + tmStore = objectManager->get(objects::TM_STORE); + if (tmStore == NULL) { + return RETURN_FAILED; + } + AcceptsTelecommandsIF* tcDistributor = + objectManager->get(ccsdsPacketDistributor); + if (tcDistributor == NULL) { + return RETURN_FAILED; + } + TmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue()); + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { + ReturnValue_t result; + result = handleTc(); + if(result != RETURN_OK) { + error << "TMTC Bridge: Error handling TCs" << std::endl; + } + result = handleTm(); + if (result != RETURN_OK) { + error << "TMTC Bridge: Error handling TMs" << std::endl; + } + return result; +} + +ReturnValue_t TmTcBridge::handleTc() { + ReturnValue_t result = receiveTc(); + return result; +} + +ReturnValue_t TmTcBridge::handleTm() { + ReturnValue_t result = readTmQueue(); + if(result != RETURN_OK) { + error << "TMTC Bridge: Reading TM Queue failed" << std::endl; + return RETURN_FAILED; + } + + if(tmStored && communicationLinkUp) { + result = sendStoredTm(); + } + return result; + +} + +ReturnValue_t TmTcBridge::readTmQueue() { + TmTcMessage message; + const uint8_t* data = NULL; + uint32_t size = 0; + for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message); + result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message)) + { + if(not communicationLinkUp) { + result = storeDownlinkData(&message); + return result; + } + + result = tmStore->getData(message.getStorageId(), &data, &size); + if (result != HasReturnvaluesIF::RETURN_OK) { + continue; + } + + result = sendTm(data, size); + if (result != RETURN_OK) { + error << "UDP Server: Could not send TM packet"<< std::endl; + tmStore->deleteData(message.getStorageId()); + return result; + + } + tmStore->deleteData(message.getStorageId()); + } + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { + info << "UDP Server: Client address not bound yet. Packet can not be sent. " + "Saving packet to be sent later " << std::endl; + store_address_t storeId; + + if(fifo.full()) { + info << "UDP Server: TM downlink store is full. Overwriting old data" << std::endl; + fifo.retrieve(&storeId); + } + storeId = message->getStorageId(); + fifo.insert(storeId); + //storageIdBufferCounter ++; + tmStored = true; + return RETURN_OK; +} + +ReturnValue_t TmTcBridge::sendStoredTm() { + uint8_t counter = 0; + ReturnValue_t result = RETURN_OK; + while(!fifo.empty() && counter < MAX_STORED_DATA_SENT_PER_CYCLE) { + info << "UDP Server: Sending stored TM data. There are " + << (int) fifo.size() << " left to send" << std::endl; + store_address_t storeId; + const uint8_t* data = NULL; + uint32_t size = 0; + fifo.retrieve(&storeId); + result = tmStore->getData(storeId, &data, &size); + sendTm(data,size); + if(result != RETURN_OK) { + error << "UDP Server: Could not send stored downlink data" << std::endl; + result = RETURN_FAILED; + } + counter ++; + + if(fifo.empty()) { + tmStored = false; + } + tmStore->deleteData(storeId); + } + return result; +} + +void TmTcBridge::registerCommConnect() { + info << "TMTC Bridge: Registered Comm Link Connect" << std::endl; + if(not communicationLinkUp) { + communicationLinkUp = true; + } +} + +void TmTcBridge::registerCommDisconnect() { + info << "TMTC Bridge: Registered Comm Link Disconnect" << std::endl; + if(communicationLinkUp) { + communicationLinkUp = false; + } +} + +MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { + return TmTcReceptionQueue->getId(); +} + +void TmTcBridge::printData(uint8_t * data, uint32_t dataLen) { + info << "TMTC Bridge: Printing data: ["; + for(uint32_t i=0;i +#include +#include +#include +#include + +#include +#include + +class TmTcBridge : public AcceptsTelemetryIF, + public ExecutableObjectIF, + public HasReturnvaluesIF, + public SystemObject { +public: + TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_); + virtual ~TmTcBridge(); + + /** + * Initializes basic FSFW components for TMTC Bridge + * @return + */ + virtual ReturnValue_t initialize(); + + /** + * @brief The performOperation method is executed in a task. + * @details There are no restrictions for calls within this method, so any + * other member of the class can be used. + * @return Currently, the return value is ignored. + */ + virtual ReturnValue_t performOperation(uint8_t operationCode = 0); + + /** + * Return TMTC Reception Queue + * @param virtualChannel + * @return + */ + virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0); + +protected: + MessageQueueIF* TmTcReceptionQueue; //!< Used to send and receive TMTC messages. TmTcMessage is used to transport messages between tasks. + StorageManagerIF* tcStore; + StorageManagerIF* tmStore; + object_id_t ccsdsPacketDistributor; + bool communicationLinkUp; //!< Used to specify whether communication link is up + bool tmStored; + + /** + * Handle TC reception. Default implementation provided + * @return + */ + virtual ReturnValue_t handleTc(); + + /** + * Implemented by child class. Perform receiving of Telecommand + * @return + */ + virtual ReturnValue_t receiveTc() = 0; + + /** + * Handle Telemetry. Default implementation provided. + * Calls sendTm() + * @return + */ + virtual ReturnValue_t handleTm(); + + /** + * Read the TM Queue and send TM if necessary. Default implementation provided + * @return + */ + virtual ReturnValue_t readTmQueue(); + + /** + * Implemented by child class. Perform sending of Telemetry + * @param data + * @param dataLen + * @return + */ + virtual ReturnValue_t sendTm(const uint8_t * data, uint32_t dataLen) = 0; + + /** + * Store data to be sent later if communication link is not up. + * @param message + * @return + */ + ReturnValue_t storeDownlinkData(TmTcMessage * message); + + /** + * Send stored data if communication link is active + * @return + */ + ReturnValue_t sendStoredTm(); + + /** + * Print data as hexidecimal array + * @param data + * @param dataLen + */ + void printData(uint8_t * data, uint32_t dataLen); + + void registerCommConnect(); + void registerCommDisconnect(); + +private: + static const uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20; + static const uint8_t MAX_STORED_DATA_SENT_PER_CYCLE = 10; + static const uint8_t MAX_DOWNLINK_PACKETS_STORED = 20; + + FIFO fifo; +}; + + +#endif /* FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ */