max tm packet size now configurable

This commit is contained in:
Robin Müller 2021-06-14 15:14:57 +02:00
parent 1d2dabb4b4
commit aa33ff2f48
No known key found for this signature in database
GPG Key ID: 9C287E88FED11DF3
12 changed files with 409 additions and 414 deletions

View File

@ -68,6 +68,8 @@ static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048;
}
#endif /* CONFIG_FSFWCONFIG_H_ */

View File

@ -1,5 +1,5 @@
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_
#ifndef FSFW_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_
#define FSFW_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
#include "../../serialize/SerializeAdapter.h"
@ -7,32 +7,32 @@
class ApidMatcher: public SerializeableMatcherIF<TmPacketMinimal*> {
private:
uint16_t apid;
uint16_t apid;
public:
ApidMatcher(uint16_t setApid) :
apid(setApid) {
}
ApidMatcher(TmPacketMinimal* test) :
apid(test->getAPID()) {
}
bool match(TmPacketMinimal* packet) {
if (packet->getAPID() == apid) {
return true;
} else {
return false;
}
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
return SerializeAdapter::serialize(&apid, buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&apid);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&apid, buffer, size, streamEndianness);
}
ApidMatcher(uint16_t setApid) :
apid(setApid) {
}
ApidMatcher(TmPacketMinimal* test) :
apid(test->getAPID()) {
}
bool match(TmPacketMinimal* packet) {
if (packet->getAPID() == apid) {
return true;
} else {
return false;
}
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
return SerializeAdapter::serialize(&apid, buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&apid);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&apid, buffer, size, streamEndianness);
}
};

View File

