Compare commits

...

36 Commits

Author SHA1 Message Date
bdfe31dba4 Merge branch 'mueller/pus-15-tm-storage' into develop 2023-02-24 19:03:21 +01:00
216f603d62 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-24 16:56:32 +01:00
174a6aa862 Merge pull request 'use timeval instead of uptime for stopwatch' (#125) from stopwatch-fix into develop
Reviewed-on: #125
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-02-24 16:51:28 +01:00
c2d9370aa1 Merge branch 'develop' into stopwatch-fix 2023-02-24 16:51:08 +01:00
893b434728 allow dest handler to handle folder destinations 2023-02-24 16:49:23 +01:00
6eba84566d use timeval instead of uptime 2023-02-24 16:39:49 +01:00
f0415a97b1 some fixes and improvements 2023-02-24 15:49:05 +01:00
abcf1b29b2 execution complete 2023-02-24 14:50:36 +01:00
d373c45d36 Merge branch 'develop' into mueller/pus-15-tm-storage 2023-02-22 15:45:54 +01:00
bd208038dd printout fixes 2023-02-22 15:45:39 +01:00
206af00c8b Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-21 11:14:19 +01:00
2a0c244468 add pus 15 store ID 2023-02-20 16:10:21 +01:00
e1711f0345 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-20 15:04:13 +01:00
b45206ccd6 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-20 13:33:10 +01:00
c745c0c8b4 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-17 13:18:09 +01:00
dae5e988fd Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-17 11:52:23 +01:00
70b785984c Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-14 17:33:59 +01:00
7f907fb9d3 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-08 17:17:33 +01:00
a1567de9e8 Merge branch 'develop' into mueller/pus-15-tm-storage 2023-02-07 12:21:35 +01:00
06dca7608a time stamper empty ctor 2023-02-07 12:06:34 +01:00
6af5274b68 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-07 10:51:17 +01:00
0cc3231ceb Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-01-23 14:20:38 +01:00
041d1b8795 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-01-11 09:17:57 +01:00
2aa4af6974 make function public 2022-12-14 13:50:57 +01:00
75fc7a056d Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-12-12 09:02:04 +01:00
1b005d706a Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-12-01 16:40:39 +01:00
e68f54b9bd Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-11-28 11:37:15 +01:00
296bc56e2a Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-11-24 15:16:34 +01:00
2b6a33e718 afmt 2022-11-11 14:13:46 +01:00
61fd5d1b62 impl function to generate ASCII timestamp sec accuracy 2022-11-11 14:12:42 +01:00
046dbe1deb Merge branch 'develop' into mueller/pus-15-tm-storage 2022-11-11 11:38:32 +01:00
0303c1a885 remove file 2022-11-11 11:31:22 +01:00
4d2802a470 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2022-11-11 11:29:29 +01:00
819a2bfac4 add prototype for new ToAscii CCSDSTime function 2022-10-25 18:20:48 +02:00
096af44e39 needs some fixing 2022-10-24 10:56:01 +02:00
56e8e5a8b3 dont know if I am going to need this 2022-10-24 10:39:43 +02:00
19 changed files with 261 additions and 123 deletions

View File

@@ -178,16 +178,25 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
dp.user.fileSegmentRecvdIndication(segParams); dp.user.fileSegmentRecvdIndication(segParams);
} }
result = dp.user.vfs.writeToFile(fileOpParams, fileData); result = dp.user.vfs.writeToFile(fileOpParams, fileData);
if (offset.value() + fileSegmentLen > tp.progress) {
tp.progress = offset.value() + fileSegmentLen;
}
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// TODO: Proper Error handling // TODO: Proper Error handling
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "File write error" << std::endl; sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2)
<< result << std::endl;
#endif #endif
tp.vfsErrorCount++;
if (tp.vfsErrorCount < 3) {
// TODO: Provide execution step as parameter
fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast<uint8_t>(fsmRes.step),
result);
}
return result;
} else { } else {
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE; tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
tp.vfsErrorCount = 0;
}
if (offset.value() + fileSegmentLen > tp.progress) {
tp.progress = offset.value() + fileSegmentLen;
} }
return result; return result;
} }
@@ -271,35 +280,55 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
return OK; return OK;
} }
ReturnValue_t result = OK; ReturnValue_t result = OK;
fsmRes.step = TransactionStep::TRANSACTION_START;
if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
} else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
}
tp.checksumType = info.getChecksumType();
tp.closureRequested = info.isClosureRequested();
size_t sourceNameSize = 0; size_t sourceNameSize = 0;
const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize); const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize);
if (sourceNameSize > tp.sourceName.size()) { if (sourceNameSize + 1 > tp.sourceName.size()) {
// TODO: Warning, event etc. fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large");
return FAILED; return FAILED;
} }
std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize); std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize);
tp.sourceName[sourceNameSize] = '\0'; tp.sourceName[sourceNameSize] = '\0';
size_t destNameSize = 0; size_t destNameSize = 0;
const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize); const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize);
if (destNameSize > tp.destName.size()) { if (destNameSize + 1 > tp.destName.size()) {
// TODO: Warning, event etc. fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large");
return FAILED; return FAILED;
} }
std::memcpy(tp.destName.data(), destNamePtr, destNameSize); std::memcpy(tp.destName.data(), destNamePtr, destNameSize);
tp.destName[destNameSize] = '\0'; tp.destName[destNameSize] = '\0';
reader.fillConfig(tp.pduConf);
tp.pduConf.direction = Direction::TOWARDS_SENDER; // If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
tp.transactionId.entityId = tp.pduConf.sourceId; // so there is no need to create a file or truncate an existing file
tp.transactionId.seqNum = tp.pduConf.seqNum; if (destNameSize > 0 and sourceNameSize > 0) {
if (not dp.remoteCfgTable.getRemoteCfg(tp.pduConf.sourceId, &tp.remoteCfg)) { FilesystemParams fparams(tp.destName.data());
// handling to allow only specifying target directory. Example:
// Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt
if (dp.user.vfs.isDirectory(tp.destName.data())) {
result = tryBuildingAbsoluteDestName(destNameSize);
if (result != OK) {
return result;
}
}
if (dp.user.vfs.fileExists(fparams)) {
result = dp.user.vfs.truncateFile(fparams);
if (result != returnvalue::OK) {
fileErrorHandler(events::FILESTORE_ERROR, result, "file truncation error");
return FAILED;
// TODO: Relevant for filestore rejection error?
}
} else {
result = dp.user.vfs.createFile(fparams);
if (result != OK) {
fileErrorHandler(events::FILESTORE_ERROR, result, "file creation error");
return FAILED;
// TODO: Relevant for filestore rejection error?
}
}
}
EntityId sourceId;
reader.getSourceId(sourceId);
if (not dp.remoteCfgTable.getRemoteCfg(sourceId, &tp.remoteCfg)) {
// TODO: Warning, event etc. // TODO: Warning, event etc.
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "cfdp::DestHandler" << __func__ sif::warning << "cfdp::DestHandler" << __func__
@@ -308,22 +337,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
#endif #endif
return FAILED; return FAILED;
} }
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU, fsmRes.step = TransactionStep::TRANSACTION_START;
// so there is no need to create a file or truncate an existing file if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) {
if (destNameSize > 0 and sourceNameSize > 0) { fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED;
FilesystemParams fparams(tp.destName.data()); } else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) {
// TODO: Filesystem errors? fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED;
if (dp.user.vfs.fileExists(fparams)) {
dp.user.vfs.truncateFile(fparams);
} else {
result = dp.user.vfs.createFile(fparams);
if (result != OK) {
// TODO: Handle FS error. This is probably a case for the filestore rejection mechanism of
// CFDP.
// In any case, it does not really make sense to continue here
}
}
} }
tp.checksumType = info.getChecksumType();
tp.closureRequested = info.isClosureRequested();
reader.fillConfig(tp.pduConf);
tp.pduConf.direction = Direction::TOWARDS_SENDER;
tp.transactionId.entityId = tp.pduConf.sourceId;
tp.transactionId.seqNum = tp.pduConf.seqNum;
fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS; fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS;
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId); MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
params.fileSize = tp.fileSize.getSize(); params.fileSize = tp.fileSize.getSize();
@@ -362,6 +387,37 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
return OK; return OK;
} }
ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize) {
char baseNameBuf[tp.destName.size()]{};
FilesystemParams fparamsSrc(tp.sourceName.data());
size_t baseNameLen = 0;
ReturnValue_t result =
dp.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf, sizeof(baseNameBuf), baseNameLen);
if (result != returnvalue::OK or baseNameLen == 0) {
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "error retrieving source base name");
return FAILED;
}
// Destination name + slash + base name + null termination
if (destNameSize + 1 + baseNameLen + 1 > tp.destName.size()) {
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0,
"dest filename too large after adding source base name");
return FAILED;
}
tp.destName[destNameSize++] = '/';
std::memcpy(tp.destName.data() + destNameSize, baseNameBuf, baseNameLen);
destNameSize += baseNameLen;
tp.destName[destNameSize++] = '\0';
return OK;
}
void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, const char* info) {
fp.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR,
static_cast<uint8_t>(fsmRes.step), result);
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "cfdp::DestHandler: " << info << std::endl;
#endif
}
void cfdp::DestHandler::finish() { void cfdp::DestHandler::finish() {
tp.reset(); tp.reset();
dp.packetListRef.clear(); dp.packetListRef.clear();

View File

@@ -84,7 +84,7 @@ enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
class DestHandler { class DestHandler {
public: public:
enum class TransactionStep { enum class TransactionStep : uint8_t {
IDLE = 0, IDLE = 0,
TRANSACTION_START = 1, TRANSACTION_START = 1,
RECEIVING_FILE_DATA_PDUS = 2, RECEIVING_FILE_DATA_PDUS = 2,
@@ -157,11 +157,13 @@ class DestHandler {
progress = 0; progress = 0;
remoteCfg = nullptr; remoteCfg = nullptr;
closureRequested = false; closureRequested = false;
vfsErrorCount = 0;
checksumType = ChecksumType::NULL_CHECKSUM; checksumType = ChecksumType::NULL_CHECKSUM;
} }
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM; ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
bool closureRequested = false; bool closureRequested = false;
uint16_t vfsErrorCount = 0;
std::vector<char> sourceName; std::vector<char> sourceName;
std::vector<char> destName; std::vector<char> destName;
cfdp::FileSize fileSize; cfdp::FileSize fileSize;
@@ -189,9 +191,11 @@ class DestHandler {
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData, ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
size_t maxSize); size_t maxSize);
ReturnValue_t handleTransferCompletion(); ReturnValue_t handleTransferCompletion();
ReturnValue_t tryBuildingAbsoluteDestName(size_t destNameSize);
ReturnValue_t sendFinishedPdu(); ReturnValue_t sendFinishedPdu();
ReturnValue_t noticeOfCompletion(); ReturnValue_t noticeOfCompletion();
ReturnValue_t checksumVerification(); ReturnValue_t checksumVerification();
void fileErrorHandler(Event event, ReturnValue_t result, const char* info);
const FsmResult& updateFsmRes(uint8_t errors); const FsmResult& updateFsmRes(uint8_t errors);
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx); void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
void finish(); void finish();

View File

@@ -12,6 +12,9 @@ namespace events {
static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW); static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW);
static constexpr Event MSG_QUEUE_ERROR = event::makeEvent(SSID, 1, severity::LOW); static constexpr Event MSG_QUEUE_ERROR = event::makeEvent(SSID, 1, severity::LOW);
static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity::LOW); static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity::LOW);
static constexpr Event FILESTORE_ERROR = event::makeEvent(SSID, 3, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name
static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, severity::LOW);
} // namespace events } // namespace events

