updating code from Flying Laptop
This is the framework of Flying Laptop OBSW version A.13.0.
This commit is contained in:
@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# OSAL makefile
|
||||
#
|
||||
# Created on: Mar 04, 2010
|
||||
# Author: ziemke
|
||||
# Author: Claas Ziemke
|
||||
# Copyright 2010, Claas Ziemke <claas.ziemke@gmx.net>
|
||||
#
|
||||
|
||||
BASEDIR=../../
|
||||
include $(BASEDIR)options.mk
|
||||
|
||||
OBJ = $(BUILDDIR)/SpacePacketBase.o \
|
||||
$(BUILDDIR)/SpacePacket.o
|
||||
|
||||
|
||||
all: $(OBJ)
|
||||
|
||||
$(BUILDDIR)/%.o: %.cpp %.h
|
||||
$(CPP) $(CFLAGS) $(DEFINES) $(CCOPT) ${INCLUDE} -c $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.gcno *.gcda
|
@ -1,28 +1,16 @@
|
||||
/*
|
||||
* SpacePacket.cpp
|
||||
*
|
||||
* Created on: Mar 23, 2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/ccsds_header.h>
|
||||
#include <framework/tmtcpacket/SpacePacket.h>
|
||||
#include <string.h>
|
||||
|
||||
SpacePacket::SpacePacket( uint16_t set_packet_data_length, uint8_t set_type, uint16_t new_apid, uint16_t set_count ):
|
||||
SpacePacketBase( (uint8_t*)&this->local_data ) {
|
||||
//reset everything to zero:
|
||||
memset(this->local_data.byteStream,0 , sizeof(this->local_data.byteStream) );
|
||||
//Primary header:
|
||||
this->local_data.fields.header.packet_id_h = 0b00000000 + ( (set_type & 0b1) << 4 );
|
||||
this->setAPID( new_apid );
|
||||
this->local_data.fields.header.sequence_control_h = 0b11000000;
|
||||
this->setPacketSequenceCount(set_count);
|
||||
if ( set_packet_data_length <= sizeof(this->local_data.fields.buffer) ) {
|
||||
this->setPacketDataLength(set_packet_data_length);
|
||||
SpacePacket::SpacePacket( uint16_t packetDataLength, bool isTelecommand, uint16_t apid, uint16_t sequenceCount ):
|
||||
SpacePacketBase( (uint8_t*)&this->localData ) {
|
||||
initSpacePacketHeader(isTelecommand, false, apid, sequenceCount);
|
||||
this->setPacketSequenceCount(sequenceCount);
|
||||
if ( packetDataLength <= sizeof(this->localData.fields.buffer) ) {
|
||||
this->setPacketDataLength(packetDataLength);
|
||||
} else {
|
||||
this->setPacketDataLength( sizeof(this->local_data.fields.buffer) );
|
||||
this->setPacketDataLength( sizeof(this->localData.fields.buffer) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +19,7 @@ SpacePacket::~SpacePacket( void ) {
|
||||
|
||||
bool SpacePacket::addWholeData( const uint8_t* p_Data, uint32_t packet_size ) {
|
||||
if ( packet_size <= sizeof(this->data) ) {
|
||||
memcpy( &this->local_data.byteStream, p_Data, packet_size );
|
||||
memcpy( &this->localData.byteStream, p_Data, packet_size );
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -13,21 +13,19 @@
|
||||
* so the parent's methods are reachable.
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
class SpacePacket : public SpacePacketBase {
|
||||
public:
|
||||
static const uint16_t PACKET_MAX_SIZE = 1024;
|
||||
class SpacePacket: public SpacePacketBase {
|
||||
public:
|
||||
static const uint16_t PACKET_MAX_SIZE = 1024;
|
||||
/**
|
||||
* The constructor initializes the packet and sets all header information
|
||||
* according to the passed parameters.
|
||||
* @param set_packet_data_length Sets the packet data length field and
|
||||
* therefore specifies the size of the packet.
|
||||
* @param set_type Sets the packet type field to either 0 (TM) or 1 (TC).
|
||||
* @param set_apid Sets the packet's APID field. The default value
|
||||
* describes an idle packet.
|
||||
* @param set_sequence_count Sets the packet's Source Sequence Count
|
||||
* field.
|
||||
* @param packetDataLength Sets the packet data length field and therefore specifies the size of the packet.
|
||||
* @param isTelecommand Sets the packet type field to either TC (true) or TM (false).
|
||||
* @param apid Sets the packet's APID field. The default value describes an idle packet.
|
||||
* @param sequenceCount ets the packet's Source Sequence Count field.
|
||||
*/
|
||||
SpacePacket( uint16_t set_packet_data_length, uint8_t set_type = 0, uint16_t set_apid = APID_IDLE_PACKET, uint16_t set_sequence_count = 0 );
|
||||
SpacePacket(uint16_t packetDataLength, bool isTelecommand = false,
|
||||
uint16_t apid = APID_IDLE_PACKET, uint16_t sequenceCount = 0);
|
||||
/**
|
||||
* The class's default destructor.
|
||||
*/
|
||||
@ -40,7 +38,7 @@ class SpacePacket : public SpacePacketBase {
|
||||
* @return @li \c true if packet_size is smaller than \c MAX_PACKET_SIZE.
|
||||
* @li \c false else.
|
||||
*/
|
||||
bool addWholeData( const uint8_t* p_data, uint32_t packet_size );
|
||||
bool addWholeData(const uint8_t* p_data, uint32_t packet_size);
|
||||
protected:
|
||||
/**
|
||||
* This structure defines the data structure of a Space Packet as local data.
|
||||
@ -66,7 +64,7 @@ protected:
|
||||
* packed in an union, so the data can be accessed as a byte stream without
|
||||
* a cast.
|
||||
*/
|
||||
SpacePacketData local_data;
|
||||
SpacePacketData localData;
|
||||
};
|
||||
|
||||
#endif /* SPACEPACKET_H_ */
|
||||
|
@ -1,11 +1,7 @@
|
||||
/*
|
||||
* SpacePacketBase.cpp
|
||||
*
|
||||
* Created on: 21.03.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/SpacePacketBase.h>
|
||||
#include <string.h>
|
||||
|
||||
SpacePacketBase::SpacePacketBase( const uint8_t* set_address ) {
|
||||
this->data = (SpacePacketPointer*) set_address;
|
||||
}
|
||||
@ -18,6 +14,20 @@ uint8_t SpacePacketBase::getPacketVersionNumber( void ) {
|
||||
return (this->data->header.packet_id_h & 0b11100000) >> 5;
|
||||
}
|
||||
|
||||
void SpacePacketBase::initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount) {
|
||||
//reset header to zero:
|
||||
memset(data,0, sizeof(this->data->header) );
|
||||
//Set TC/TM bit.
|
||||
data->header.packet_id_h = ((isTelecommand? 1 : 0)) << 4;
|
||||
//Set secondaryHeader bit
|
||||
data->header.packet_id_h |= ((hasSecondaryHeader? 1 : 0)) << 3;
|
||||
this->setAPID( apid );
|
||||
//Always initialize as standalone packets.
|
||||
data->header.sequence_control_h = 0b11000000;
|
||||
setPacketSequenceCount(sequenceCount);
|
||||
|
||||
}
|
||||
|
||||
bool SpacePacketBase::isTelecommand( void ) {
|
||||
return (this->data->header.packet_id_h & 0b00010000) >> 4;
|
||||
}
|
||||
@ -31,7 +41,7 @@ uint16_t SpacePacketBase::getPacketId() {
|
||||
this->data->header.packet_id_l;
|
||||
}
|
||||
|
||||
uint16_t SpacePacketBase::getAPID( void ) {
|
||||
uint16_t SpacePacketBase::getAPID( void ) const {
|
||||
return ( (this->data->header.packet_id_h & 0b00000111) << 8 ) +
|
||||
this->data->header.packet_id_l;
|
||||
}
|
||||
@ -51,7 +61,7 @@ uint8_t SpacePacketBase::getSequenceFlags( void ) {
|
||||
return (this->data->header.sequence_control_h & 0b11000000) >> 6 ;
|
||||
}
|
||||
|
||||
uint16_t SpacePacketBase::getPacketSequenceCount( void ) {
|
||||
uint16_t SpacePacketBase::getPacketSequenceCount( void ) const {
|
||||
return ( (this->data->header.sequence_control_h & 0b00111111) << 8 )
|
||||
+ this->data->header.sequence_control_l;
|
||||
}
|
||||
@ -83,3 +93,11 @@ uint8_t* SpacePacketBase::getWholeData() {
|
||||
void SpacePacketBase::setData( const uint8_t* p_Data ) {
|
||||
this->data = (SpacePacketPointer*)p_Data;
|
||||
}
|
||||
|
||||
uint32_t SpacePacketBase::getApidAndSequenceCount() const {
|
||||
return (getAPID() << 16) + getPacketSequenceCount();
|
||||
}
|
||||
|
||||
uint8_t* SpacePacketBase::getPacketData() {
|
||||
return &(data->packet_data);
|
||||
}
|
||||
|
@ -80,6 +80,8 @@ public:
|
||||
* @return Returns true if the bit is set and false if not.
|
||||
*/
|
||||
bool isTelecommand( void );
|
||||
|
||||
void initSpacePacketHeader(bool isTelecommand, bool hasSecondaryHeader, uint16_t apid, uint16_t sequenceCount = 0);
|
||||
/**
|
||||
* The CCSDS header provides a secondary header flag (the fifth-highest bit),
|
||||
* which is checked with this method.
|
||||
@ -97,7 +99,7 @@ public:
|
||||
* id.
|
||||
* @return The CCSDS APID.
|
||||
*/
|
||||
uint16_t getAPID( void );
|
||||
uint16_t getAPID( void ) const;
|
||||
/**
|
||||
* Sets the APID of a packet, which are the lowest 11 bit of the packet
|
||||
* id.
|
||||
@ -122,7 +124,7 @@ public:
|
||||
* packet sequence control field.
|
||||
* @return The CCSDS sequence count.
|
||||
*/
|
||||
uint16_t getPacketSequenceCount( void );
|
||||
uint16_t getPacketSequenceCount( void ) const;
|
||||
/**
|
||||
* Sets the packet sequence count, which are the lowest 14 bit of the
|
||||
* packet sequence control field.
|
||||
@ -153,6 +155,8 @@ public:
|
||||
* @return A \c uint8_t pointer to the first byte of the CCSDS primary header.
|
||||
*/
|
||||
virtual uint8_t* getWholeData( void );
|
||||
|
||||
uint8_t* getPacketData();
|
||||
/**
|
||||
* With this method, the packet data pointer can be redirected to another
|
||||
* location.
|
||||
@ -165,6 +169,8 @@ public:
|
||||
*/
|
||||
uint32_t getFullSize();
|
||||
|
||||
uint32_t getApidAndSequenceCount() const;
|
||||
|
||||
};
|
||||
|
||||
#endif /* SPACEPACKETBASE_H_ */
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* ApidMatcher.h
|
||||
*
|
||||
* Created on: 09.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_
|
||||
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_APIDMATCHER_H_
|
||||
|
||||
@ -19,6 +12,9 @@ public:
|
||||
ApidMatcher(uint16_t setApid) :
|
||||
apid(setApid) {
|
||||
}
|
||||
ApidMatcher(TmPacketMinimal* test) :
|
||||
apid(test->getAPID()) {
|
||||
}
|
||||
bool match(TmPacketMinimal* packet) {
|
||||
if (packet->getAPID() == apid) {
|
||||
return true;
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* PacketMatchTree.cpp
|
||||
*
|
||||
* Created on: 10.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/tmtcpacket/packetmatcher/ApidMatcher.h>
|
||||
#include <framework/tmtcpacket/packetmatcher/PacketMatchTree.h>
|
||||
#include <framework/tmtcpacket/packetmatcher/ServiceMatcher.h>
|
||||
@ -31,116 +24,148 @@ PacketMatchTree::~PacketMatchTree() {
|
||||
ReturnValue_t PacketMatchTree::addMatch(uint16_t apid, uint8_t type,
|
||||
uint8_t subtype) {
|
||||
//We assume adding APID is always requested.
|
||||
uint8_t expectedHierarchy = 0;
|
||||
if (type != 0) {
|
||||
expectedHierarchy++;
|
||||
if (subtype != 0) {
|
||||
expectedHierarchy++;
|
||||
}
|
||||
}
|
||||
TmPacketMinimal::TmPacketMinimalPointer data;
|
||||
data.data_field.service_type = type;
|
||||
data.data_field.service_subtype = subtype;
|
||||
TmPacketMinimal testPacket((uint8_t*)&data);
|
||||
TmPacketMinimal testPacket((uint8_t*) &data);
|
||||
testPacket.setAPID(apid);
|
||||
uint8_t realHierarchy = 0;
|
||||
iterator lastMatch;
|
||||
bool isInTree = matchesTree(&testPacket, &lastMatch, &realHierarchy);
|
||||
if (isInTree) {
|
||||
//Matches somehow.
|
||||
//TODO: Are we interested in details?
|
||||
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;
|
||||
}
|
||||
if (expectedHierarchy == realHierarchy) {
|
||||
//Add another element (of correct type) at the OR branch.
|
||||
lastMatch = addElement(OR, realHierarchy, lastMatch, &testPacket);
|
||||
if (lastMatch == this->end()) {
|
||||
return FULL;
|
||||
//Type insertion required.
|
||||
result = findOrInsertMatch<TmPacketMinimal*, ServiceMatcher>(
|
||||
lastTest.left(), &testPacket, &lastTest);
|
||||
if (result == NEW_NODE_CREATED) {
|
||||
if (rollback == this->end()) {
|
||||
rollback = lastTest;
|
||||
}
|
||||
} else if (expectedHierarchy > realHierarchy) {
|
||||
//A certain amount of downward structure does not exist. Add first element as OR, rest as AND.
|
||||
|
||||
lastMatch = addElement(OR, realHierarchy, lastMatch, &testPacket);
|
||||
if (lastMatch == end()) {
|
||||
return FULL;
|
||||
} else if (result != RETURN_OK) {
|
||||
if (rollback != this->end()) {
|
||||
removeElementAndAllChildren(rollback);
|
||||
}
|
||||
iterator firstOfList = lastMatch;
|
||||
while (lastMatch != end() && realHierarchy < expectedHierarchy) {
|
||||
realHierarchy++;
|
||||
lastMatch = addElement(AND, realHierarchy, lastMatch, &testPacket);
|
||||
return result;
|
||||
}
|
||||
if (subtype == 0) {
|
||||
if (lastTest.left() != this->end()) {
|
||||
//See above
|
||||
removeElementAndAllChildren(lastTest.left());
|
||||
}
|
||||
if (lastMatch == end()) {
|
||||
//At least one element could not be inserted. So delete everything.
|
||||
removeElementAndAllChildren(firstOfList);
|
||||
return FULL;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
//Might work like that.
|
||||
//Too detailed match, delete the last element and all its children.
|
||||
while (lastMatch.up() != end() && lastMatch.up().left() != lastMatch) {
|
||||
lastMatch = lastMatch.up();
|
||||
}
|
||||
removeElementAndAllChildren(lastMatch);
|
||||
return result;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PacketMatchTree::removeMatch(uint16_t apid, uint8_t type,
|
||||
uint8_t subtype) {
|
||||
//We assume APID is always in request.
|
||||
uint8_t expectedHierarchy = 1;
|
||||
if (type != 0) {
|
||||
expectedHierarchy++;
|
||||
if (subtype != 0) {
|
||||
expectedHierarchy++;
|
||||
}
|
||||
}
|
||||
TmPacketMinimal::TmPacketMinimalPointer data;
|
||||
data.data_field.service_type = type;
|
||||
data.data_field.service_subtype = subtype;
|
||||
TmPacketMinimal testPacket((uint8_t*)&data);
|
||||
testPacket.setAPID(apid);
|
||||
uint8_t realHierarchy = 0;
|
||||
iterator lastMatch;
|
||||
bool isInTree = matchesTree(&testPacket, &lastMatch, &realHierarchy);
|
||||
if (isInTree) {
|
||||
if (expectedHierarchy == realHierarchy) {
|
||||
return removeElementAndReconnectChildren(lastMatch);
|
||||
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 {
|
||||
return TOO_DETAILED_REQUEST;
|
||||
//Go down OR branch.
|
||||
iter = iter.right();
|
||||
}
|
||||
} else {
|
||||
//TODO: Maybe refine this a bit.
|
||||
return NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
PacketMatchTree::iterator PacketMatchTree::addElement(bool andBranch,
|
||||
uint8_t level, PacketMatchTree::iterator position,
|
||||
TmPacketMinimal* content) {
|
||||
SerializeableMatcherIF<TmPacketMinimal*>* newContent = NULL;
|
||||
switch (level) {
|
||||
case 0:
|
||||
newContent = factory.generate<ApidMatcher>(content->getAPID());
|
||||
break;
|
||||
case 1:
|
||||
newContent = factory.generate<ServiceMatcher>(content->getService());
|
||||
break;
|
||||
case 2:
|
||||
newContent = factory.generate<SubServiceMatcher>(
|
||||
content->getSubService());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//Only reached if nothing was found.
|
||||
SerializeableMatcherIF<VALUE_T>* newContent = factory.generate<INSERTION_T>(
|
||||
test);
|
||||
if (newContent == NULL) {
|
||||
return end();
|
||||
return FULL;
|
||||
}
|
||||
Node* newNode = factory.generate<Node>(newContent);
|
||||
if (newNode == NULL) {
|
||||
return end();
|
||||
//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;
|
||||
}
|
||||
return insert(andBranch, position, newNode);
|
||||
*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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ReturnValue_t PacketMatchTree::initialize() {
|
||||
@ -150,7 +175,7 @@ ReturnValue_t PacketMatchTree::initialize() {
|
||||
const uint16_t PacketMatchTree::POOL_SIZES[N_POOLS] = { sizeof(ServiceMatcher),
|
||||
sizeof(SubServiceMatcher), sizeof(ApidMatcher),
|
||||
sizeof(PacketMatchTree::Node) };
|
||||
//TODO: Rather arbitrary. Adjust!
|
||||
//Maximum number of types and subtypes to filter should be more than sufficient.
|
||||
const uint16_t PacketMatchTree::N_ELEMENTS[N_POOLS] = { 10, 20, 2, 40 };
|
||||
|
||||
ReturnValue_t PacketMatchTree::changeMatch(bool addToMatch, uint16_t apid,
|
||||
@ -163,7 +188,8 @@ ReturnValue_t PacketMatchTree::changeMatch(bool addToMatch, uint16_t apid,
|
||||
}
|
||||
|
||||
ReturnValue_t PacketMatchTree::cleanUpElement(iterator position) {
|
||||
//TODO: What if first deletion fails?
|
||||
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);
|
||||
}
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* PacketMatchTree.h
|
||||
*
|
||||
* Created on: 10.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_
|
||||
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_PACKETMATCHTREE_H_
|
||||
|
||||
@ -34,7 +27,9 @@ private:
|
||||
PlacementFactory factory;
|
||||
static const uint16_t POOL_SIZES[N_POOLS];
|
||||
static const uint16_t N_ELEMENTS[N_POOLS];
|
||||
iterator addElement(bool andBranch, uint8_t level, iterator position, TmPacketMinimal* content);
|
||||
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_ */
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* ServiceMatcher.h
|
||||
*
|
||||
* Created on: 09.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_SERVICEMATCHER_H_
|
||||
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_SERVICEMATCHER_H_
|
||||
|
||||
@ -19,6 +12,9 @@ public:
|
||||
ServiceMatcher(uint8_t setService) :
|
||||
service(setService) {
|
||||
}
|
||||
ServiceMatcher(TmPacketMinimal* test) :
|
||||
service(test->getService()) {
|
||||
}
|
||||
bool match(TmPacketMinimal* packet) {
|
||||
if (packet->getService() == service) {
|
||||
return true;
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* SubserviceMatcher.h
|
||||
*
|
||||
* Created on: 09.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_
|
||||
#define FRAMEWORK_TMTCPACKET_PACKETMATCHER_SUBSERVICEMATCHER_H_
|
||||
|
||||
@ -17,6 +10,9 @@ public:
|
||||
SubServiceMatcher(uint8_t subService) :
|
||||
subService(subService) {
|
||||
}
|
||||
SubServiceMatcher(TmPacketMinimal* test) :
|
||||
subService(test->getSubService()) {
|
||||
}
|
||||
bool match(TmPacketMinimal* packet) {
|
||||
if (packet->getSubService() == subService) {
|
||||
return true;
|
||||
|
16
tmtcpacket/pus/PacketTimestampInterpreterIF.h
Normal file
16
tmtcpacket/pus/PacketTimestampInterpreterIF.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef FRAMEWORK_TMTCPACKET_PUS_PACKETTIMESTAMPINTERPRETERIF_H_
|
||||
#define FRAMEWORK_TMTCPACKET_PUS_PACKETTIMESTAMPINTERPRETERIF_H_
|
||||
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
class TmPacketMinimal;
|
||||
|
||||
class PacketTimestampInterpreterIF {
|
||||
public:
|
||||
virtual ~PacketTimestampInterpreterIF() {}
|
||||
virtual ReturnValue_t getPacketTime(TmPacketMinimal* packet, timeval* timestamp) const = 0;
|
||||
virtual ReturnValue_t getPacketTimeRaw(TmPacketMinimal* packet, const uint8_t** timePtr, uint32_t* size) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_TMTCPACKET_PUS_PACKETTIMESTAMPINTERPRETERIF_H_ */
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* TcPacket.cpp
|
||||
*
|
||||
* Created on: 18.06.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacket.h>
|
||||
#include <string.h>
|
||||
template <uint32_t byte_size>
|
||||
TcPacket<byte_size>::TcPacket() : TcPacketBase( (uint8_t*)&this->local_data ) {
|
||||
memset( &this->local_data, 0, sizeof(this->local_data) );
|
||||
//Set all constant elements in header according to ECSS E-70-41A (2003)
|
||||
//Primary header:
|
||||
//Set APID to idle packet
|
||||
this->local_data.primary.packet_id_h = 0b00011000;
|
||||
this->setAPID( APID_IDLE_PACKET );
|
||||
//Set Sequence Flags to "stand-alone packet"
|
||||
this->local_data.primary.sequence_control_h = 0b11000000;
|
||||
//Set packet size to size of data field header + CRC
|
||||
this->setPacketDataLength( sizeof(this->local_data.data_field) + CRC_SIZE );
|
||||
|
||||
//Data Field Header:
|
||||
//Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000
|
||||
this->local_data.data_field.version_type_ack = 0b00010000;
|
||||
|
||||
}
|
||||
|
||||
template <uint32_t byte_size>
|
||||
TcPacket<byte_size>::TcPacket( uint16_t new_apid, uint8_t new_ack, uint8_t new_service, uint8_t new_subservice, uint16_t new_sequence_count) : TcPacketBase( (uint8_t*)&this->local_data ) {
|
||||
memset( &this->local_data, 0, sizeof(this->local_data) );
|
||||
//Set all constant elements in header according to ECSS E-70-41A (2003)
|
||||
//Primary header:
|
||||
//Set APID to idle packet
|
||||
this->local_data.primary.packet_id_h = 0b00011000;
|
||||
this->setAPID( new_apid );
|
||||
//Set Sequence Flags to "stand-alone packet"
|
||||
this->local_data.primary.sequence_control_h = 0b11000000;
|
||||
this->setPacketSequenceCount( new_sequence_count );
|
||||
this->setPacketDataLength( sizeof(this->local_data.data_field) + CRC_SIZE );
|
||||
|
||||
//Data Field Header:
|
||||
//Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000
|
||||
this->local_data.data_field.version_type_ack = 0b00010000;
|
||||
this->local_data.data_field.version_type_ack |= ( new_ack & 0x0F);
|
||||
this->local_data.data_field.service_type = new_service;
|
||||
this->local_data.data_field.service_subtype = new_subservice;
|
||||
this->setErrorControl();
|
||||
|
||||
}
|
||||
|
||||
template <uint32_t byte_size>
|
||||
TcPacket< byte_size >::~TcPacket() {
|
||||
}
|
||||
|
||||
template <uint32_t byte_size>
|
||||
bool TcPacket<byte_size>::addApplicationData( uint8_t* newData, uint32_t amount ) {
|
||||
if ( amount <= ( sizeof(this->local_data.application_data) - CRC_SIZE ) ) {
|
||||
memcpy( this->local_data.application_data, newData, amount );
|
||||
this->setPacketDataLength( amount + sizeof(this->local_data.data_field) + CRC_SIZE - 1 );
|
||||
this->setErrorControl();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template class TcPacket<TC_PACKET_MIN_SIZE>;
|
||||
template class TcPacket<32>;
|
||||
template class TcPacket<64>;
|
||||
template class TcPacket<128>;
|
||||
template class TcPacket<256>;
|
||||
template class TcPacket<1024>;
|
@ -1,83 +0,0 @@
|
||||
#ifndef TCPACKET_H_
|
||||
#define TCPACKET_H_
|
||||
|
||||
#include <framework/tmtcpacket/pus/TcPacketBase.h>
|
||||
|
||||
/**
|
||||
* This constant defines the minimum size of a valid PUS Telecommand Packet.
|
||||
*/
|
||||
#define TC_PACKET_MIN_SIZE (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + 2)
|
||||
|
||||
/**
|
||||
* The TcPacket class is a representation of a ECSS PUS Telecommand packet.
|
||||
|
||||
* The template parameter is used to instantiate the class with different
|
||||
* maximum Application Data sizes (to avoid wasting stack size).
|
||||
* Telecommand packets are mainly created on ground, which are accessed with
|
||||
* the TcPacketBase class. However, there are occasions when command packets
|
||||
* are created on-board, for example when commanding another PUS compatible
|
||||
* device such as the star trackers.
|
||||
* These packets can be created with the TcPacket class.
|
||||
* A pointer to \c local_data is passed to the \c TcPacketBase parent class,
|
||||
* so the parent's methods are reachable.
|
||||
* @t_param byte_size The maximum size of the complete packet (including CRC
|
||||
* and headers)
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
template<uint32_t byte_size>
|
||||
class TcPacket : public TcPacketBase {
|
||||
private:
|
||||
/**
|
||||
* This structure defines the data structure of a Telecommand Packet as
|
||||
* local data.
|
||||
*
|
||||
* There's a buffer which corresponds to the Telecommand Application Data
|
||||
* Field with a maximum size of \c byte_size.
|
||||
*/
|
||||
struct TcPacketData {
|
||||
CCSDSPrimaryHeader primary;
|
||||
PUSTcDataFieldHeader data_field;
|
||||
uint8_t application_data[byte_size - sizeof(CCSDSPrimaryHeader) - sizeof(PUSTcDataFieldHeader)];
|
||||
};
|
||||
/**
|
||||
* This is the data representation of the class.
|
||||
*/
|
||||
TcPacketData local_data;
|
||||
public:
|
||||
/**
|
||||
* This is the default constructor of the class.
|
||||
*
|
||||
* It sets all values to default for a CCSDS Idle Packet (i.e. APID is 2047).
|
||||
*/
|
||||
TcPacket( void );
|
||||
/**
|
||||
* A constructor which directly sets all relevant header information.
|
||||
* @param apid Sets the packet's APID field.
|
||||
* @param ack Set's the packet's Ack field,
|
||||
* which specifies number and size of verification packets returned
|
||||
* for this command.
|
||||
* @param service Sets the packet's Service ID field.
|
||||
* This specifies the destination service.
|
||||
* @param subservice Sets the packet's Service Subtype field.
|
||||
* This specifies the destination sub-service.
|
||||
* @param sequence_count Sets the packet's Source Sequence Count field.
|
||||
*/
|
||||
TcPacket( uint16_t apid, uint8_t ack, uint8_t service, uint8_t subservice, uint16_t sequence_count = 0 );
|
||||
/**
|
||||
* This is the empty default destructor of the class.
|
||||
*/
|
||||
~TcPacket( void );
|
||||
/**
|
||||
* With this call, application data can be added to the Application Data
|
||||
* buffer.
|
||||
* The Error Control Field is updated automatically.
|
||||
* @param data The data to add to the Application Data field.
|
||||
* @param size The size of the data to add.
|
||||
* @return @li \c true if \c size is smaller than the Application Data
|
||||
* buffer.
|
||||
* @li \c false else.
|
||||
*/
|
||||
bool addApplicationData( uint8_t* data, uint32_t size );
|
||||
};
|
||||
|
||||
#endif /* TCPACKET_H_ */
|
@ -1,16 +1,11 @@
|
||||
/*
|
||||
* TcPacketBase.cpp
|
||||
*
|
||||
* Created on: 18.06.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/globalfunctions/crc_ccitt.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacketBase.h>
|
||||
#include <string.h>
|
||||
|
||||
TcPacketBase::TcPacketBase( const uint8_t* set_data ) : SpacePacketBase( set_data ) {
|
||||
this->tc_data = (TcPacketPointer*)set_data;
|
||||
TcPacketBase::TcPacketBase(const uint8_t* set_data) :
|
||||
SpacePacketBase(set_data) {
|
||||
tcData = (TcPacketPointer*) set_data;
|
||||
}
|
||||
|
||||
TcPacketBase::~TcPacketBase() {
|
||||
@ -18,57 +13,70 @@ TcPacketBase::~TcPacketBase() {
|
||||
}
|
||||
|
||||
uint8_t TcPacketBase::getService() {
|
||||
return this->tc_data->data_field.service_type;
|
||||
return tcData->data_field.service_type;
|
||||
}
|
||||
|
||||
uint8_t TcPacketBase::getSubService() {
|
||||
return this->tc_data->data_field.service_subtype;
|
||||
return tcData->data_field.service_subtype;
|
||||
}
|
||||
|
||||
uint8_t TcPacketBase::getAcknowledgeFlags() {
|
||||
return this->tc_data->data_field.version_type_ack & 0b00001111;
|
||||
return tcData->data_field.version_type_ack & 0b00001111;
|
||||
}
|
||||
|
||||
const uint8_t* TcPacketBase::getApplicationData() const {
|
||||
return &this->tc_data->data;
|
||||
return &tcData->data;
|
||||
}
|
||||
|
||||
uint16_t TcPacketBase::getApplicationDataSize() {
|
||||
return this->getPacketDataLength() - sizeof(this->tc_data->data_field) - CRC_SIZE + 1;
|
||||
return getPacketDataLength() - sizeof(tcData->data_field) - CRC_SIZE + 1;
|
||||
}
|
||||
|
||||
uint16_t TcPacketBase::getErrorControl() {
|
||||
uint16_t size = this->getApplicationDataSize() + CRC_SIZE;
|
||||
uint8_t* p_to_buffer = &this->tc_data->data;
|
||||
return ( p_to_buffer[size - 2] << 8 ) + p_to_buffer[size - 1];
|
||||
uint16_t size = getApplicationDataSize() + CRC_SIZE;
|
||||
uint8_t* p_to_buffer = &tcData->data;
|
||||
return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1];
|
||||
}
|
||||
|
||||
void TcPacketBase::setErrorControl() {
|
||||
uint32_t full_size = this->getFullSize();
|
||||
uint16_t crc = ::Calculate_CRC ( this->getWholeData(), full_size - CRC_SIZE );
|
||||
uint32_t size = this->getApplicationDataSize();
|
||||
(&tc_data->data)[ size ] = ( crc & 0XFF00) >> 8; // CRCH
|
||||
(&tc_data->data)[ size + 1 ] = ( crc ) & 0X00FF; // CRCL
|
||||
uint32_t full_size = getFullSize();
|
||||
uint16_t crc = ::Calculate_CRC(getWholeData(), full_size - CRC_SIZE);
|
||||
uint32_t size = getApplicationDataSize();
|
||||
(&tcData->data)[size] = (crc & 0XFF00) >> 8; // CRCH
|
||||
(&tcData->data)[size + 1] = (crc) & 0X00FF; // CRCL
|
||||
}
|
||||
|
||||
void TcPacketBase::setData(const uint8_t* p_Data) {
|
||||
this->SpacePacketBase::setData( p_Data );
|
||||
this->tc_data = (TcPacketPointer*)p_Data;
|
||||
SpacePacketBase::setData(p_Data);
|
||||
tcData = (TcPacketPointer*) p_Data;
|
||||
}
|
||||
|
||||
uint8_t TcPacketBase::getSecondaryHeaderFlag() {
|
||||
return (this->tc_data->data_field.version_type_ack & 0b10000000) >> 7;
|
||||
return (tcData->data_field.version_type_ack & 0b10000000) >> 7;
|
||||
}
|
||||
|
||||
uint8_t TcPacketBase::getPusVersionNumber() {
|
||||
return (this->tc_data->data_field.version_type_ack & 0b01110000) >> 4;
|
||||
return (tcData->data_field.version_type_ack & 0b01110000) >> 4;
|
||||
}
|
||||
|
||||
void TcPacketBase::print() {
|
||||
uint8_t * wholeData = this->getWholeData();
|
||||
uint8_t * wholeData = getWholeData();
|
||||
debug << "TcPacket contains: " << std::endl;
|
||||
for (uint8_t count = 0; count < this->getFullSize(); ++count ) {
|
||||
debug << std::hex << (uint16_t)wholeData[count] << " ";
|
||||
for (uint8_t count = 0; count < getFullSize(); ++count) {
|
||||
debug << std::hex << (uint16_t) wholeData[count] << " ";
|
||||
}
|
||||
debug << std::dec << std::endl;
|
||||
}
|
||||
|
||||
void TcPacketBase::initializeTcPacket(uint16_t apid, uint16_t sequenceCount,
|
||||
uint8_t ack, uint8_t service, uint8_t subservice) {
|
||||
initSpacePacketHeader(true, true, apid, sequenceCount);
|
||||
memset(&tcData->data_field, 0, sizeof(tcData->data_field));
|
||||
setPacketDataLength(sizeof(tcData->data_field) + CRC_SIZE);
|
||||
//Data Field Header:
|
||||
//Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000
|
||||
tcData->data_field.version_type_ack = 0b00010000;
|
||||
tcData->data_field.version_type_ack |= (ack & 0x0F);
|
||||
tcData->data_field.service_type = service;
|
||||
tcData->data_field.service_subtype = subservice;
|
||||
}
|
||||
|
@ -46,8 +46,9 @@ protected:
|
||||
*
|
||||
* To be hardware-safe, all elements are of byte size.
|
||||
*/
|
||||
TcPacketPointer* tc_data;
|
||||
TcPacketPointer* tcData;
|
||||
public:
|
||||
static const uint16_t TC_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTcDataFieldHeader) + 2);
|
||||
/**
|
||||
* With this constant for the acknowledge field responses on all levels are expected.
|
||||
*/
|
||||
@ -83,6 +84,22 @@ public:
|
||||
* This is the empty default destructor.
|
||||
*/
|
||||
virtual ~TcPacketBase();
|
||||
/**
|
||||
* Initializes the Tc Packet header.
|
||||
* @param apid APID used.
|
||||
* @param service PUS Service
|
||||
* @param subservice PUS Subservice
|
||||
* @param packetSubcounter Additional subcounter used.
|
||||
*/
|
||||
/**
|
||||
* Initializes the Tc Packet header.
|
||||
* @param apid APID used.
|
||||
* @param sequenceCount Sequence Count in the primary header.
|
||||
* @param ack Which acknowledeges are expected from the receiver.
|
||||
* @param service PUS Service
|
||||
* @param subservice PUS Subservice
|
||||
*/
|
||||
void initializeTcPacket(uint16_t apid, uint16_t sequenceCount, uint8_t ack, uint8_t service, uint8_t subservice);
|
||||
/**
|
||||
* This command returns the CCSDS Secondary Header Flag.
|
||||
* It shall always be zero for PUS Packets. This is the
|
||||
|
@ -1,56 +1,57 @@
|
||||
|
||||
/*
|
||||
* TcPacketStored.cpp
|
||||
*
|
||||
* Created on: 20.11.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacket.h>
|
||||
#include <framework/tmtcpacket/pus/TcPacketStored.h>
|
||||
#include <string.h>
|
||||
|
||||
TcPacketStored::TcPacketStored( store_address_t setAddress) : TcPacketBase(NULL), storeAddress(setAddress) {
|
||||
this->setStoreAddress( this->storeAddress );
|
||||
TcPacketStored::TcPacketStored(store_address_t setAddress) :
|
||||
TcPacketBase(NULL), storeAddress(setAddress) {
|
||||
this->setStoreAddress(this->storeAddress);
|
||||
}
|
||||
|
||||
TcPacketStored::TcPacketStored( uint16_t apid, uint8_t ack, uint8_t service, uint8_t subservice,
|
||||
uint8_t sequence_count, const uint8_t* data, uint32_t size) : TcPacketBase(NULL) {
|
||||
TcPacketStored::TcPacketStored(uint16_t apid, uint8_t ack, uint8_t service,
|
||||
uint8_t subservice, uint8_t sequence_count, const uint8_t* data,
|
||||
uint32_t size) :
|
||||
TcPacketBase(NULL) {
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
if ( this->checkAndSetStore() ) {
|
||||
TcPacket<TC_PACKET_MIN_SIZE> temp_packet( apid, ack, service, subservice, sequence_count);
|
||||
uint8_t* p_data = NULL;
|
||||
ReturnValue_t returnValue = this->store->getFreeElement( &this->storeAddress, (TC_PACKET_MIN_SIZE + size), &p_data );
|
||||
if ( returnValue == this->store->RETURN_OK ) {
|
||||
memcpy(p_data, temp_packet.getWholeData(), temp_packet.getFullSize() );
|
||||
this->setData( p_data );
|
||||
memcpy( &tc_data->data, data, size );
|
||||
this->setPacketDataLength( size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1 );
|
||||
this->setErrorControl();
|
||||
}
|
||||
if (!this->checkAndSetStore()) {
|
||||
return;
|
||||
}
|
||||
uint8_t* p_data = NULL;
|
||||
ReturnValue_t returnValue = this->store->getFreeElement(&this->storeAddress,
|
||||
(TC_PACKET_MIN_SIZE + size), &p_data);
|
||||
if (returnValue != this->store->RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
this->setData(p_data);
|
||||
initializeTcPacket(apid, sequence_count, ack, service, subservice);
|
||||
memcpy(&tcData->data, data, size);
|
||||
this->setPacketDataLength(
|
||||
size + sizeof(PUSTcDataFieldHeader) + CRC_SIZE - 1);
|
||||
this->setErrorControl();
|
||||
}
|
||||
|
||||
TcPacketStored::TcPacketStored() : TcPacketBase(NULL) {
|
||||
TcPacketStored::TcPacketStored() :
|
||||
TcPacketBase(NULL) {
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
this->checkAndSetStore();
|
||||
|
||||
}
|
||||
|
||||
//TODO: return code?
|
||||
void TcPacketStored::deletePacket() {
|
||||
this->store->deleteData( this->storeAddress );
|
||||
ReturnValue_t TcPacketStored::deletePacket() {
|
||||
ReturnValue_t result = this->store->deleteData(this->storeAddress);
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
this->setData( NULL );
|
||||
this->setData( NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TcPacketStored::checkAndSetStore() {
|
||||
if (this->store == NULL) {
|
||||
this->store = objectManager->get<StorageManagerIF>( objects::TC_STORE );
|
||||
if ( this->store == NULL ) {
|
||||
error << "TcPacketStored::TcPacketStored: TC Store not found!" << std::endl;
|
||||
this->store = objectManager->get<StorageManagerIF>(objects::TC_STORE);
|
||||
if (this->store == NULL) {
|
||||
error << "TcPacketStored::TcPacketStored: TC Store not found!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -62,8 +63,9 @@ void TcPacketStored::setStoreAddress(store_address_t setAddress) {
|
||||
const uint8_t* temp_data = NULL;
|
||||
uint32_t temp_size;
|
||||
ReturnValue_t status = StorageManagerIF::RETURN_FAILED;
|
||||
if ( this->checkAndSetStore() ) {
|
||||
status = this->store->getData(this->storeAddress, &temp_data, &temp_size );
|
||||
if (this->checkAndSetStore()) {
|
||||
status = this->store->getData(this->storeAddress, &temp_data,
|
||||
&temp_size);
|
||||
}
|
||||
if (status == StorageManagerIF::RETURN_OK) {
|
||||
this->setData(temp_data);
|
||||
@ -80,9 +82,10 @@ store_address_t TcPacketStored::getStoreAddress() {
|
||||
bool TcPacketStored::isSizeCorrect() {
|
||||
const uint8_t* temp_data = NULL;
|
||||
uint32_t temp_size;
|
||||
ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, &temp_size );
|
||||
ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data,
|
||||
&temp_size);
|
||||
if (status == StorageManagerIF::RETURN_OK) {
|
||||
if (this->getFullSize() == temp_size ) {
|
||||
if (this->getFullSize() == temp_size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -91,11 +94,12 @@ bool TcPacketStored::isSizeCorrect() {
|
||||
|
||||
StorageManagerIF* TcPacketStored::store = NULL;
|
||||
|
||||
TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) : TcPacketBase(data) {
|
||||
TcPacketStored::TcPacketStored(const uint8_t* data, uint32_t size) :
|
||||
TcPacketBase(data) {
|
||||
if (getFullSize() != size) {
|
||||
return;
|
||||
}
|
||||
if ( this->checkAndSetStore() ) {
|
||||
if (this->checkAndSetStore()) {
|
||||
ReturnValue_t status = store->addData(&storeAddress, data, size);
|
||||
if (status != HasReturnvaluesIF::RETURN_OK) {
|
||||
this->setData(NULL);
|
||||
|
@ -81,8 +81,9 @@ public:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void deletePacket();
|
||||
ReturnValue_t deletePacket();
|
||||
/**
|
||||
* With this call, a packet can be linked to another store. This is useful
|
||||
* if the packet is a class member and used for more than one packet.
|
||||
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* TmPacket.cpp
|
||||
*
|
||||
* Created on: 18.06.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/tmtcpacket/pus/TmPacket.h>
|
||||
#include <string.h>
|
||||
template <uint32_t byte_size>
|
||||
TmPacket<byte_size>::TmPacket() : TmPacketBase( (uint8_t*)&this->local_data ) {
|
||||
memset( &this->local_data, 0, sizeof(this->local_data) );
|
||||
//Set all constant elements in header according to ECSS E-70-41A (2003)
|
||||
//Primary header:
|
||||
//Set APID to idle packet
|
||||
local_data.primary.packet_id_h = 0b00001000;
|
||||
setAPID( APID_IDLE_PACKET );
|
||||
//Set Sequence Flags to "stand-alone packet"
|
||||
local_data.primary.sequence_control_h = 0b11000000;
|
||||
//Set packet size to size of data field header + CRC
|
||||
setPacketDataLength( sizeof(this->local_data.data_field) + CRC_SIZE );
|
||||
if (checkAndSetStamper()) {
|
||||
timeStamper->addTimeStamp(local_data.data_field.time, sizeof(local_data.data_field.time));
|
||||
}
|
||||
//Data Field Header:
|
||||
//Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000
|
||||
this->local_data.data_field.version_type_ack = 0b00010000;
|
||||
|
||||
}
|
||||
|
||||
template <uint32_t byte_size>
|
||||
TmPacket<byte_size>::TmPacket( uint16_t new_apid, uint8_t new_service, uint8_t new_subservice, uint8_t new_packet_counter ) : TmPacketBase( (uint8_t*)&this->local_data ) {
|
||||
memset( &this->local_data, 0, sizeof(this->local_data) );
|
||||
//Set all constant elements in header according to ECSS E-70-41A (2003)
|
||||
//Primary header:
|
||||
//Set APID to idle packet
|
||||
this->local_data.primary.packet_id_h = 0b00001000;
|
||||
this->setAPID( new_apid );
|
||||
//Set Sequence Flags to "stand-alone packet"
|
||||
this->local_data.primary.sequence_control_h = 0b11000000;
|
||||
//Set Data Length to minimum size (Data Field Header + CRC size)
|
||||
this->setPacketDataLength( sizeof(this->local_data.data_field) + CRC_SIZE );
|
||||
|
||||
//Data Field Header:
|
||||
//Set CCSDS_secondary_header_flag to 0, version number to 001 and ack to 0000
|
||||
this->local_data.data_field.version_type_ack = 0b00010000;
|
||||
this->local_data.data_field.service_type = new_service;
|
||||
this->local_data.data_field.service_subtype = new_subservice;
|
||||
this->local_data.data_field.subcounter = new_packet_counter;
|
||||
|
||||
if (checkAndSetStamper()) {
|
||||
timeStamper->addTimeStamp(local_data.data_field.time, sizeof(local_data.data_field.time));
|
||||
}
|
||||
|
||||
// this->local_data.data_field.destination = new_destination;
|
||||
this->setErrorControl();
|
||||
}
|
||||
|
||||
template <uint32_t byte_size>
|
||||
TmPacket< byte_size >::~TmPacket() {
|
||||
}
|
||||
|
||||
template <uint32_t byte_size>
|
||||
bool TmPacket<byte_size>::addSourceData( uint8_t* newData, uint32_t amount ) {
|
||||
if ( amount <= ( sizeof(this->local_data.source_data) - CRC_SIZE ) ) {
|
||||
memcpy( this->local_data.source_data, newData, amount );
|
||||
this->setPacketDataLength( amount + sizeof(this->local_data.data_field) + CRC_SIZE - 1 );
|
||||
this->setErrorControl();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template class TmPacket<TmPacketBase::TM_PACKET_MIN_SIZE>;
|
||||
template class TmPacket<64>;
|
||||
template class TmPacket<128>;
|
||||
template class TmPacket<256>;
|
||||
template class TmPacket<512>;
|
||||
template class TmPacket<1024>;
|
@ -1,72 +0,0 @@
|
||||
#ifndef TMPACKET_H_
|
||||
#define TMPACKET_H_
|
||||
|
||||
#include <framework/tmtcpacket/pus/TmPacketBase.h>
|
||||
|
||||
/**
|
||||
* The TmPacket class is a representation of a ECSS PUS Telemetry packet.
|
||||
|
||||
* The template parameter is used to instantiate the class with different
|
||||
* maximum Application Data sizes (to avoid wasting stack size). Almost every
|
||||
* on-board service is a source of telemetry packets. These packets are created
|
||||
* with the TmPacket class, which is instantiated similar to the TcPacket
|
||||
* class.
|
||||
* A pointer to \c local_data is passed to the \c TmPacketBase parent class,
|
||||
* so the parent's methods are reachable.
|
||||
* @t_param byte_size The maximum size of the complete packet (including CRC
|
||||
* and headers)
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
template<uint32_t byte_size>
|
||||
class TmPacket : public TmPacketBase {
|
||||
public:
|
||||
/**
|
||||
* This is the default constructor of the class.
|
||||
*
|
||||
* It sets all values to default for a CCSDS Idle Packet (i.e. APID is 2047).
|
||||
*/
|
||||
TmPacket( void );
|
||||
/**
|
||||
* A constructor which directly sets all relevant header information.
|
||||
* @param apid Sets the packet's APID field.
|
||||
* @param service Sets the packet's Service ID field.
|
||||
* This specifies the source service.
|
||||
* @param subservice Sets the packet's Service Subtype field.
|
||||
* This specifies the source sub-service.
|
||||
* @param packet_counter Sets the Packet counter field of this packet.
|
||||
*/
|
||||
TmPacket( uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packet_counter = 0 );
|
||||
/**
|
||||
* This is the empty default destructor of the class.
|
||||
*/
|
||||
~TmPacket( void );
|
||||
/**
|
||||
* With this call, application data can be added to the Source Data
|
||||
* buffer.
|
||||
* The Error Control Field is updated automatically.
|
||||
* @param data The data to add to the Source Data field.
|
||||
* @param size The size of the data to add.
|
||||
* @return @li \c true if \c size is smaller than the Source Data buffer.
|
||||
* @li \c false else.
|
||||
*/
|
||||
bool addSourceData( uint8_t*, uint32_t );
|
||||
private:
|
||||
/**
|
||||
* This structure defines the data structure of a Telemetry Packet as
|
||||
* local data.
|
||||
*
|
||||
* There's a buffer which corresponds to the Telemetry Source Data Field
|
||||
* with a maximum size of \c byte_size.
|
||||
*/
|
||||
struct TmPacketData {
|
||||
CCSDSPrimaryHeader primary;
|
||||
PUSTmDataFieldHeader data_field;
|
||||
uint8_t source_data[byte_size - sizeof(CCSDSPrimaryHeader) - sizeof(PUSTmDataFieldHeader)];
|
||||
};
|
||||
/**
|
||||
* This is the data representation of the class.
|
||||
*/
|
||||
TmPacketData local_data;
|
||||
};
|
||||
|
||||
#endif /* TMPACKET_H_ */
|
@ -1,17 +1,13 @@
|
||||
/*
|
||||
* TmPacketBase.cpp
|
||||
*
|
||||
* Created on: 18.06.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/globalfunctions/crc_ccitt.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/pus/TmPacketBase.h>
|
||||
#include <framework/timemanager/CCSDSTime.h>
|
||||
#include <string.h>
|
||||
|
||||
TmPacketBase::TmPacketBase( uint8_t* set_data ) : SpacePacketBase( set_data ) {
|
||||
this->tm_data = (TmPacketPointer*)set_data;
|
||||
TmPacketBase::TmPacketBase(uint8_t* set_data) :
|
||||
SpacePacketBase(set_data) {
|
||||
tm_data = (TmPacketPointer*) set_data;
|
||||
}
|
||||
|
||||
TmPacketBase::~TmPacketBase() {
|
||||
@ -19,60 +15,97 @@ TmPacketBase::~TmPacketBase() {
|
||||
}
|
||||
|
||||
uint8_t TmPacketBase::getService() {
|
||||
return this->tm_data->data_field.service_type;
|
||||
return tm_data->data_field.service_type;
|
||||
}
|
||||
|
||||
uint8_t TmPacketBase::getSubService() {
|
||||
return this->tm_data->data_field.service_subtype;
|
||||
return tm_data->data_field.service_subtype;
|
||||
}
|
||||
|
||||
uint8_t* TmPacketBase::getSourceData() {
|
||||
return &this->tm_data->data;
|
||||
return &tm_data->data;
|
||||
}
|
||||
|
||||
uint16_t TmPacketBase::getSourceDataSize() {
|
||||
return this->getPacketDataLength() - sizeof(this->tm_data->data_field) - CRC_SIZE + 1;
|
||||
return getPacketDataLength() - sizeof(tm_data->data_field)
|
||||
- CRC_SIZE + 1;
|
||||
}
|
||||
|
||||
uint16_t TmPacketBase::getErrorControl() {
|
||||
uint32_t size = this->getSourceDataSize() + CRC_SIZE;
|
||||
uint8_t* p_to_buffer = &this->tm_data->data;
|
||||
return ( p_to_buffer[size - 2] << 8 ) + p_to_buffer[size - 1];
|
||||
uint32_t size = getSourceDataSize() + CRC_SIZE;
|
||||
uint8_t* p_to_buffer = &tm_data->data;
|
||||
return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1];
|
||||
}
|
||||
|
||||
|
||||
void TmPacketBase::setErrorControl() {
|
||||
uint32_t full_size = this->getFullSize();
|
||||
uint16_t crc = ::Calculate_CRC ( this->getWholeData(), full_size - CRC_SIZE );
|
||||
uint32_t size = this->getSourceDataSize();
|
||||
this->getSourceData()[ size ] = ( crc & 0XFF00) >> 8; // CRCH
|
||||
this->getSourceData()[ size + 1 ] = ( crc ) & 0X00FF; // CRCL
|
||||
uint32_t full_size = getFullSize();
|
||||
uint16_t crc = ::Calculate_CRC(getWholeData(), full_size - CRC_SIZE);
|
||||
uint32_t size = getSourceDataSize();
|
||||
getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH
|
||||
getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL
|
||||
}
|
||||
|
||||
void TmPacketBase::setData(const uint8_t* p_Data) {
|
||||
this->SpacePacketBase::setData( p_Data );
|
||||
this->tm_data = (TmPacketPointer*)p_Data;
|
||||
SpacePacketBase::setData(p_Data);
|
||||
tm_data = (TmPacketPointer*) p_Data;
|
||||
}
|
||||
|
||||
void TmPacketBase::print() {
|
||||
/*uint8_t * wholeData = this->getWholeData();
|
||||
debug << "TmPacket contains: " << std::endl;
|
||||
for (uint8_t count = 0; count < this->getFullSize(); ++count ) {
|
||||
debug << std::hex << (uint16_t)wholeData[count] << " ";
|
||||
}
|
||||
debug << std::dec << std::endl;*/
|
||||
/*uint8_t * wholeData = getWholeData();
|
||||
debug << "TmPacket contains: " << std::endl;
|
||||
for (uint8_t count = 0; count < getFullSize(); ++count ) {
|
||||
debug << std::hex << (uint16_t)wholeData[count] << " ";
|
||||
}
|
||||
debug << std::dec << std::endl;*/
|
||||
}
|
||||
|
||||
bool TmPacketBase::checkAndSetStamper() {
|
||||
if (timeStamper == NULL) {
|
||||
//TODO: Adjust name?
|
||||
timeStamper = objectManager->get<TimeStamperIF>( objects::TIME_MANAGER );
|
||||
if ( timeStamper == NULL ) {
|
||||
error << "TmPacketBase::checkAndSetStamper: Stamper not found!" << std::endl;
|
||||
timeStamper = objectManager->get<TimeStamperIF>(timeStamperId);
|
||||
if (timeStamper == NULL) {
|
||||
error << "TmPacketBase::checkAndSetStamper: Stamper not found!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const {
|
||||
uint32_t tempSize = 0;
|
||||
return CCSDSTime::convertFromCcsds(timestamp, tm_data->data_field.time,
|
||||
&tempSize, sizeof(tm_data->data_field.time));
|
||||
}
|
||||
|
||||
uint8_t* TmPacketBase::getPacketTimeRaw() const{
|
||||
return tm_data->data_field.time;
|
||||
|
||||
}
|
||||
|
||||
void TmPacketBase::initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter) {
|
||||
//Set primary header:
|
||||
initSpacePacketHeader(false, true, apid);
|
||||
//Set data Field Header:
|
||||
//First, set to zero.
|
||||
memset(&tm_data->data_field, 0, sizeof(tm_data->data_field));
|
||||
//Set CCSDS_secondary header flag to 0, version number to 001 and ack to 0000
|
||||
tm_data->data_field.version_type_ack = 0b00010000;
|
||||
tm_data->data_field.service_type = service;
|
||||
tm_data->data_field.service_subtype = subservice;
|
||||
tm_data->data_field.subcounter = packetSubcounter;
|
||||
//Timestamp packet
|
||||
if (checkAndSetStamper()) {
|
||||
timeStamper->addTimeStamp(tm_data->data_field.time, sizeof(tm_data->data_field.time));
|
||||
}
|
||||
}
|
||||
|
||||
void TmPacketBase::setSourceDataSize(uint16_t size) {
|
||||
setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
|
||||
}
|
||||
|
||||
uint32_t TmPacketBase::getTimestampSize() const {
|
||||
return sizeof(tm_data->data_field.time);
|
||||
}
|
||||
|
||||
TimeStamperIF* TmPacketBase::timeStamper = NULL;
|
||||
object_id_t TmPacketBase::timeStamperId = 0;
|
||||
|
@ -3,6 +3,12 @@
|
||||
|
||||
#include <framework/timemanager/TimeStamperIF.h>
|
||||
#include <framework/tmtcpacket/SpacePacketBase.h>
|
||||
#include <framework/timemanager/Clock.h>
|
||||
#include <framework/objectmanager/SystemObjectIF.h>
|
||||
|
||||
namespace Factory{
|
||||
void setStaticFrameworkObjectIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* This struct defines a byte-wise structured PUS TM Data Field Header.
|
||||
@ -31,8 +37,6 @@ struct TmPacketPointer {
|
||||
uint8_t data;
|
||||
};
|
||||
|
||||
//TODO: add getTime, getSubcounter, getDestionation (if required)
|
||||
|
||||
/**
|
||||
* This class is the basic data handler for any ECSS PUS Telemetry packet.
|
||||
*
|
||||
@ -45,7 +49,14 @@ struct TmPacketPointer {
|
||||
* @ingroup tmtcpackets
|
||||
*/
|
||||
class TmPacketBase : public SpacePacketBase {
|
||||
friend void (Factory::setStaticFrameworkObjectIds)();
|
||||
public:
|
||||
/**
|
||||
* This constant defines the minimum size of a valid PUS Telemetry Packet.
|
||||
*/
|
||||
static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTmDataFieldHeader) + 2); //!< Minimum size of a valid PUS Telemetry Packet.
|
||||
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; //!< Maximum size of a TM Packet in this mission.
|
||||
static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000; //!< First byte of secondary header for PUS-A packets.
|
||||
/**
|
||||
* This is the default constructor.
|
||||
* It sets its internal data pointer to the address passed and also
|
||||
@ -57,6 +68,15 @@ public:
|
||||
* This is the empty default destructor.
|
||||
*/
|
||||
virtual ~TmPacketBase();
|
||||
/**
|
||||
* Initializes the Tm Packet header.
|
||||
* Does set the timestamp (to now), but not the error control field.
|
||||
* @param apid APID used.
|
||||
* @param service PUS Service
|
||||
* @param subservice PUS Subservice
|
||||
* @param packetSubcounter Additional subcounter used.
|
||||
*/
|
||||
void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter);
|
||||
/**
|
||||
* This is a getter for the packet's PUS Service ID, which is the second
|
||||
* byte of the Data Field Header.
|
||||
@ -85,6 +105,12 @@ public:
|
||||
* @return The size of the PUS Source Data (without Error Control field)
|
||||
*/
|
||||
uint16_t getSourceDataSize();
|
||||
|
||||
/**
|
||||
* In case data was filled manually (almost never the case).
|
||||
* @param size Size of source data (without CRC and data filed header!).
|
||||
*/
|
||||
void setSourceDataSize(uint16_t size);
|
||||
/**
|
||||
* This getter returns the Error Control Field of the packet.
|
||||
*
|
||||
@ -115,10 +141,18 @@ public:
|
||||
*/
|
||||
void print();
|
||||
/**
|
||||
* This constant defines the minimum size of a valid PUS Telemetry Packet.
|
||||
* Interprets the "time"-field in the secondary header and returns it in timeval format.
|
||||
* @return Converted timestamp of packet.
|
||||
*/
|
||||
static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) + sizeof(PUSTmDataFieldHeader) + 2);
|
||||
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; //!< Maximum size of a TM Packet in this mission.
|
||||
ReturnValue_t getPacketTime(timeval* timestamp) const;
|
||||
/**
|
||||
* Returns a raw pointer to the beginning of the time field.
|
||||
* @return Raw pointer to time field.
|
||||
*/
|
||||
uint8_t* getPacketTimeRaw() const;
|
||||
|
||||
uint32_t getTimestampSize() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* A pointer to a structure which defines the data structure of
|
||||
@ -132,6 +166,8 @@ protected:
|
||||
* It is initialized lazy.
|
||||
*/
|
||||
static TimeStamperIF* timeStamper;
|
||||
|
||||
static object_id_t timeStamperId; //!< The ID to use when looking for a time stamper.
|
||||
/**
|
||||
* Checks if a time stamper is available and tries to set it if not.
|
||||
* @return Returns false if setting failed.
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
#include <framework/tmtcpacket/pus/TmPacketMinimal.h>
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
#include <framework/tmtcpacket/pus/PacketTimestampInterpreterIF.h>
|
||||
|
||||
TmPacketMinimal::TmPacketMinimal(const uint8_t* set_data) : SpacePacketBase( set_data ) {
|
||||
this->tm_data = (TmPacketMinimalPointer*)set_data;
|
||||
@ -19,3 +21,25 @@ uint8_t TmPacketMinimal::getSubService() {
|
||||
uint8_t TmPacketMinimal::getPacketSubcounter() {
|
||||
return tm_data->data_field.subcounter;
|
||||
}
|
||||
|
||||
ReturnValue_t TmPacketMinimal::getPacketTime(timeval* timestamp) {
|
||||
if (timestampInterpreter == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return timestampInterpreter->getPacketTime(this, timestamp);
|
||||
}
|
||||
|
||||
ReturnValue_t TmPacketMinimal::getPacketTimeRaw(const uint8_t** timePtr, uint32_t* size) {
|
||||
if (timestampInterpreter == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return timestampInterpreter->getPacketTimeRaw(this, timePtr, size);
|
||||
}
|
||||
|
||||
void TmPacketMinimal::setInterpretTimestampObject(PacketTimestampInterpreterIF* interpreter) {
|
||||
if (TmPacketMinimal::timestampInterpreter == NULL) {
|
||||
TmPacketMinimal::timestampInterpreter = interpreter;
|
||||
}
|
||||
}
|
||||
|
||||
PacketTimestampInterpreterIF* TmPacketMinimal::timestampInterpreter = NULL;
|
||||
|
@ -1,16 +1,12 @@
|
||||
/*
|
||||
* TmPacketMinimal.h
|
||||
*
|
||||
* Created on: 09.03.2015
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORK_TMTCPACKET_PUS_TMPACKETMINIMAL_H_
|
||||
#define FRAMEWORK_TMTCPACKET_PUS_TMPACKETMINIMAL_H_
|
||||
|
||||
|
||||
#include <framework/tmtcpacket/SpacePacketBase.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
struct timeval;
|
||||
class PacketTimestampInterpreterIF;
|
||||
/**
|
||||
* This is a minimal version of a PUS TmPacket without any variable field, or,
|
||||
* in other words with Service Type, Subtype and subcounter only.
|
||||
@ -54,6 +50,11 @@ public:
|
||||
uint8_t subcounter;
|
||||
};
|
||||
|
||||
ReturnValue_t getPacketTime(timeval* timestamp);
|
||||
|
||||
ReturnValue_t getPacketTimeRaw(const uint8_t** timePtr, uint32_t* size);
|
||||
|
||||
static void setInterpretTimestampObject(PacketTimestampInterpreterIF* interpreter);
|
||||
/**
|
||||
* This struct defines the data structure of a PUS Telecommand Packet when
|
||||
* accessed via a pointer.
|
||||
@ -64,7 +65,8 @@ public:
|
||||
PUSTmMinimalHeader data_field;
|
||||
uint8_t rest;
|
||||
};
|
||||
static const uint16_t MINIMUM_SIZE = sizeof(TmPacketMinimalPointer) -1;
|
||||
//Must include a checksum and is therefore at least one larger than the above struct.
|
||||
static const uint16_t MINIMUM_SIZE = sizeof(TmPacketMinimalPointer) +1;
|
||||
protected:
|
||||
/**
|
||||
* A pointer to a structure which defines the data structure of
|
||||
@ -73,6 +75,8 @@ protected:
|
||||
* To be hardware-safe, all elements are of byte size.
|
||||
*/
|
||||
TmPacketMinimalPointer* tm_data;
|
||||
|
||||
static PacketTimestampInterpreterIF* timestampInterpreter;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,101 +1,105 @@
|
||||
/*
|
||||
* TmPacketStored.cpp
|
||||
*
|
||||
* Created on: 19.11.2012
|
||||
* Author: baetz
|
||||
*/
|
||||
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <framework/tmtcpacket/pus/TmPacket.h>
|
||||
#include <framework/tmtcpacket/pus/TmPacketStored.h>
|
||||
#include <framework/tmtcservices/TmTcMessage.h>
|
||||
#include <string.h>
|
||||
|
||||
TmPacketStored::TmPacketStored( store_address_t setAddress ) : TmPacketBase(NULL), storeAddress(setAddress) {
|
||||
this->setStoreAddress( this->storeAddress );
|
||||
}
|
||||
|
||||
TmPacketStored::TmPacketStored( uint16_t apid, uint8_t service,
|
||||
uint8_t subservice, uint8_t packet_counter, const uint8_t* data, uint32_t size,const uint8_t* headerData, uint32_t headerSize) : TmPacketBase(NULL) {
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
if ( this->checkAndSetStore() ) {
|
||||
TmPacket<TmPacketBase::TM_PACKET_MIN_SIZE> temp_packet( apid, service, subservice, packet_counter );
|
||||
uint8_t* p_data = NULL;
|
||||
ReturnValue_t returnValue = this->store->getFreeElement( &this->storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &p_data );
|
||||
if ( returnValue == this->store->RETURN_OK ) {
|
||||
memcpy(p_data, temp_packet.getWholeData(), temp_packet.getFullSize() );
|
||||
this->setData( p_data );
|
||||
memcpy( this->getSourceData(), headerData, headerSize );
|
||||
memcpy( this->getSourceData() + headerSize, data, size );
|
||||
this->setPacketDataLength( size + headerSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1 );
|
||||
this->setErrorControl();
|
||||
}
|
||||
}
|
||||
TmPacketStored::TmPacketStored(store_address_t setAddress) :
|
||||
TmPacketBase(NULL), storeAddress(setAddress) {
|
||||
setStoreAddress(storeAddress);
|
||||
}
|
||||
|
||||
TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
|
||||
uint8_t subservice, uint8_t packet_counter, SerializeIF* content,
|
||||
SerializeIF* header) : TmPacketBase(NULL) {
|
||||
uint8_t subservice, uint8_t packetSubcounter, const uint8_t* data,
|
||||
uint32_t size, const uint8_t* headerData, uint32_t headerSize) :
|
||||
TmPacketBase(NULL) {
|
||||
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
if ( checkAndSetStore() ) {
|
||||
TmPacket<TmPacketBase::TM_PACKET_MIN_SIZE> temp_packet( apid, service, subservice, packet_counter );
|
||||
uint32_t sourceDataSize = 0;
|
||||
if (content != NULL) {
|
||||
sourceDataSize += content->getSerializedSize();
|
||||
}
|
||||
if (header != NULL) {
|
||||
sourceDataSize += header->getSerializedSize();
|
||||
}
|
||||
uint8_t* p_data = NULL;
|
||||
ReturnValue_t returnValue = this->store->getFreeElement( &this->storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + sourceDataSize), &p_data );
|
||||
if ( returnValue == store->RETURN_OK ) {
|
||||
memcpy(p_data, temp_packet.getWholeData(), temp_packet.getFullSize() );
|
||||
this->setData( p_data );
|
||||
uint8_t* putDataHere = getSourceData();
|
||||
uint32_t size = 0;
|
||||
if (header != NULL) {
|
||||
header->serialize(&putDataHere, &size, sourceDataSize, true);
|
||||
}
|
||||
if (content != NULL) {
|
||||
content->serialize(&putDataHere, &size, sourceDataSize, true);
|
||||
}
|
||||
this->setPacketDataLength( sourceDataSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1 );
|
||||
this->setErrorControl();
|
||||
}
|
||||
if (!checkAndSetStore()) {
|
||||
return;
|
||||
}
|
||||
uint8_t* pData = NULL;
|
||||
ReturnValue_t returnValue = store->getFreeElement(&storeAddress,
|
||||
(TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData);
|
||||
|
||||
if (returnValue != store->RETURN_OK) {
|
||||
checkAndReportLostTm();
|
||||
return;
|
||||
}
|
||||
setData(pData);
|
||||
initializeTmPacket(apid, service, subservice, packetSubcounter);
|
||||
memcpy(getSourceData(), headerData, headerSize);
|
||||
memcpy(getSourceData() + headerSize, data, size);
|
||||
setPacketDataLength(
|
||||
size + headerSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
|
||||
}
|
||||
|
||||
TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
|
||||
uint8_t subservice, uint8_t packetSubcounter, SerializeIF* content,
|
||||
SerializeIF* header) :
|
||||
TmPacketBase(NULL) {
|
||||
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
if (!checkAndSetStore()) {
|
||||
return;
|
||||
}
|
||||
uint32_t sourceDataSize = 0;
|
||||
if (content != NULL) {
|
||||
sourceDataSize += content->getSerializedSize();
|
||||
}
|
||||
if (header != NULL) {
|
||||
sourceDataSize += header->getSerializedSize();
|
||||
}
|
||||
uint8_t* p_data = NULL;
|
||||
ReturnValue_t returnValue = store->getFreeElement(&storeAddress,
|
||||
(TmPacketBase::TM_PACKET_MIN_SIZE + sourceDataSize), &p_data);
|
||||
if (returnValue != store->RETURN_OK) {
|
||||
checkAndReportLostTm();
|
||||
}
|
||||
setData(p_data);
|
||||
initializeTmPacket(apid, service, subservice, packetSubcounter);
|
||||
uint8_t* putDataHere = getSourceData();
|
||||
uint32_t size = 0;
|
||||
if (header != NULL) {
|
||||
header->serialize(&putDataHere, &size, sourceDataSize, true);
|
||||
}
|
||||
if (content != NULL) {
|
||||
content->serialize(&putDataHere, &size, sourceDataSize, true);
|
||||
}
|
||||
setPacketDataLength(
|
||||
sourceDataSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
|
||||
}
|
||||
|
||||
store_address_t TmPacketStored::getStoreAddress() {
|
||||
return this->storeAddress;
|
||||
return storeAddress;
|
||||
}
|
||||
|
||||
void TmPacketStored::deletePacket() {
|
||||
this->store->deleteData( this->storeAddress );
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
this->setData( NULL );
|
||||
store->deleteData(storeAddress);
|
||||
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
setData(NULL);
|
||||
}
|
||||
|
||||
void TmPacketStored::setStoreAddress(store_address_t setAddress) {
|
||||
this->storeAddress = setAddress;
|
||||
storeAddress = setAddress;
|
||||
const uint8_t* temp_data = NULL;
|
||||
uint32_t temp_size;
|
||||
if (!checkAndSetStore()) {
|
||||
return;
|
||||
}
|
||||
ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, &temp_size );
|
||||
ReturnValue_t status = store->getData(storeAddress, &temp_data, &temp_size);
|
||||
if (status == StorageManagerIF::RETURN_OK) {
|
||||
this->setData(temp_data);
|
||||
setData(temp_data);
|
||||
} else {
|
||||
this->setData(NULL);
|
||||
this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
setData(NULL);
|
||||
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
bool TmPacketStored::checkAndSetStore() {
|
||||
if (this->store == NULL) {
|
||||
this->store = objectManager->get<StorageManagerIF>( objects::TM_STORE );
|
||||
if ( this->store == NULL ) {
|
||||
error << "TmPacketStored::TmPacketStored: TM Store not found!" << std::endl;
|
||||
if (store == NULL) {
|
||||
store = objectManager->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if (store == NULL) {
|
||||
error << "TmPacketStored::TmPacketStored: TM Store not found!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -103,3 +107,34 @@ bool TmPacketStored::checkAndSetStore() {
|
||||
}
|
||||
|
||||
StorageManagerIF* TmPacketStored::store = NULL;
|
||||
InternalErrorReporterIF* TmPacketStored::internalErrorReporter = NULL;
|
||||
|
||||
ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination,
|
||||
MessageQueueId_t sentFrom, bool doErrorReporting) {
|
||||
if (getWholeData() == NULL) {
|
||||
//SHOULDDO: More decent code.
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
TmTcMessage tmMessage(getStoreAddress());
|
||||
ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, &tmMessage, sentFrom);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
deletePacket();
|
||||
if (doErrorReporting) {
|
||||
checkAndReportLostTm();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//SHOULDDO: In many cases, some counter is incremented for successfully sent packets. The check is often not done, but just incremented.
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
void TmPacketStored::checkAndReportLostTm() {
|
||||
if (internalErrorReporter == NULL) {
|
||||
internalErrorReporter = objectManager->get<InternalErrorReporterIF>(
|
||||
objects::INTERNAL_ERROR_REPORTER);
|
||||
}
|
||||
if (internalErrorReporter != NULL) {
|
||||
internalErrorReporter->lostTm();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <framework/serialize/SerializeIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/tmtcpacket/pus/TmPacketBase.h>
|
||||
#include <framework/internalError/InternalErrorReporterIF.h>
|
||||
#include <framework/ipc/MessageQueueSenderIF.h>
|
||||
|
||||
/**
|
||||
* This class generates a ECSS PUS Telemetry packet within a given
|
||||
@ -24,6 +26,9 @@ private:
|
||||
* The default store is objects::TM_STORE.
|
||||
*/
|
||||
static StorageManagerIF* store;
|
||||
|
||||
static InternalErrorReporterIF *internalErrorReporter;
|
||||
|
||||
/**
|
||||
* The address where the packet data of the object instance is stored.
|
||||
*/
|
||||
@ -36,6 +41,8 @@ private:
|
||||
* @li \c false otherwise.
|
||||
*/
|
||||
bool checkAndSetStore();
|
||||
|
||||
void checkAndReportLostTm();
|
||||
public:
|
||||
/**
|
||||
* This is a default constructor which does not set the data pointer.
|
||||
@ -81,6 +88,8 @@ public:
|
||||
* @param setAddress The new packet id to link to.
|
||||
*/
|
||||
void setStoreAddress( store_address_t setAddress );
|
||||
|
||||
ReturnValue_t sendPacket( MessageQueueId_t destination, MessageQueueId_t sentFrom, bool doErrorReporting = true );
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user