@ -5,197 +5,194 @@
// This should be configurable..
const LocalPool::LocalPoolConfig PacketMatchTree::poolConfig = {
{10, sizeof(ServiceMatcher)},
{20, sizeof(SubServiceMatcher)},
{2, sizeof(ApidMatcher)},
{40, sizeof(PacketMatchTree::Node)}
{10, sizeof(ServiceMatcher)},
{20, sizeof(SubServiceMatcher)},
{2, sizeof(ApidMatcher)},
{40, sizeof(PacketMatchTree::Node)}
};
PacketMatchTree::PacketMatchTree(Node* root) :
MatchTree<TmPacketMinimal*>(root, 2),
factoryBackend(0, poolConfig, false, true),
factory(&factoryBackend) {
PacketMatchTree::PacketMatchTree(Node* root): MatchTree<TmPacketMinimal*>(root, 2),
factoryBackend(0, poolConfig, false, true),
factory(&factoryBackend) {
}
PacketMatchTree::PacketMatchTree(iterator root) :
MatchTree<TmPacketMinimal*>(root.element, 2),
factoryBackend(0, poolConfig, false, true),
factory(&factoryBackend) {
PacketMatchTree::PacketMatchTree(iterator root): MatchTree<TmPacketMinimal*>(root.element, 2),
factoryBackend(0, poolConfig, false, true),
factory(&factoryBackend) {
}
PacketMatchTree::PacketMatchTree() :
MatchTree<TmPacketMinimal*>((Node*) NULL, 2),
factoryBackend(0, poolConfig, false, true),
factory(&factoryBackend) {
PacketMatchTree::PacketMatchTree(): MatchTree<TmPacketMinimal*>((Node*) NULL, 2),
factoryBackend(0, poolConfig, false, true),
factory(&factoryBackend) {
}
PacketMatchTree::~PacketMatchTree() {
}
ReturnValue_t PacketMatchTree::addMatch(uint16_t apid, uint8_t type,
uint8_t subtype) {
//We assume adding APID is always requested.
TmPacketMinimal::TmPacketMinimalPointer data;
data.data_field.service_type = type;
data.data_field.service_subtype = subtype;
TmPacketMinimal testPacket((uint8_t*) &data);
testPacket.setAPID(apid);
iterator lastTest;
iterator rollback;
ReturnValue_t result = findOrInsertMatch<TmPacketMinimal*, ApidMatcher>(
this->begin(), &testPacket, &lastTest);
if (result == NEW_NODE_CREATED) {
rollback = lastTest;
} else if (result != RETURN_OK) {
return result;
}
if (type == 0) {
//Check if lastTest has no children, otherwise, delete them,
//as a more general check is requested.
if (lastTest.left() != this->end()) {
removeElementAndAllChildren(lastTest.left());
}
return RETURN_OK;
}
//Type insertion required.
result = findOrInsertMatch<TmPacketMinimal*, ServiceMatcher>(
lastTest.left(), &testPacket, &lastTest);
if (result == NEW_NODE_CREATED) {
if (rollback == this->end()) {
rollback = lastTest;
}
} else if (result != RETURN_OK) {
if (rollback != this->end()) {
removeElementAndAllChildren(rollback);
}
return result;
}
if (subtype == 0) {
if (lastTest.left() != this->end()) {
//See above
removeElementAndAllChildren(lastTest.left());
}
return RETURN_OK;
}
//Subtype insertion required.
result = findOrInsertMatch<TmPacketMinimal*, SubServiceMatcher>(
lastTest.left(), &testPacket, &lastTest);
if (result == NEW_NODE_CREATED) {
return RETURN_OK;
} else if (result != RETURN_OK) {
if (rollback != this->end()) {
removeElementAndAllChildren(rollback);
}
return result;
}
return RETURN_OK;
uint8_t subtype) {
//We assume adding APID is always requested.
TmPacketMinimal::TmPacketMinimalPointer data;
data.data_field.service_type = type;
data.data_field.service_subtype = subtype;
TmPacketMinimal testPacket((uint8_t*) &data);
testPacket.setAPID(apid);
iterator lastTest;
iterator rollback;
ReturnValue_t result = findOrInsertMatch<TmPacketMinimal*, ApidMatcher>(
this->begin(), &testPacket, &lastTest);
if (result == NEW_NODE_CREATED) {
rollback = lastTest;
} else if (result != RETURN_OK) {
return result;
}
if (type == 0) {
//Check if lastTest has no children, otherwise, delete them,
//as a more general check is requested.
if (lastTest.left() != this->end()) {
removeElementAndAllChildren(lastTest.left());
}
return RETURN_OK;
}
//Type insertion required.
result = findOrInsertMatch<TmPacketMinimal*, ServiceMatcher>(
lastTest.left(), &testPacket, &lastTest);
if (result == NEW_NODE_CREATED) {
if (rollback == this->end()) {
rollback = lastTest;
}
} else if (result != RETURN_OK) {
if (rollback != this->end()) {
removeElementAndAllChildren(rollback);
}
return result;
}
if (subtype == 0) {
if (lastTest.left() != this->end()) {
//See above
removeElementAndAllChildren(lastTest.left());
}
return RETURN_OK;
}
//Subtype insertion required.
result = findOrInsertMatch<TmPacketMinimal*, SubServiceMatcher>(
lastTest.left(), &testPacket, &lastTest);
if (result == NEW_NODE_CREATED) {
return RETURN_OK;
} else if (result != RETURN_OK) {
if (rollback != this->end()) {
removeElementAndAllChildren(rollback);
}
return result;
}
return RETURN_OK;
}
template<typename VALUE_T, typename INSERTION_T>
ReturnValue_t PacketMatchTree::findOrInsertMatch(iterator startAt, VALUE_T test,
iterator* lastTest) {
bool attachToBranch = AND;
iterator iter = startAt;
while (iter != this->end()) {
bool isMatch = iter->match(test);
attachToBranch = OR;
*lastTest = iter;
if (isMatch) {
return RETURN_OK;
} else {
//Go down OR branch.
iter = iter.right();
}
}
//Only reached if nothing was found.
SerializeableMatcherIF<VALUE_T>* newContent = factory.generate<INSERTION_T>(
test);
if (newContent == NULL) {
return FULL;
}
Node* newNode = factory.generate<Node>(newContent);
if (newNode == NULL) {
//Need to make sure partially generated content is deleted, otherwise, that's a leak.
factory.destroy<INSERTION_T>(static_cast<INSERTION_T*>(newContent));
return FULL;
}
*lastTest = insert(attachToBranch, *lastTest, newNode);
if (*lastTest == end()) {
//This actaully never fails, so creating a dedicated returncode seems an overshoot.
return RETURN_FAILED;
}
return NEW_NODE_CREATED;
iterator* lastTest) {
bool attachToBranch = AND;
iterator iter = startAt;
while (iter != this->end()) {
bool isMatch = iter->match(test);
attachToBranch = OR;
*lastTest = iter;
if (isMatch) {
return RETURN_OK;
} else {
//Go down OR branch.
iter = iter.right();
}
}
//Only reached if nothing was found.
SerializeableMatcherIF<VALUE_T>* newContent = factory.generate<INSERTION_T>(
test);
if (newContent == NULL) {
return FULL;
}
Node* newNode = factory.generate<Node>(newContent);
if (newNode == NULL) {
//Need to make sure partially generated content is deleted, otherwise, that's a leak.
factory.destroy<INSERTION_T>(static_cast<INSERTION_T*>(newContent));
return FULL;
}
*lastTest = insert(attachToBranch, *lastTest, newNode);
if (*lastTest == end()) {
//This actaully never fails, so creating a dedicated returncode seems an overshoot.
return RETURN_FAILED;
}
return NEW_NODE_CREATED;
}
ReturnValue_t PacketMatchTree::removeMatch(uint16_t apid, uint8_t type,
uint8_t subtype) {
TmPacketMinimal::TmPacketMinimalPointer data;
data.data_field.service_type = type;
data.data_field.service_subtype = subtype;
TmPacketMinimal testPacket((uint8_t*) &data);
testPacket.setAPID(apid);
iterator foundElement = findMatch(begin(), &testPacket);
if (foundElement == this->end()) {
return NO_MATCH;
}
if (type == 0) {
if (foundElement.left() == end()) {
return removeElementAndReconnectChildren(foundElement);
} else {
return TOO_GENERAL_REQUEST;
}
}
//Go down AND branch. Will abort if empty.
foundElement = findMatch(foundElement.left(), &testPacket);
if (foundElement == this->end()) {
return NO_MATCH;
}
if (subtype == 0) {
if (foundElement.left() == end()) {
return removeElementAndReconnectChildren(foundElement);
} else {
return TOO_GENERAL_REQUEST;
}
}
//Again, go down AND branch.
foundElement = findMatch(foundElement.left(), &testPacket);
if (foundElement == end()) {
return NO_MATCH;
}
return removeElementAndReconnectChildren(foundElement);
uint8_t subtype) {
TmPacketMinimal::TmPacketMinimalPointer data;
data.data_field.service_type = type;
data.data_field.service_subtype = subtype;
TmPacketMinimal testPacket((uint8_t*) &data);
testPacket.setAPID(apid);
iterator foundElement = findMatch(begin(), &testPacket);
if (foundElement == this->end()) {
return NO_MATCH;
}
if (type == 0) {
if (foundElement.left() == end()) {
return removeElementAndReconnectChildren(foundElement);
} else {
return TOO_GENERAL_REQUEST;
}
}
//Go down AND branch. Will abort if empty.
foundElement = findMatch(foundElement.left(), &testPacket);
if (foundElement == this->end()) {
return NO_MATCH;
}
if (subtype == 0) {
if (foundElement.left() == end()) {
return removeElementAndReconnectChildren(foundElement);
} else {
return TOO_GENERAL_REQUEST;
}
}
//Again, go down AND branch.
foundElement = findMatch(foundElement.left(), &testPacket);
if (foundElement == end()) {
return NO_MATCH;
}
return removeElementAndReconnectChildren(foundElement);
}
PacketMatchTree::iterator PacketMatchTree::findMatch(iterator startAt,
TmPacketMinimal* test) {
iterator iter = startAt;
while (iter != end()) {
bool isMatch = iter->match(test);
if (isMatch) {
break;
} else {
iter = iter.right(); //next OR element
}
}
return iter;
TmPacketMinimal* test) {
iterator iter = startAt;
while (iter != end()) {
bool isMatch = iter->match(test);
if (isMatch) {
break;
} else {
iter = iter.right(); //next OR element
}
}
return iter;
}
ReturnValue_t PacketMatchTree::initialize() {
return factoryBackend.initialize();
return factoryBackend.initialize();
}
ReturnValue_t PacketMatchTree::changeMatch(bool addToMatch, uint16_t apid,
uint8_t type, uint8_t subtype) {
if (addToMatch) {
return addMatch(apid, type, subtype);
} else {
return removeMatch(apid, type, subtype);
}
uint8_t type, uint8_t subtype) {
if (addToMatch) {
return addMatch(apid, type, subtype);
} else {
return removeMatch(apid, type, subtype);
}
}
ReturnValue_t PacketMatchTree::cleanUpElement(iterator position) {
factory.destroy(position.element->value);
//Go on anyway, there's nothing we can do.
//SHOULDDO: Throw event, or write debug message?
return factory.destroy(position.element);
factory.destroy(position.element->value);
//Go on anyway, there's nothing we can do.
//SHOULDDO: Throw event, or write debug message?
return factory.destroy(position.element);
}

View File

@ -1,5 +1,5 @@
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_
#ifndef FSFW_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_
#define FSFW_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_
#include "../../container/PlacementFactory.h"
#include "../../globalfunctions/matching/MatchTree.h"
@ -8,29 +8,29 @@
class PacketMatchTree: public MatchTree<TmPacketMinimal*>, public HasReturnvaluesIF {
public:
PacketMatchTree(Node* root);
PacketMatchTree(iterator root);
PacketMatchTree();
virtual ~PacketMatchTree();
ReturnValue_t changeMatch(bool addToMatch, uint16_t apid, uint8_t type = 0,
uint8_t subtype = 0);
ReturnValue_t addMatch(uint16_t apid, uint8_t type = 0,
uint8_t subtype = 0);
ReturnValue_t removeMatch(uint16_t apid, uint8_t type = 0,
uint8_t subtype = 0);
ReturnValue_t initialize();
PacketMatchTree(Node* root);
PacketMatchTree(iterator root);
PacketMatchTree();
virtual ~PacketMatchTree();
ReturnValue_t changeMatch(bool addToMatch, uint16_t apid, uint8_t type = 0,
uint8_t subtype = 0);
ReturnValue_t addMatch(uint16_t apid, uint8_t type = 0,
uint8_t subtype = 0);
ReturnValue_t removeMatch(uint16_t apid, uint8_t type = 0,
uint8_t subtype = 0);
ReturnValue_t initialize();
protected:
ReturnValue_t cleanUpElement(iterator position);
ReturnValue_t cleanUpElement(iterator position);
private:
static const uint8_t N_POOLS = 4;
LocalPool factoryBackend;
PlacementFactory factory;
static const LocalPool::LocalPoolConfig poolConfig;
static const uint16_t POOL_SIZES[N_POOLS];
static const uint16_t N_ELEMENTS[N_POOLS];
template<typename VALUE_T, typename INSERTION_T>
ReturnValue_t findOrInsertMatch(iterator startAt, VALUE_T test, iterator* lastTest);
iterator findMatch(iterator startAt, TmPacketMinimal* test);
static const uint8_t N_POOLS = 4;
LocalPool factoryBackend;
PlacementFactory factory;
static const LocalPool::LocalPoolConfig poolConfig;
static const uint16_t POOL_SIZES[N_POOLS];
static const uint16_t N_ELEMENTS[N_POOLS];
template<typename VALUE_T, typename INSERTION_T>
ReturnValue_t findOrInsertMatch(iterator startAt, VALUE_T test, iterator* lastTest);
iterator findMatch(iterator startAt, TmPacketMinimal* test);
};
#endif /* FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_ */

View File

@ -7,32 +7,32 @@
class ServiceMatcher: public SerializeableMatcherIF<TmPacketMinimal*> {
private:
uint8_t service;
uint8_t service;
public:
ServiceMatcher(uint8_t setService) :
service(setService) {
}
ServiceMatcher(TmPacketMinimal* test) :
service(test->getService()) {
}
bool match(TmPacketMinimal* packet) {
if (packet->getService() == service) {
return true;
} else {
return false;
}
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
return SerializeAdapter::serialize(&service, buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&service);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&service, buffer, size, streamEndianness);
}
ServiceMatcher(uint8_t setService) :
service(setService) {
}
ServiceMatcher(TmPacketMinimal* test) :
service(test->getService()) {
}
bool match(TmPacketMinimal* packet) {
if (packet->getService() == service) {
return true;
} else {
return false;
}
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
return SerializeAdapter::serialize(&service, buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&service);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&service, buffer, size, streamEndianness);
}
};

View File

@ -1,5 +1,5 @@
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_
#ifndef FSFW_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_
#define FSFW_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_
#include "../../globalfunctions/matching/SerializeableMatcherIF.h"
#include "../../serialize/SerializeAdapter.h"
@ -7,32 +7,32 @@
class SubServiceMatcher: public SerializeableMatcherIF<TmPacketMinimal*> {
public:
SubServiceMatcher(uint8_t subService) :
subService(subService) {
}
SubServiceMatcher(TmPacketMinimal* test) :
subService(test->getSubService()) {
}
bool match(TmPacketMinimal* packet) {
if (packet->getSubService() == subService) {
return true;
} else {
return false;
}
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
return SerializeAdapter::serialize(&subService, buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&subService);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&subService, buffer, size, streamEndianness);
}
SubServiceMatcher(uint8_t subService) :
subService(subService) {
}
SubServiceMatcher(TmPacketMinimal* test) :
subService(test->getSubService()) {
}
bool match(TmPacketMinimal* packet) {
if (packet->getSubService() == subService) {
return true;
} else {
return false;
}
}
ReturnValue_t serialize(uint8_t** buffer, size_t* size,
size_t maxSize, Endianness streamEndianness) const {
return SerializeAdapter::serialize(&subService, buffer, size, maxSize, streamEndianness);
}
size_t getSerializedSize() const {
return SerializeAdapter::getSerializedSize(&subService);
}
ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) {
return SerializeAdapter::deSerialize(&subService, buffer, size, streamEndianness);
}
private:
uint8_t subService;
uint8_t subService;
};