View File

@@ -74,6 +74,12 @@ class HasFileSystemIF {
return MessageQueueIF::NO_QUEUE; return MessageQueueIF::NO_QUEUE;
} }
// Get the base filename without the full directory path
virtual ReturnValue_t getBaseFilename(FilesystemParams params, char* nameBuf, size_t maxLen,
size_t& baseNameLen) = 0;
virtual bool isDirectory(const char* path) = 0;
virtual bool fileExists(FilesystemParams params) = 0; virtual bool fileExists(FilesystemParams params) = 0;
/** /**

View File

@@ -15,6 +15,7 @@ enum framework_objects : object_id_t {
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008, PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
PUS_SERVICE_9_TIME_MGMT = 0x53000009, PUS_SERVICE_9_TIME_MGMT = 0x53000009,
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011, PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
PUS_SERVICE_15_TM_STORAGE = 0x53000015,
PUS_SERVICE_17_TEST = 0x53000017, PUS_SERVICE_17_TEST = 0x53000017,
PUS_SERVICE_20_PARAMETERS = 0x53000020, PUS_SERVICE_20_PARAMETERS = 0x53000020,
PUS_SERVICE_200_MODE_MGMT = 0x53000200, PUS_SERVICE_200_MODE_MGMT = 0x53000200,

View File

@@ -79,7 +79,7 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message,
} }
case (Subservice::COMMAND_ANNOUNCE_HEALTH): { case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE); HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
break; return CommandingServiceBase::EXECUTION_COMPLETE;
} }
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): { case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
ReturnValue_t result = iterateHealthTable(true); ReturnValue_t result = iterateHealthTable(true);

View File

@@ -15,10 +15,10 @@ ReturnValue_t FixedTimeslotTaskBase::addSlot(object_id_t execId, ExecutableObjec
uint32_t slotTimeMs, int8_t executionStep) { uint32_t slotTimeMs, int8_t executionStep) {
if (execObj == nullptr) { if (execObj == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "Component 0x" << std::hex << std::setw(8) << std::setfill('0') << execObj sif::error << "Component 0x" << std::hex << std::setw(8) << std::setfill('0') << execId
<< std::setfill(' ') << " not found, not adding it to PST" << std::dec << std::endl; << std::setfill(' ') << " not found, not adding it to PST" << std::dec << std::endl;
#else #else
sif::printError("Component 0x%08x not found, not adding it to PST\n"); sif::printError("Component 0x%08x not found, not adding it to PST\n", execId);
#endif #endif
return returnvalue::FAILED; return returnvalue::FAILED;
} }

View File

@@ -246,6 +246,20 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t*
return UNSUPPORTED_TIME_FORMAT; return UNSUPPORTED_TIME_FORMAT;
} }
ReturnValue_t CCSDSTime::convertToAsciiWithSecs(int8_t* to, const Clock::TimeOfDay_t* from,
uint8_t length) {
if (from == nullptr or to == nullptr) {
return returnvalue::FAILED;
}
int count = snprintf(reinterpret_cast<char*>(to), length,
"%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32,
from->year, from->month, from->day, from->hour, from->minute, from->second);
if (count >= length) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) { ReturnValue_t CCSDSTime::checkCcs(const uint8_t* time, uint8_t length) {
const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time); const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time);

View File

@@ -207,7 +207,8 @@ class CCSDSTime {
static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from, static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from,
uint8_t length); uint8_t length);
static ReturnValue_t convertToAsciiWithSecs(int8_t *to, const Clock::TimeOfDay_t *from,
uint8_t length);
static uint32_t subsecondsToMicroseconds(uint16_t subseconds); static uint32_t subsecondsToMicroseconds(uint16_t subseconds);
private: private:

View File

@@ -9,7 +9,7 @@
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode) Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) { : displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
// Measures start time on initialization. // Measures start time on initialization.
Clock::getUptime(&startTime); Clock::getClock_timeval(&startTime);
} }
void Stopwatch::start() { Clock::getUptime(&startTime); } void Stopwatch::start() { Clock::getUptime(&startTime); }
@@ -63,6 +63,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
void Stopwatch::stopInternal() { void Stopwatch::stopInternal() {
timeval endTime; timeval endTime;
Clock::getUptime(&endTime); Clock::getClock_timeval(&endTime);
elapsedTime = endTime - startTime; elapsedTime = endTime - startTime;
} }

View File

@@ -6,47 +6,12 @@
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "tmStorageConf.h" #include "tmStorageConf.h"
class TmPacketMinimal; class PusTmReader;
class SpacePacketBase; class SpacePacketReader;
class TmStoreBackendIF; class TmStoreBackendIF;
class TmStoreFrontendIF { class TmStoreFrontendIF {
public: public:
virtual TmStoreBackendIF* getBackend() const = 0;
/**
* What do I need to implement here?
* This is propably used by PUS Service 15 so we should propably check for messages..
* Provide base implementation?
* @param opCode
* @return
*/
virtual ReturnValue_t performOperation(uint8_t opCode) = 0;
/**
* Callback from the back-end to indicate a certain packet was received.
* front-end takes care of discarding/downloading the packet.
* @param packet Pointer to the newly received Space Packet.
* @param address Start address of the packet found
* @param isLastPacket Indicates if no more packets can be fetched.
* @return If more packets shall be fetched, returnvalue::OK must be returned.
* Any other code stops fetching packets.
*/
virtual ReturnValue_t packetRetrieved(TmPacketMinimal* packet, uint32_t address) = 0;
virtual void noMorePacketsInStore() = 0;
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) = 0;
/**
* To get the queue where commands shall be sent.
* @return Id of command queue.
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
virtual ReturnValue_t checkPacket(SpacePacketBase* tmPacket) = 0;
virtual bool isEnabled() const = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void resetDownlinkedPacketCount() = 0;
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF; static const uint8_t INTERFACE_ID = CLASS_ID::TM_STORE_FRONTEND_IF;
static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1); static const ReturnValue_t BUSY = MAKE_RETURN_CODE(1);
static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2); static const ReturnValue_t LAST_PACKET_FOUND = MAKE_RETURN_CODE(2);
@@ -57,7 +22,38 @@ class TmStoreFrontendIF {
static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7); static const ReturnValue_t ALL_DELETED = MAKE_RETURN_CODE(7);
static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8); static const ReturnValue_t INVALID_DATA = MAKE_RETURN_CODE(8);
static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9); static const ReturnValue_t NOT_READY = MAKE_RETURN_CODE(9);
virtual ~TmStoreFrontendIF() {}
virtual ~TmStoreFrontendIF() = default;
/**
* To get the queue where commands shall be sent.
* @return Id of command queue.
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
virtual TmStoreBackendIF* getBackend() const = 0;
/**
* Callback from the back-end to indicate a certain packet was received.
* front-end takes care of discarding/downloading the packet.
* @param packet Pointer to the newly received Space Packet.
* @param address Start address of the packet found
* @param isLastPacket Indicates if no more packets can be fetched.
* @return If more packets shall be fetched, returnvalue::OK must be returned.
* Any other code stops fetching packets.
*/
virtual ReturnValue_t packetRetrieved(PusTmReader* packet, uint32_t address) = 0;
virtual void noMorePacketsInStore() = 0;
virtual void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0,
uint32_t parameter2 = 0) = 0;
virtual ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) = 0;
virtual ReturnValue_t deletePackets(ApidSsc upTo) = 0;
virtual ReturnValue_t checkPacket(SpacePacketReader* tmPacket) = 0;
virtual bool isEnabled() const = 0;
virtual void setEnabled(bool enabled) = 0;
virtual void resetDownlinkedPacketCount() = 0;
virtual ReturnValue_t setDumpTarget(object_id_t dumpTarget) = 0;
}; };
#endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */ #endif /* FSFW_TMTCSERVICES_TMSTOREFRONTENDIF_H_ */

