1
0
forked from fsfw/fsfw

unittests for TC and CCSDS distributor

This commit is contained in:
2022-08-01 17:16:37 +02:00
parent bf540ebb49
commit 902a4bfa9c
29 changed files with 277 additions and 66 deletions

View File

@ -3,11 +3,11 @@
#include <map>
#include "LocalDataPoolManager.h"
#include "fsfw/datapool/PoolEntryIF.h"
#include "fsfw/housekeeping/HousekeepingMessage.h"
#include "fsfw/ipc/MessageQueueSenderIF.h"
#include "fsfw/serviceinterface.h"
#include "LocalDataPoolManager.h"
#include "localPoolDefinitions.h"
class AccessPoolManagerIF;

View File

@ -19,6 +19,7 @@ enum : uint8_t {
HK = 73,
SYSTEM_MANAGER = 74,
SYSTEM_MANAGER_1 = 75,
TC_DISTRIBUTION = 76,
SYSTEM_1 = 79,
PUS_SERVICE_1 = 80,
PUS_SERVICE_2 = 82,

View File

@ -2,7 +2,6 @@
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
#include "fsfw/FSFW.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,9 +1,8 @@
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
#include "fsfw/FSFW.h"
#include "ServiceInterfaceBuffer.h"
#include "fsfw/FSFW.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1

View File

@ -1,7 +1,7 @@
#include "fsfw/FSFW.h"
#include "fsfw/tcdistribution/CcsdsDistributor.h"
#include "definitions.h"
#include "fsfw/FSFW.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
@ -9,9 +9,11 @@
#define CCSDS_DISTRIBUTOR_DEBUGGING 0
CcsdsDistributor::CcsdsDistributor(uint16_t setDefaultApid, object_id_t setObjectId,
StorageManagerIF* tcStore, MessageQueueIF* queue,
CcsdsPacketCheckIF* packetChecker)
: TcDistributorBase(setObjectId),
: TcDistributorBase(setObjectId, queue),
defaultApid(setDefaultApid),
tcStore(tcStore),
packetChecker(packetChecker) {}
CcsdsDistributor::~CcsdsDistributor() = default;
@ -28,9 +30,8 @@ ReturnValue_t CcsdsDistributor::selectDestination(MessageQueueId_t& destId) {
currentMessage.getStorageId().packetIndex);
#endif
#endif
const uint8_t* packet = nullptr;
size_t size = 0;
ReturnValue_t result = tcStore->getData(currentMessage.getStorageId(), &packet, &size);
auto accessorPair = tcStore->getData(currentMessage.getStorageId());
ReturnValue_t result = accessorPair.first;
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
@ -45,8 +46,11 @@ ReturnValue_t CcsdsDistributor::selectDestination(MessageQueueId_t& destId) {
#endif
return result;
}
SpacePacketReader currentPacket(packet, size);
result = packetChecker->checkPacket(currentPacket, size);
if (accessorPair.second.size() < ccsds::HEADER_LEN) {
return SerializeIF::STREAM_TOO_SHORT;
}
SpacePacketReader currentPacket(accessorPair.second.data(), accessorPair.second.size());
result = packetChecker->checkPacket(currentPacket, accessorPair.second.size());
if (result != HasReturnvaluesIF::RETURN_OK) {
handlePacketCheckFailure(result);
return result;
@ -59,11 +63,12 @@ ReturnValue_t CcsdsDistributor::selectDestination(MessageQueueId_t& destId) {
if (iter != receiverMap.end()) {
destId = iter->second.destId;
if (iter->second.removeHeader) {
handleCcsdsHeaderRemoval();
// Do not call accessor release method here to ensure the old packet gets deleted.
return handleCcsdsHeaderRemoval(accessorPair.second);
}
} else {
// The APID was not found. Forward packet to main SW-APID anyway to
// create acceptance failure report.
// create acceptance failure report.
iter = receiverMap.find(defaultApid);
if (iter != receiverMap.end()) {
destId = iter->second.destId;
@ -71,6 +76,7 @@ ReturnValue_t CcsdsDistributor::selectDestination(MessageQueueId_t& destId) {
return DESTINATION_NOT_FOUND;
}
}
accessorPair.second.release();
return HasReturnvaluesIF::RETURN_OK;
}
@ -111,23 +117,28 @@ ReturnValue_t CcsdsDistributor::initialize() {
if (packetChecker == nullptr) {
packetChecker = new CcsdsPacketChecker(ccsds::PacketType::TC);
}
ReturnValue_t status = this->TcDistributorBase::initialize();
this->tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (this->tcStore == nullptr) {
ReturnValue_t result = TcDistributorBase::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (tcStore == nullptr) {
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (tcStore == nullptr) {
#if FSFW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CCSDSDistributor::initialize: Could not initialize"
" TC store!"
<< std::endl;
sif::error << "CCSDSDistributor::initialize: Could not initialize"
" TC store!"
<< std::endl;
#else
sif::printError(
"CCSDSDistributor::initialize: Could not initialize"
" TC store!\n");
sif::printError(
"CCSDSDistributor::initialize: Could not initialize"
" TC store!\n");
#endif
#endif
status = RETURN_FAILED;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
return status;
return result;
}
ReturnValue_t CcsdsDistributor::callbackAfterSending(ReturnValue_t queueStatus) {
@ -151,15 +162,19 @@ void CcsdsDistributor::print() {
const char* CcsdsDistributor::getName() const { return "CCSDS Distributor"; }
ReturnValue_t CcsdsDistributor::handleCcsdsHeaderRemoval() {
currentMessage;
auto accessorPair = tcStore->getData(currentMessage.getStorageId());
if(accessorPair.first != HasReturnvaluesIF::RETURN_OK) {
ReturnValue_t CcsdsDistributor::handleCcsdsHeaderRemoval(ConstStorageAccessor& accessor) {
store_address_t newStoreId;
ReturnValue_t result = tcStore->addData(&newStoreId, accessor.data() + ccsds::HEADER_LEN,
accessor.size() - ccsds::HEADER_LEN);
if (result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << __func__ << ": Getting TC data failed" << std::endl;
sif::error << __func__ << ": TC store full" << std::endl;
#else
sif::printError("%s: Getting TC data failed\n", __func__);
sif::printError("%s: TC store full\n", __func__);
#endif
return accessorPair.first;
return result;
}
currentMessage.setStorageId(newStoreId);
// The const accessor will delete the old data automatically
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -31,6 +31,7 @@ class CcsdsDistributor : public TcDistributorBase,
* destination are sent to.
*/
CcsdsDistributor(uint16_t unknownApid, object_id_t setObjectId,
StorageManagerIF* tcStore = nullptr, MessageQueueIF* msgQueue = nullptr,
CcsdsPacketCheckIF* packetChecker = nullptr);
/**
* The destructor is empty.
@ -63,7 +64,7 @@ class CcsdsDistributor : public TcDistributorBase,
static void handlePacketCheckFailure(ReturnValue_t result);
ReturnValue_t handleCcsdsHeaderRemoval();
ReturnValue_t handleCcsdsHeaderRemoval(ConstStorageAccessor& accessor);
void print();
/**
* The default APID, where packets with unknown APID are sent to.

View File

@ -17,8 +17,8 @@ class CcsdsDistributorIF {
struct DestInfo {
DestInfo(const char* name, uint16_t apid, MessageQueueId_t destId, bool removeHeader)
: name(name), apid(apid), destId(destId), removeHeader(removeHeader) {}
DestInfo(const char* name, const AcceptsTelecommandsIF& ccsdsReceiver, bool removeHeader_)
: name(name) {
DestInfo(const AcceptsTelecommandsIF& ccsdsReceiver, bool removeHeader_)
: name(ccsdsReceiver.getName()) {
apid = ccsdsReceiver.getIdentifier();
destId = ccsdsReceiver.getRequestQueue();
removeHeader = removeHeader_;

View File

@ -4,29 +4,28 @@
CcsdsUnpacker::CcsdsUnpacker(MessageQueueIF& msgQueue, AcceptsTelecommandsIF& receiver,
StorageManagerIF& sourceStore)
: sourceStore(sourceStore), msgQueue(msgQueue), receiver(receiver) {
: sourceStore(sourceStore), msgQueue(msgQueue), receiver(receiver) {
msgQueue.setDefaultDestination(receiver.getRequestQueue());
}
ReturnValue_t CcsdsUnpacker::performOperation(uint8_t operationCode) {
TmTcMessage msg;
ReturnValue_t result;
for (result = msgQueue.receiveMessage(&msg); result == HasReturnvaluesIF::RETURN_OK;
for (result = msgQueue.receiveMessage(&msg); result == HasReturnvaluesIF::RETURN_OK;
result = msgQueue.receiveMessage(&msg)) {
auto resultPair = sourceStore.getData(msg.getStorageId());
if(resultPair.first != HasReturnvaluesIF::RETURN_OK) {
if (resultPair.first != HasReturnvaluesIF::RETURN_OK) {
continue;
}
if(resultPair.second.size() < 6) {
if (resultPair.second.size() < 6) {
// TODO: This is a config error. Does it make sense to forward the message?
result = msgQueue.sendToDefault(&msg);
if(result != HasReturnvaluesIF::RETURN_OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
}
continue;
}
StorageManagerIF* tgtStore;
if(targetStore != nullptr) {
if (targetStore != nullptr) {
tgtStore = targetStore;
} else {
tgtStore = &sourceStore;
@ -34,24 +33,22 @@ ReturnValue_t CcsdsUnpacker::performOperation(uint8_t operationCode) {
store_address_t newId;
uint8_t* ptr;
result = tgtStore->getFreeElement(&newId, resultPair.second.size(), &ptr);
if(result != HasReturnvaluesIF::RETURN_OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
// TODO: Implement error handling
}
std::memcpy(ptr, resultPair.second.data() + 6, resultPair.second.size() - 6);
result = sourceStore.deleteData(msg.getStorageId());
if(result != HasReturnvaluesIF::RETURN_OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
// TODO: Implement error handling (though this really should not happen)
}
TmTcMessage newMsg(newId);
result = msgQueue.sendToDefault(&newMsg);
if(result != HasReturnvaluesIF::RETURN_OK) {
if (result != HasReturnvaluesIF::RETURN_OK) {
}
}
return result;
}
void CcsdsUnpacker::setDifferentTargetStore(StorageManagerIF& otherTargetStore) {
targetStore = &otherTargetStore;
}

View File

@ -7,7 +7,8 @@
class CcsdsUnpacker : public ExecutableObjectIF, public AcceptsTelecommandsIF {
public:
CcsdsUnpacker(MessageQueueIF& msgQueue, AcceptsTelecommandsIF& receiver, StorageManagerIF& sourceStore);
CcsdsUnpacker(MessageQueueIF& msgQueue, AcceptsTelecommandsIF& receiver,
StorageManagerIF& sourceStore);
void setDifferentTargetStore(StorageManagerIF& otherTargetStore);
ReturnValue_t performOperation(uint8_t operationCode) override;

View File

@ -68,6 +68,7 @@ ReturnValue_t CfdpDistributor::selectDestination(MessageQueueId_t& destId) {
// } else {
// return queueMapIt;
// }
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t CfdpDistributor::registerHandler(AcceptsTelecommandsIF* handler) {
@ -141,4 +142,5 @@ ReturnValue_t CfdpDistributor::initialize() {
// return RETURN_FAILED;
// }
// return ccsdsDistributor->registerApplication(this);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -139,8 +139,7 @@ ReturnValue_t PusDistributor::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
return ccsdsDistributor->registerApplication(
CcsdsDistributorIF::DestInfo(getName(), *this, false));
return ccsdsDistributor->registerApplication(CcsdsDistributorIF::DestInfo(*this, false));
}
void PusDistributor::checkerFailurePrinter() const {

View File

@ -3,22 +3,35 @@
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
TcDistributorBase::TcDistributorBase(object_id_t objectId) : SystemObject(objectId) {
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS);
TcDistributorBase::TcDistributorBase(object_id_t objectId, MessageQueueIF* tcQueue_)
: SystemObject(objectId), tcQueue(tcQueue_) {
if (tcQueue == nullptr) {
ownedQueue = true;
tcQueue = QueueFactory::instance()->createMessageQueue(DISTRIBUTER_MAX_PACKETS);
}
}
TcDistributorBase::~TcDistributorBase() { QueueFactory::instance()->deleteMessageQueue(tcQueue); }
TcDistributorBase::~TcDistributorBase() {
if (ownedQueue) {
QueueFactory::instance()->deleteMessageQueue(tcQueue);
}
}
ReturnValue_t TcDistributorBase::performOperation(uint8_t opCode) {
ReturnValue_t status;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (status = tcQueue->receiveMessage(&currentMessage); status == RETURN_OK;
status = tcQueue->receiveMessage(&currentMessage)) {
status = handlePacket();
ReturnValue_t packetResult = handlePacket();
if (packetResult != HasReturnvaluesIF::RETURN_OK) {
result = packetResult;
triggerEvent(HANDLE_PACKET_FAILED, packetResult, __LINE__);
}
}
if (status == MessageQueueIF::EMPTY) {
return RETURN_OK;
return result;
}
return status;
return result;
}
ReturnValue_t TcDistributorBase::handlePacket() {

View File

@ -3,6 +3,7 @@
#include <map>
#include "fsfw/events/Event.h"
#include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/objectmanager/ObjectManagerIF.h"
#include "fsfw/objectmanager/SystemObject.h"
@ -33,6 +34,10 @@ class TcDistributorBase : public SystemObject, public ExecutableObjectIF, public
static constexpr ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE(1);
static constexpr ReturnValue_t DESTINATION_NOT_FOUND = MAKE_RETURN_CODE(2);
static constexpr ReturnValue_t SERVICE_ID_ALREADY_EXISTS = MAKE_RETURN_CODE(3);
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TC_DISTRIBUTION;
//! P1: Returnvalue, P2: Line number
static constexpr Event HANDLE_PACKET_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
/**
* Within the default constructor, the SystemObject id is set and the
* message queue is initialized.
@ -40,7 +45,7 @@ class TcDistributorBase : public SystemObject, public ExecutableObjectIF, public
* @param set_object_id This id is assigned to the distributor
* implementation.
*/
explicit TcDistributorBase(object_id_t objectId);
explicit TcDistributorBase(object_id_t objectId, MessageQueueIF* tcQueue = nullptr);
/**
* The destructor is empty, the message queues are not in the vicinity of
* this class.
@ -56,6 +61,7 @@ class TcDistributorBase : public SystemObject, public ExecutableObjectIF, public
ReturnValue_t performOperation(uint8_t opCode) override;
protected:
bool ownedQueue = false;
/**
* This is the receiving queue for incoming Telecommands.
* The child classes must make its queue id public.

View File

@ -35,8 +35,11 @@ uint16_t SpacePacketReader::getPacketDataLen() const { return ccsds::getPacketLe
ReturnValue_t SpacePacketReader::setInternalFields(const uint8_t* data, size_t maxSize_) {
bufSize = maxSize_;
if (maxSize_ < ccsds::HEADER_LEN) {
return SerializeIF::STREAM_TOO_SHORT;
}
spHeader = reinterpret_cast<const ccsds::PrimaryHeader*>(data);
if (maxSize_ > 6) {
if (maxSize_ > ccsds::HEADER_LEN) {
packetDataField = data + ccsds::HEADER_LEN;
}
return checkSize();