View File

@ -19,114 +19,114 @@ class TcPacketBase : public SpacePacketBase {
friend class TcPacketStoredBase;
public:
enum AckField {
//! No acknowledgements are expected.
ACK_NONE = 0b0000,
//! Acknowledgements on acceptance are expected.
ACK_ACCEPTANCE = 0b0001,
//! Acknowledgements on start are expected.
ACK_START = 0b0010,
//! Acknowledgements on step are expected.
ACK_STEP = 0b0100,
//! Acknowledfgement on completion are expected.
ACK_COMPLETION = 0b1000
};
enum AckField {
//! No acknowledgements are expected.
ACK_NONE = 0b0000,
//! Acknowledgements on acceptance are expected.
ACK_ACCEPTANCE = 0b0001,
//! Acknowledgements on start are expected.
ACK_START = 0b0010,
//! Acknowledgements on step are expected.
ACK_STEP = 0b0100,
//! Acknowledfgement on completion are expected.
ACK_COMPLETION = 0b1000
};
static constexpr uint8_t ACK_ALL = ACK_ACCEPTANCE | ACK_START | ACK_STEP |
ACK_COMPLETION;
static constexpr uint8_t ACK_ALL = ACK_ACCEPTANCE | ACK_START | ACK_STEP |
ACK_COMPLETION;
/**
* This is the default constructor.
* It sets its internal data pointer to the address passed and also
* forwards the data pointer to the parent SpacePacketBase class.
* @param setData The position where the packet data lies.
*/
TcPacketBase( const uint8_t* setData );
/**
* This is the empty default destructor.
*/
virtual ~TcPacketBase();
/**
* This is the default constructor.
* It sets its internal data pointer to the address passed and also
* forwards the data pointer to the parent SpacePacketBase class.
* @param setData The position where the packet data lies.
*/
TcPacketBase( const uint8_t* setData );
/**
* This is the empty default destructor.
*/
virtual ~TcPacketBase();
/**
* This command returns the CCSDS Secondary Header Flag.
* It shall always be zero for PUS Packets. This is the
* highest bit of the first byte of the Data Field Header.
* @return the CCSDS Secondary Header Flag
*/
virtual uint8_t getSecondaryHeaderFlag() const = 0;
/**
* This command returns the TC Packet PUS Version Number.
* The version number of ECSS PUS 2003 is 1.
* It consists of the second to fourth highest bits of the
* first byte.
* @return
*/
virtual uint8_t getPusVersionNumber() const = 0;
/**
* This is a getter for the packet's Ack field, which are the lowest four
* bits of the first byte of the Data Field Header.
*
* It is packed in a uint8_t variable.
* @return The packet's PUS Ack field.
*/
virtual uint8_t getAcknowledgeFlags() const = 0;
/**
* This is a getter for the packet's PUS Service ID, which is the second
* byte of the Data Field Header.
* @return The packet's PUS Service ID.
*/
virtual uint8_t getService() const = 0;
/**
* This is a getter for the packet's PUS Service Subtype, which is the
* third byte of the Data Field Header.
* @return The packet's PUS Service Subtype.
*/
virtual uint8_t getSubService() const = 0;
/**
* The source ID can be used to have an additional identifier, e.g. for different ground
* station.
* @return
*/
virtual uint16_t getSourceId() const = 0;
/**
* This command returns the CCSDS Secondary Header Flag.
* It shall always be zero for PUS Packets. This is the
* highest bit of the first byte of the Data Field Header.
* @return the CCSDS Secondary Header Flag
*/
virtual uint8_t getSecondaryHeaderFlag() const = 0;
/**
* This command returns the TC Packet PUS Version Number.
* The version number of ECSS PUS 2003 is 1.
* It consists of the second to fourth highest bits of the
* first byte.
* @return
*/
virtual uint8_t getPusVersionNumber() const = 0;
/**
* This is a getter for the packet's Ack field, which are the lowest four
* bits of the first byte of the Data Field Header.
*
* It is packed in a uint8_t variable.
* @return The packet's PUS Ack field.
*/
virtual uint8_t getAcknowledgeFlags() const = 0;
/**
* This is a getter for the packet's PUS Service ID, which is the second
* byte of the Data Field Header.
* @return The packet's PUS Service ID.
*/
virtual uint8_t getService() const = 0;
/**
* This is a getter for the packet's PUS Service Subtype, which is the
* third byte of the Data Field Header.
* @return The packet's PUS Service Subtype.
*/
virtual uint8_t getSubService() const = 0;
/**
* The source ID can be used to have an additional identifier, e.g. for different ground
* station.
* @return
*/
virtual uint16_t getSourceId() const = 0;
/**
* This is a getter for a pointer to the packet's Application data.
*
* These are the bytes that follow after the Data Field Header. They form
* the packet's application data.
* @return A pointer to the PUS Application Data.
*/
virtual const uint8_t* getApplicationData() const = 0;
/**
* This method calculates the size of the PUS Application data field.
*
* It takes the information stored in the CCSDS Packet Data Length field
* and subtracts the Data Field Header size and the CRC size.
* @return The size of the PUS Application Data (without Error Control
* field)
*/
virtual uint16_t getApplicationDataSize() const = 0;
/**
* This getter returns the Error Control Field of the packet.
*
* The field is placed after any possible Application Data. If no
* Application Data is present there's still an Error Control field. It is
* supposed to be a 16bit-CRC.
* @return The PUS Error Control
*/
virtual uint16_t getErrorControl() const = 0;
/**
* With this method, the Error Control Field is updated to match the
* current content of the packet.
*/
virtual void setErrorControl() = 0;
/**
* This is a getter for a pointer to the packet's Application data.
*
* These are the bytes that follow after the Data Field Header. They form
* the packet's application data.
* @return A pointer to the PUS Application Data.
*/
virtual const uint8_t* getApplicationData() const = 0;
/**
* This method calculates the size of the PUS Application data field.
*
* It takes the information stored in the CCSDS Packet Data Length field
* and subtracts the Data Field Header size and the CRC size.
* @return The size of the PUS Application Data (without Error Control
* field)
*/
virtual uint16_t getApplicationDataSize() const = 0;
/**
* This getter returns the Error Control Field of the packet.
*
* The field is placed after any possible Application Data. If no
* Application Data is present there's still an Error Control field. It is
* supposed to be a 16bit-CRC.
* @return The PUS Error Control
*/
virtual uint16_t getErrorControl() const = 0;
/**
* With this method, the Error Control Field is updated to match the
* current content of the packet.
*/
virtual void setErrorControl() = 0;
/**
* Calculate full packet length from application data length.
* @param appDataLen
* @return
*/
virtual size_t calculateFullPacketLength(size_t appDataLen) const = 0;
/**
* Calculate full packet length from application data length.
* @param appDataLen
* @return
*/
virtual size_t calculateFullPacketLength(size_t appDataLen) const = 0;
/**
* This is a debugging helper method that prints the whole packet content

View File

@ -18,32 +18,32 @@ TcPacketStoredBase::~TcPacketStoredBase() {
}
ReturnValue_t TcPacketStoredBase::getData(const uint8_t ** dataPtr,
size_t* dataSize) {
auto result = this->store->getData(storeAddress, dataPtr, dataSize);
if(result != HasReturnvaluesIF::RETURN_OK) {
size_t* dataSize) {
auto result = this->store->getData(storeAddress, dataPtr, dataSize);
if(result != HasReturnvaluesIF::RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "TcPacketStoredBase: Could not get data!" << std::endl;
sif::warning << "TcPacketStoredBase: Could not get data!" << std::endl;
#else
sif::printWarning("TcPacketStoredBase: Could not get data!\n");
sif::printWarning("TcPacketStoredBase: Could not get data!\n");
#endif
}
return result;
}
return result;
}
bool TcPacketStoredBase::checkAndSetStore() {
if (this->store == nullptr) {
this->store = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (this->store == nullptr) {
if (this->store == nullptr) {
this->store = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
if (this->store == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found!"
<< std::endl;
sif::error << "TcPacketStoredBase::TcPacketStoredBase: TC Store not found!"
<< std::endl;
#endif
return false;
}
}
return true;
return false;
}
}
return true;
}
void TcPacketStoredBase::setStoreAddress(store_address_t setAddress) {
@ -68,5 +68,5 @@ void TcPacketStoredBase::setStoreAddress(store_address_t setAddress) {
}
store_address_t TcPacketStoredBase::getStoreAddress() {
return this->storeAddress;
return this->storeAddress;
}

View File

@ -34,35 +34,35 @@ public:
*/
TcPacketStoredBase(const uint8_t* data, uint32_t size);
virtual~ TcPacketStoredBase();
virtual~ TcPacketStoredBase();
/**
* Getter function for the raw data.
* @param dataPtr [out] Pointer to the data pointer to set
* @param dataSize [out] Address of size to set.
* @return -@c RETURN_OK if data was retrieved successfully.
*/
ReturnValue_t getData(const uint8_t ** dataPtr, size_t* dataSize) override;
/**
* Getter function for the raw data.
* @param dataPtr [out] Pointer to the data pointer to set
* @param dataSize [out] Address of size to set.
* @return -@c RETURN_OK if data was retrieved successfully.
*/
ReturnValue_t getData(const uint8_t ** dataPtr, size_t* dataSize) override;
void setStoreAddress(store_address_t setAddress) override;
store_address_t getStoreAddress() override;
/**
* With this call, the packet is deleted.
* It removes itself from the store and sets its data pointer to NULL.
* @return returncode from deleting the data.
*/
virtual ReturnValue_t deletePacket() = 0;
/**
* With this call, the packet is deleted.
* It removes itself from the store and sets its data pointer to NULL.
* @return returncode from deleting the data.
*/
virtual ReturnValue_t deletePacket() = 0;
/**
* This method performs a size check.
* It reads the stored size and compares it with the size entered in the
* packet header. This class is the optimal place for such a check as it
* has access to both the header data and the store.
* @return true if size is correct, false if packet is not registered in
* store or size is incorrect.
*/
virtual bool isSizeCorrect() = 0;
/**
* This method performs a size check.
* It reads the stored size and compares it with the size entered in the
* packet header. This class is the optimal place for such a check as it
* has access to both the header data and the store.
* @return true if size is correct, false if packet is not registered in
* store or size is incorrect.
*/
virtual bool isSizeCorrect() = 0;
protected:
/**

View File

@ -11,9 +11,7 @@
TimeStamperIF* TmPacketBase::timeStamper = nullptr;
object_id_t TmPacketBase::timeStamperId = objects::NO_OBJECT;
TmPacketBase::TmPacketBase(uint8_t* setData):
SpacePacketBase(setData) {
}
TmPacketBase::TmPacketBase(uint8_t* setData): SpacePacketBase(setData) {}
TmPacketBase::~TmPacketBase() {
//Nothing to do.

View File

@ -23,7 +23,7 @@ struct PUSTmDataFieldHeaderPusA {
uint8_t service_type;
uint8_t service_subtype;
uint8_t subcounter;
// uint8_t destination;
// uint8_t destination;
uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
};
@ -51,8 +51,7 @@ public:
static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) +
sizeof(PUSTmDataFieldHeaderPusA) + 2);
//! Maximum size of a TM Packet in this mission.
//! TODO: Make this dependant on a config variable.
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048;
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = fsfwconfig::FSFW_MAX_TM_PACKET_SIZE;
/**
* This is the default constructor.

View File

@ -53,8 +53,7 @@ public:
static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) +
sizeof(PUSTmDataFieldHeaderPusC) + 2);
//! Maximum size of a TM Packet in this mission.
//! TODO: Make this dependant on a config variable.
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048;
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = fsfwconfig::FSFW_MAX_TM_PACKET_SIZE;
/**
* This is the default constructor.