View File

@@ -0,0 +1,15 @@
#ifndef FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
#define FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_
#include <fsfw/ipc/messageQueueDefinitions.h>
class TmStoreFrontendSimpleIF {
public:
virtual ~TmStoreFrontendSimpleIF() = default;
virtual MessageQueueId_t getCommandQueue() const = 0;
private:
};
#endif /* FSFW_SRC_FSFW_TMSTORAGE_TMSTOREBACKENDSIMPLEIF_H_ */

View File

@@ -1,6 +1,10 @@
#ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_ #ifndef FSFW_TMSTORAGE_TMSTOREPACKETS_H_
#define FSFW_TMSTORAGE_TMSTOREPACKETS_H_ #define FSFW_TMSTORAGE_TMSTOREPACKETS_H_
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
#include <vector>
#include "fsfw/globalfunctions/timevalOperations.h" #include "fsfw/globalfunctions/timevalOperations.h"
#include "fsfw/serialize/SerialBufferAdapter.h" #include "fsfw/serialize/SerialBufferAdapter.h"
#include "fsfw/serialize/SerialFixedArrayListAdapter.h" #include "fsfw/serialize/SerialFixedArrayListAdapter.h"
@@ -24,7 +28,7 @@ class ServiceSubservice : public SerialLinkedListAdapter<SerializeIF> {
class ApidSsc : public SerializeIF { class ApidSsc : public SerializeIF {
public: public:
ApidSsc() : apid(SpacePacketBase::LIMIT_APID), ssc(0) {} ApidSsc() : apid(ccsds::LIMIT_APID), ssc(0) {}
ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {} ApidSsc(uint16_t apid, uint16_t ssc) : apid(apid), ssc(ssc) {}
uint16_t apid; uint16_t apid;
uint16_t ssc; uint16_t ssc;
@@ -62,51 +66,59 @@ class ChangeSelectionDefinition : public SerialLinkedListAdapter<SerializeIF> {
class TmPacketInformation : public SerializeIF { class TmPacketInformation : public SerializeIF {
public: public:
TmPacketInformation(TmPacketMinimal* packet) { setContent(packet); } TmPacketInformation(PusTmReader* packet, size_t timestampLen) : rawTimestamp(timestampLen) {
TmPacketInformation() setContent(packet);
: apid(SpacePacketBase::LIMIT_APID), }
TmPacketInformation(size_t timestampLen)
: apid(ccsds::LIMIT_APID),
sourceSequenceCount(0), sourceSequenceCount(0),
serviceType(0), serviceType(0),
serviceSubtype(0), serviceSubtype(0),
subCounter(0) {} subCounter(0),
rawTimestamp(timestampLen) {}
void reset() { void reset() {
apid = SpacePacketBase::LIMIT_APID; apid = ccsds::LIMIT_APID;
sourceSequenceCount = 0; sourceSequenceCount = 0;
serviceType = 0; serviceType = 0;
serviceSubtype = 0; serviceSubtype = 0;
subCounter = 0; subCounter = 0;
memset(rawTimestamp, 0, sizeof(rawTimestamp)); memset(rawTimestamp.data(), 0, rawTimestamp.size());
} }
void setContent(TmPacketMinimal* packet) { void setContent(PusTmReader* packet) {
apid = packet->getAPID(); apid = packet->getApid();
sourceSequenceCount = packet->getPacketSequenceCount(); sourceSequenceCount = packet->getSequenceCount();
serviceType = packet->getService(); serviceType = packet->getService();
serviceSubtype = packet->getSubService(); serviceSubtype = packet->getSubService();
subCounter = packet->getPacketSubcounter(); subCounter = packet->getMessageTypeCounter();
memset(rawTimestamp, 0, sizeof(rawTimestamp)); memset(rawTimestamp.data(), 0, rawTimestamp.size());
const uint8_t* pField = NULL; // TODO: Fix all of this
uint32_t size = 0; // const uint8_t* pField = NULL;
ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size); // uint32_t size = 0;
if (result != returnvalue::OK) { // auto* timeReader = packet->getTimeReader();
return; // ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
} // if (result != returnvalue::OK) {
if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE) { // return;
// Shortcut to avoid converting CDS back and forth. //}
memcpy(rawTimestamp, pField, size); // if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE)
return; // {
} // Shortcut to avoid converting CDS back and forth.
timeval time = {0, 0}; // TODO: Fix
result = packet->getPacketTime(&time); // memcpy(rawTimestamp, pField, size);
if (result != returnvalue::OK) { // return;
return; // }
} // timeval time = {0, 0};
// result = packet->getPacketTime(&time);
CCSDSTime::CDS_short cdsFormat; // if (result != returnvalue::OK) {
result = CCSDSTime::convertToCcsds(&cdsFormat, &time); // return;
if (result != returnvalue::OK) { // }
return; //
} // CCSDSTime::CDS_short cdsFormat;
memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat)); // result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
// if (result != returnvalue::OK) {
// return;
// }
// TODO: Fix
// memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
} }
void setContent(TmPacketInformation* content) { void setContent(TmPacketInformation* content) {
apid = content->apid; apid = content->apid;
@@ -114,9 +126,10 @@ class TmPacketInformation : public SerializeIF {
serviceType = content->serviceType; serviceType = content->serviceType;
serviceSubtype = content->serviceSubtype; serviceSubtype = content->serviceSubtype;
subCounter = content->subCounter; subCounter = content->subCounter;
memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp)); // TODO: Fix
// memcpy(rawTimestamp, content->rawTimestamp, sizeof(rawTimestamp));
} }
bool isValid() const { return (apid < SpacePacketBase::LIMIT_APID) ? true : false; } bool isValid() const { return (apid < ccsds::LIMIT_APID) ? true : false; }
static void reset(TmPacketInformation* packet) { packet->reset(); } static void reset(TmPacketInformation* packet) { packet->reset(); }
static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) { static bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) {
@@ -216,7 +229,7 @@ class TmPacketInformation : public SerializeIF {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp)); SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
return adapter.serialize(buffer, size, maxSize, streamEndianness); return adapter.serialize(buffer, size, maxSize, streamEndianness);
} }
@@ -227,7 +240,7 @@ class TmPacketInformation : public SerializeIF {
size += SerializeAdapter::getSerializedSize(&serviceType); size += SerializeAdapter::getSerializedSize(&serviceType);
size += SerializeAdapter::getSerializedSize(&serviceSubtype); size += SerializeAdapter::getSerializedSize(&serviceSubtype);
size += SerializeAdapter::getSerializedSize(&subCounter); size += SerializeAdapter::getSerializedSize(&subCounter);
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp)); SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
size += adapter.getSerializedSize(); size += adapter.getSerializedSize();
return size; return size;
}; };
@@ -253,7 +266,7 @@ class TmPacketInformation : public SerializeIF {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp)); SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
return adapter.deSerialize(buffer, size, streamEndianness); return adapter.deSerialize(buffer, size, streamEndianness);
} }
@@ -263,6 +276,6 @@ class TmPacketInformation : public SerializeIF {
uint8_t serviceType; uint8_t serviceType;
uint8_t serviceSubtype; uint8_t serviceSubtype;
uint8_t subCounter; uint8_t subCounter;
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE]; std::vector<uint8_t> rawTimestamp;
}; };
#endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */ #endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */

