Compare commits
35 Commits
bd208038dd
...
bdfe31dba4
Author | SHA1 | Date | |
---|---|---|---|
bdfe31dba4 | |||
216f603d62 | |||
174a6aa862 | |||
c2d9370aa1 | |||
893b434728 | |||
6eba84566d | |||
f0415a97b1 | |||
abcf1b29b2 | |||
d373c45d36 | |||
206af00c8b | |||
2a0c244468 | |||
e1711f0345 | |||
b45206ccd6 | |||
c745c0c8b4 | |||
dae5e988fd | |||
70b785984c | |||
7f907fb9d3 | |||
a1567de9e8 | |||
06dca7608a | |||
6af5274b68 | |||
0cc3231ceb | |||
041d1b8795 | |||
2aa4af6974 | |||
75fc7a056d | |||
1b005d706a | |||
e68f54b9bd | |||
296bc56e2a | |||
2b6a33e718 | |||
61fd5d1b62 | |||
046dbe1deb | |||
0303c1a885 | |||
4d2802a470 | |||
819a2bfac4 | |||
096af44e39 | |||
56e8e5a8b3 |
@@ -178,16 +178,25 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
||||
dp.user.fileSegmentRecvdIndication(segParams);
|
||||
}
|
||||
result = dp.user.vfs.writeToFile(fileOpParams, fileData);
|
||||
if (offset.value() + fileSegmentLen > tp.progress) {
|
||||
tp.progress = offset.value() + fileSegmentLen;
|
||||
}
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Proper Error handling
|
||||
#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
|
||||
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 {
|
||||
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
||||
tp.vfsErrorCount = 0;
|
||||
}
|
||||
if (offset.value() + fileSegmentLen > tp.progress) {
|
||||
tp.progress = offset.value() + fileSegmentLen;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -271,35 +280,55 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
||||
return 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;
|
||||
|
||||
const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize);
|
||||
if (sourceNameSize > tp.sourceName.size()) {
|
||||
// TODO: Warning, event etc.
|
||||
if (sourceNameSize + 1 > tp.sourceName.size()) {
|
||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large");
|
||||
return FAILED;
|
||||
}
|
||||
std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize);
|
||||
tp.sourceName[sourceNameSize] = '\0';
|
||||
size_t destNameSize = 0;
|
||||
const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize);
|
||||
if (destNameSize > tp.destName.size()) {
|
||||
// TODO: Warning, event etc.
|
||||
if (destNameSize + 1 > tp.destName.size()) {
|
||||
fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large");
|
||||
return FAILED;
|
||||
}
|
||||
std::memcpy(tp.destName.data(), destNamePtr, destNameSize);
|
||||
tp.destName[destNameSize] = '\0';
|
||||
reader.fillConfig(tp.pduConf);
|
||||
tp.pduConf.direction = Direction::TOWARDS_SENDER;
|
||||
tp.transactionId.entityId = tp.pduConf.sourceId;
|
||||
tp.transactionId.seqNum = tp.pduConf.seqNum;
|
||||
if (not dp.remoteCfgTable.getRemoteCfg(tp.pduConf.sourceId, &tp.remoteCfg)) {
|
||||
|
||||
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
||||
// so there is no need to create a file or truncate an existing file
|
||||
if (destNameSize > 0 and sourceNameSize > 0) {
|
||||
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.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "cfdp::DestHandler" << __func__
|
||||
@@ -308,22 +337,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
||||
#endif
|
||||
return FAILED;
|
||||
}
|
||||
// If both dest name size and source name size are 0, we are dealing with a metadata only PDU,
|
||||
// so there is no need to create a file or truncate an existing file
|
||||
if (destNameSize > 0 and sourceNameSize > 0) {
|
||||
FilesystemParams fparams(tp.destName.data());
|
||||
// TODO: Filesystem errors?
|
||||
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
|
||||
}
|
||||
}
|
||||
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();
|
||||
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;
|
||||
MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId);
|
||||
params.fileSize = tp.fileSize.getSize();
|
||||
@@ -362,6 +387,37 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||
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() {
|
||||
tp.reset();
|
||||
dp.packetListRef.clear();
|
||||
|
@@ -84,7 +84,7 @@ enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN };
|
||||
|
||||
class DestHandler {
|
||||
public:
|
||||
enum class TransactionStep {
|
||||
enum class TransactionStep : uint8_t {
|
||||
IDLE = 0,
|
||||
TRANSACTION_START = 1,
|
||||
RECEIVING_FILE_DATA_PDUS = 2,
|
||||
@@ -157,11 +157,13 @@ class DestHandler {
|
||||
progress = 0;
|
||||
remoteCfg = nullptr;
|
||||
closureRequested = false;
|
||||
vfsErrorCount = 0;
|
||||
checksumType = ChecksumType::NULL_CHECKSUM;
|
||||
}
|
||||
|
||||
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
||||
bool closureRequested = false;
|
||||
uint16_t vfsErrorCount = 0;
|
||||
std::vector<char> sourceName;
|
||||
std::vector<char> destName;
|
||||
cfdp::FileSize fileSize;
|
||||
@@ -189,9 +191,11 @@ class DestHandler {
|
||||
ReturnValue_t handleMetadataParseError(ReturnValue_t result, const uint8_t* rawData,
|
||||
size_t maxSize);
|
||||
ReturnValue_t handleTransferCompletion();
|
||||
ReturnValue_t tryBuildingAbsoluteDestName(size_t destNameSize);
|
||||
ReturnValue_t sendFinishedPdu();
|
||||
ReturnValue_t noticeOfCompletion();
|
||||
ReturnValue_t checksumVerification();
|
||||
void fileErrorHandler(Event event, ReturnValue_t result, const char* info);
|
||||
const FsmResult& updateFsmRes(uint8_t errors);
|
||||
void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx);
|
||||
void finish();
|
||||
|
@@ -12,6 +12,9 @@ namespace events {
|
||||
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 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
|
||||
|
||||
|
@@ -74,6 +74,12 @@ class HasFileSystemIF {
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@@ -15,6 +15,7 @@ enum framework_objects : object_id_t {
|
||||
PUS_SERVICE_8_FUNCTION_MGMT = 0x53000008,
|
||||
PUS_SERVICE_9_TIME_MGMT = 0x53000009,
|
||||
PUS_SERVICE_11_TC_SCHEDULER = 0x53000011,
|
||||
PUS_SERVICE_15_TM_STORAGE = 0x53000015,
|
||||
PUS_SERVICE_17_TEST = 0x53000017,
|
||||
PUS_SERVICE_20_PARAMETERS = 0x53000020,
|
||||
PUS_SERVICE_200_MODE_MGMT = 0x53000200,
|
||||
|
@@ -79,7 +79,7 @@ ReturnValue_t CServiceHealthCommanding::prepareCommand(CommandMessage *message,
|
||||
}
|
||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH): {
|
||||
HealthMessage::setHealthMessage(message, HealthMessage::HEALTH_ANNOUNCE);
|
||||
break;
|
||||
return CommandingServiceBase::EXECUTION_COMPLETE;
|
||||
}
|
||||
case (Subservice::COMMAND_ANNOUNCE_HEALTH_ALL): {
|
||||
ReturnValue_t result = iterateHealthTable(true);
|
||||
|
@@ -246,6 +246,20 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t*
|
||||
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) {
|
||||
const Ccs_mseconds* time_struct = reinterpret_cast<const Ccs_mseconds*>(time);
|
||||
|
||||
|
@@ -207,7 +207,8 @@ class CCSDSTime {
|
||||
|
||||
static ReturnValue_t convertFromASCII(Clock::TimeOfDay_t *to, uint8_t const *from,
|
||||
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);
|
||||
|
||||
private:
|
||||
|
@@ -9,7 +9,7 @@
|
||||
Stopwatch::Stopwatch(bool displayOnDestruction, StopwatchDisplayMode displayMode)
|
||||
: displayOnDestruction(displayOnDestruction), displayMode(displayMode) {
|
||||
// Measures start time on initialization.
|
||||
Clock::getUptime(&startTime);
|
||||
Clock::getClock_timeval(&startTime);
|
||||
}
|
||||
|
||||
void Stopwatch::start() { Clock::getUptime(&startTime); }
|
||||
@@ -63,6 +63,6 @@ StopwatchDisplayMode Stopwatch::getDisplayMode() const { return displayMode; }
|
||||
|
||||
void Stopwatch::stopInternal() {
|
||||
timeval endTime;
|
||||
Clock::getUptime(&endTime);
|
||||
Clock::getClock_timeval(&endTime);
|
||||
elapsedTime = endTime - startTime;
|
||||
}
|
||||
|
@@ -6,47 +6,12 @@
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "tmStorageConf.h"
|
||||
|
||||
class TmPacketMinimal;
|
||||
class SpacePacketBase;
|
||||
class PusTmReader;
|
||||
class SpacePacketReader;
|
||||
class TmStoreBackendIF;
|
||||
|
||||
class TmStoreFrontendIF {
|
||||
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 ReturnValue_t BUSY = MAKE_RETURN_CODE(1);
|
||||
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 INVALID_DATA = MAKE_RETURN_CODE(8);
|
||||
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_ */
|
||||
|
15
src/fsfw/tmstorage/TmStoreFrontendSimpleIF.h
Normal file
15
src/fsfw/tmstorage/TmStoreFrontendSimpleIF.h
Normal 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_ */
|
@@ -1,6 +1,10 @@
|
||||
#ifndef 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/serialize/SerialBufferAdapter.h"
|
||||
#include "fsfw/serialize/SerialFixedArrayListAdapter.h"
|
||||
@@ -24,7 +28,7 @@ class ServiceSubservice : public SerialLinkedListAdapter<SerializeIF> {
|
||||
|
||||
class ApidSsc : public SerializeIF {
|
||||
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) {}
|
||||
uint16_t apid;
|
||||
uint16_t ssc;
|
||||
@@ -62,51 +66,59 @@ class ChangeSelectionDefinition : public SerialLinkedListAdapter<SerializeIF> {
|
||||
|
||||
class TmPacketInformation : public SerializeIF {
|
||||
public:
|
||||
TmPacketInformation(TmPacketMinimal* packet) { setContent(packet); }
|
||||
TmPacketInformation()
|
||||
: apid(SpacePacketBase::LIMIT_APID),
|
||||
TmPacketInformation(PusTmReader* packet, size_t timestampLen) : rawTimestamp(timestampLen) {
|
||||
setContent(packet);
|
||||
}
|
||||
TmPacketInformation(size_t timestampLen)
|
||||
: apid(ccsds::LIMIT_APID),
|
||||
sourceSequenceCount(0),
|
||||
serviceType(0),
|
||||
serviceSubtype(0),
|
||||
subCounter(0) {}
|
||||
subCounter(0),
|
||||
rawTimestamp(timestampLen) {}
|
||||
void reset() {
|
||||
apid = SpacePacketBase::LIMIT_APID;
|
||||
apid = ccsds::LIMIT_APID;
|
||||
sourceSequenceCount = 0;
|
||||
serviceType = 0;
|
||||
serviceSubtype = 0;
|
||||
subCounter = 0;
|
||||
memset(rawTimestamp, 0, sizeof(rawTimestamp));
|
||||
memset(rawTimestamp.data(), 0, rawTimestamp.size());
|
||||
}
|
||||
void setContent(TmPacketMinimal* packet) {
|
||||
apid = packet->getAPID();
|
||||
sourceSequenceCount = packet->getPacketSequenceCount();
|
||||
void setContent(PusTmReader* packet) {
|
||||
apid = packet->getApid();
|
||||
sourceSequenceCount = packet->getSequenceCount();
|
||||
serviceType = packet->getService();
|
||||
serviceSubtype = packet->getSubService();
|
||||
subCounter = packet->getPacketSubcounter();
|
||||
memset(rawTimestamp, 0, sizeof(rawTimestamp));
|
||||
const uint8_t* pField = NULL;
|
||||
uint32_t size = 0;
|
||||
ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE) {
|
||||
// Shortcut to avoid converting CDS back and forth.
|
||||
memcpy(rawTimestamp, pField, size);
|
||||
return;
|
||||
}
|
||||
timeval time = {0, 0};
|
||||
result = packet->getPacketTime(&time);
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
CCSDSTime::CDS_short cdsFormat;
|
||||
result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
|
||||
if (result != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
|
||||
subCounter = packet->getMessageTypeCounter();
|
||||
memset(rawTimestamp.data(), 0, rawTimestamp.size());
|
||||
// TODO: Fix all of this
|
||||
// const uint8_t* pField = NULL;
|
||||
// uint32_t size = 0;
|
||||
// auto* timeReader = packet->getTimeReader();
|
||||
// ReturnValue_t result = packet->getPacketTimeRaw(&pField, &size);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return;
|
||||
//}
|
||||
// if (*pField == CCSDSTime::P_FIELD_CDS_SHORT && size <= TimeStamperIF::MISSION_TIMESTAMP_SIZE)
|
||||
// {
|
||||
// Shortcut to avoid converting CDS back and forth.
|
||||
// TODO: Fix
|
||||
// memcpy(rawTimestamp, pField, size);
|
||||
// return;
|
||||
// }
|
||||
// timeval time = {0, 0};
|
||||
// result = packet->getPacketTime(&time);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// CCSDSTime::CDS_short cdsFormat;
|
||||
// result = CCSDSTime::convertToCcsds(&cdsFormat, &time);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return;
|
||||
// }
|
||||
// TODO: Fix
|
||||
// memcpy(rawTimestamp, &cdsFormat, sizeof(cdsFormat));
|
||||
}
|
||||
void setContent(TmPacketInformation* content) {
|
||||
apid = content->apid;
|
||||
@@ -114,9 +126,10 @@ class TmPacketInformation : public SerializeIF {
|
||||
serviceType = content->serviceType;
|
||||
serviceSubtype = content->serviceSubtype;
|
||||
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 bool isOlderThan(const TmPacketInformation* packet, const timeval* cmpTime) {
|
||||
@@ -216,7 +229,7 @@ class TmPacketInformation : public SerializeIF {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||
return adapter.serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
@@ -227,7 +240,7 @@ class TmPacketInformation : public SerializeIF {
|
||||
size += SerializeAdapter::getSerializedSize(&serviceType);
|
||||
size += SerializeAdapter::getSerializedSize(&serviceSubtype);
|
||||
size += SerializeAdapter::getSerializedSize(&subCounter);
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||
size += adapter.getSerializedSize();
|
||||
return size;
|
||||
};
|
||||
@@ -253,7 +266,7 @@ class TmPacketInformation : public SerializeIF {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp, sizeof(rawTimestamp));
|
||||
SerialBufferAdapter<uint8_t> adapter(rawTimestamp.data(), rawTimestamp.size());
|
||||
return adapter.deSerialize(buffer, size, streamEndianness);
|
||||
}
|
||||
|
||||
@@ -263,6 +276,6 @@ class TmPacketInformation : public SerializeIF {
|
||||
uint8_t serviceType;
|
||||
uint8_t serviceSubtype;
|
||||
uint8_t subCounter;
|
||||
uint8_t rawTimestamp[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
|
||||
std::vector<uint8_t> rawTimestamp;
|
||||
};
|
||||
#endif /* FSFW_TMSTORAGE_TMSTOREPACKETS_H_ */
|
||||
|
@@ -160,3 +160,18 @@ ReturnValue_t HostFilesystem::truncateFile(FilesystemParams params) {
|
||||
ofstream of(path);
|
||||
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;
|
||||
}
|
||||
|
@@ -9,6 +9,9 @@ class HostFilesystem : public HasFileSystemIF {
|
||||
public:
|
||||
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;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fsfw_hal/linux/serial/SerialComIF.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||
|
||||
#include "fsfw/ipc/MutexIF.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
|
@@ -138,3 +138,10 @@ ReturnValue_t FilesystemMock::truncateFile(FilesystemParams params) {
|
||||
truncateCalledOnFile = params.path;
|
||||
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; }
|
||||
|
@@ -56,6 +56,10 @@ class FilesystemMock : public HasFileSystemIF {
|
||||
std::string truncateCalledOnFile;
|
||||
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;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
|
||||
|
Reference in New Issue
Block a user