View File

@@ -160,3 +160,18 @@ ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
ofstream of(path); ofstream of(path);
return returnvalue::OK; return returnvalue::OK;
} }
bool HostFilesystem::isDirectory(const char *path) { return filesystem::is_directory(path); }
ReturnValue_t HostFilesystem::getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
size_t &baseNameLen) {
std::string path(params.path);
std::string baseName = path.substr(path.find_last_of("/\\") + 1);
if (baseName.size() + 1 > maxLen) {
return returnvalue::FAILED;
}
std::memcpy(nameBuf, baseName.c_str(), baseName.size());
nameBuf[baseName.size()] = '\0';
baseNameLen = baseName.size();
return returnvalue::OK;
}

View File

@@ -9,6 +9,9 @@ class HostFilesystem : public HasFileSystemIF {
public: public:
HostFilesystem(); HostFilesystem();
ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
size_t &baseNameLen) override;
bool isDirectory(const char *path) override;
bool fileExists(FilesystemParams params) override; bool fileExists(FilesystemParams params) override;
ReturnValue_t truncateFile(FilesystemParams params) override; ReturnValue_t truncateFile(FilesystemParams params) override;
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override; ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;

View File

@@ -2,7 +2,6 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <fsfw_hal/linux/serial/SerialComIF.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <fsfw_hal/linux/spi/SpiCookie.h> #include <fsfw_hal/linux/spi/SpiCookie.h>
#include "fsfw/ipc/MutexIF.h" #include "fsfw/ipc/MutexIF.h"
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/GpioIF.h"

View File

@@ -138,3 +138,10 @@ ReturnValue_t FilesystemMock::truncateFile(FilesystemParams params) {
truncateCalledOnFile = params.path; truncateCalledOnFile = params.path;
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t FilesystemMock::getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
size_t &baseNameLen) {
return returnvalue::OK;
}
bool FilesystemMock::isDirectory(const char *path) { return false; }

View File

@@ -56,6 +56,10 @@ class FilesystemMock : public HasFileSystemIF {
std::string truncateCalledOnFile; std::string truncateCalledOnFile;
ReturnValue_t feedFile(const std::string &filename, std::ifstream &file); ReturnValue_t feedFile(const std::string &filename, std::ifstream &file);
ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
size_t &baseNameLen) override;
bool isDirectory(const char *path) override;
bool fileExists(FilesystemParams params) override; bool fileExists(FilesystemParams params) override;
ReturnValue_t truncateFile(FilesystemParams params) override; ReturnValue_t truncateFile(FilesystemParams params) override;