Persistent TM Store #320
@ -3,8 +3,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_sources(
|
target_sources(
|
||||||
${OBSW_NAME} PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp
|
${OBSW_NAME}
|
||||||
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp)
|
PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp
|
||||||
|
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp)
|
||||||
|
|
||||||
add_subdirectory(ploc)
|
add_subdirectory(ploc)
|
||||||
|
|
||||||
|
@ -139,10 +139,10 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR);
|
new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
||||||
|
|
||||||
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, *tmStore, *ipcStore, 50, 15);
|
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, *tmStore, *ipcStore, 50);
|
||||||
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
|
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
|
||||||
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, *tmStore, *ipcStore,
|
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, *tmStore, *ipcStore,
|
||||||
config::MAX_PUS_FUNNEL_QUEUE_DEPTH, 15);
|
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
|
||||||
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
|
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
|
||||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||||
|
@ -256,7 +256,7 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi
|
|||||||
ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
|
ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
ReturnValue_t status = returnvalue::OK;
|
ReturnValue_t status = returnvalue::OK;
|
||||||
if(getMode() != MODE_NORMAL) {
|
if (getMode() != MODE_NORMAL) {
|
||||||
// Ignore replies during transitions.
|
// Ignore replies during transitions.
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ ReturnValue_t CfdpTmFunnel::performOperation(uint8_t) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
if(count == 500) {
|
if (count == 500) {
|
||||||
sif::error << "CfdpTmFunnel: Possible message storm detected" << std::endl;
|
sif::error << "CfdpTmFunnel: Possible message storm detected" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
|
#include "fsfw/tmstorage/TmStoreMessage.h"
|
||||||
|
|
||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
|
|
||||||
TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName,
|
TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName,
|
||||||
muellerr marked this conversation as resolved
|
|||||||
@ -19,9 +23,46 @@ TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName
|
|||||||
currentTv(currentTv),
|
currentTv(currentTv),
|
||||||
sdcMan(sdcMan),
|
sdcMan(sdcMan),
|
||||||
tmStore(tmStore) {
|
tmStore(tmStore) {
|
||||||
|
tcQueue = QueueFactory::instance()->createMessageQueue();
|
||||||
calcDiffSeconds(intervalUnit, intervalCount);
|
calcDiffSeconds(intervalUnit, intervalCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t TmStore::handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel) {
|
||||||
|
CommandMessage cmdMessage;
|
||||||
|
ReturnValue_t result = tcQueue->receiveMessage(&cmdMessage);
|
||||||
|
if (result == MessageQueueIF::EMPTY) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (cmdMessage.getMessageType() == messagetypes::TM_STORE) {
|
||||||
|
Command_t cmd = cmdMessage.getCommand();
|
||||||
|
if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) {
|
||||||
|
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
|
||||||
|
auto accessor = ipcStore.getData(storeId);
|
||||||
|
uint32_t deleteUpToUnixSeconds = 0;
|
||||||
|
size_t size = accessor.second.size();
|
||||||
|
SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
deleteUpTo(deleteUpToUnixSeconds);
|
||||||
|
} else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
|
||||||
|
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
|
||||||
|
auto accessor = ipcStore.getData(storeId);
|
||||||
|
uint32_t dumpFromUnixSeconds;
|
||||||
|
uint32_t dumpUntilUnixSeconds;
|
||||||
|
size_t size = accessor.second.size();
|
||||||
|
SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size,
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
// TODO: TM store missing, and maybe there is a better way to do this?
|
||||||
|
dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, tmFunnel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t TmStore::passPacket(PusTmReader& reader) {
|
ReturnValue_t TmStore::passPacket(PusTmReader& reader) {
|
||||||
bool inApidList = false;
|
bool inApidList = false;
|
||||||
if (filter.apid) {
|
if (filter.apid) {
|
||||||
@ -91,11 +132,12 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) {
|
|||||||
|
|
||||||
// Rollover conditions were handled, write to file now
|
// Rollover conditions were handled, write to file now
|
||||||
std::ofstream of(mostRecentFile.value(), std::ios::app | std::ios::binary);
|
std::ofstream of(mostRecentFile.value(), std::ios::app | std::ios::binary);
|
||||||
of.write(reinterpret_cast<const char*>(reader.getFullData()), reader.getFullPacketLen());
|
of.write(reinterpret_cast<const char*>(reader.getFullData()),
|
||||||
|
static_cast<std::streamsize>(reader.getFullPacketLen()));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; }
|
MessageQueueId_t TmStore::getCommandQueue() const { return tcQueue->getId(); }
|
||||||
|
|
||||||
void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) {
|
void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) {
|
||||||
if (intervalUnit == RolloverInterval::MINUTELY) {
|
if (intervalUnit == RolloverInterval::MINUTELY) {
|
||||||
@ -184,7 +226,7 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) {
|
|||||||
std::vector<std::pair<uint8_t, uint8_t>>({std::pair(service, subservice)});
|
std::vector<std::pair<uint8_t, uint8_t>>({std::pair(service, subservice)});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
filter.serviceSubservices.value().push_back({service, subservice});
|
filter.serviceSubservices.value().emplace_back(service, subservice);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TmStore::deleteUpTo(uint32_t unixSeconds) {
|
void TmStore::deleteUpTo(uint32_t unixSeconds) {
|
||||||
@ -196,7 +238,7 @@ void TmStore::deleteUpTo(uint32_t unixSeconds) {
|
|||||||
}
|
}
|
||||||
Clock::TimeOfDay_t tod;
|
Clock::TimeOfDay_t tod;
|
||||||
pathToTod(file.path(), tod);
|
pathToTod(file.path(), tod);
|
||||||
timeval time;
|
timeval time{};
|
||||||
ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time);
|
ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error << "TOD to time conversion failed for file " << file << std::endl;
|
sif::error << "TOD to time conversion failed for file " << file << std::endl;
|
||||||
@ -222,13 +264,13 @@ void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds,
|
|||||||
}
|
}
|
||||||
Clock::TimeOfDay_t tod;
|
Clock::TimeOfDay_t tod;
|
||||||
pathToTod(file.path(), tod);
|
pathToTod(file.path(), tod);
|
||||||
timeval time;
|
timeval time{};
|
||||||
ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time);
|
ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::error << "TOD to time conversion failed for file " << file << std::endl;
|
sif::error << "TOD to time conversion failed for file " << file << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint32_t timeUnsigned = static_cast<uint32_t>(time.tv_sec);
|
auto timeUnsigned = static_cast<uint32_t>(time.tv_sec);
|
||||||
if (timeUnsigned > fromUnixSeconds && timeUnsigned + rolloverDiffSeconds < upToUnixSeconds) {
|
if (timeUnsigned > fromUnixSeconds && timeUnsigned + rolloverDiffSeconds < upToUnixSeconds) {
|
||||||
fileToPackets(file, timeUnsigned, funnel);
|
fileToPackets(file, timeUnsigned, funnel);
|
||||||
}
|
}
|
||||||
@ -237,7 +279,7 @@ void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds,
|
|||||||
|
|
||||||
void TmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) {
|
void TmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) {
|
||||||
auto pathStr = path.string();
|
auto pathStr = path.string();
|
||||||
size_t splitChar = pathStr.find("_");
|
size_t splitChar = pathStr.find('_');
|
||||||
auto timeOnlyStr = pathStr.substr(splitChar);
|
auto timeOnlyStr = pathStr.substr(splitChar);
|
||||||
sscanf(timeOnlyStr.data(),
|
sscanf(timeOnlyStr.data(),
|
||||||
"%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "Z",
|
"%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "Z",
|
||||||
@ -254,7 +296,7 @@ void TmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStam
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::ifstream ifile(path, std::ios::binary);
|
std::ifstream ifile(path, std::ios::binary);
|
||||||
ifile.read(reinterpret_cast<char*>(fileBuf.data()), size);
|
ifile.read(reinterpret_cast<char*>(fileBuf.data()), static_cast<std::streamsize>(size));
|
||||||
size_t currentIdx = 0;
|
size_t currentIdx = 0;
|
||||||
while (currentIdx < size) {
|
while (currentIdx < size) {
|
||||||
PusTmReader reader(&timeReader, fileBuf.data(), fileBuf.size());
|
PusTmReader reader(&timeReader, fileBuf.data(), fileBuf.size());
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
||||||
#include <fsfw/tmstorage/TmStoreFrontendIF.h>
|
#include <fsfw/tmstorage/TmStoreFrontendSimpleIF.h>
|
||||||
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
|
#include <fsfw/tmtcpacket/pus/tm/PusTmReader.h>
|
||||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||||
#include <mission/memory/SdCardMountedIF.h>
|
#include <mission/memory/SdCardMountedIF.h>
|
||||||
@ -21,7 +21,7 @@ struct PacketFilter {
|
|||||||
|
|
||||||
enum class RolloverInterval { MINUTELY, HOURLY, DAILY };
|
enum class RolloverInterval { MINUTELY, HOURLY, DAILY };
|
||||||
|
|
||||||
class TmStore : public SystemObject {
|
class TmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE;
|
||||||
|
|
||||||
@ -34,6 +34,8 @@ class TmStore : public SystemObject {
|
|||||||
RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv,
|
RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv,
|
||||||
StorageManagerIF& tmStore, SdCardMountedIF& sdcMan);
|
StorageManagerIF& tmStore, SdCardMountedIF& sdcMan);
|
||||||
|
|
||||||
|
ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel);
|
||||||
|
|
||||||
void addApid(uint16_t apid);
|
void addApid(uint16_t apid);
|
||||||
void addService(uint8_t service);
|
void addService(uint8_t service);
|
||||||
void addServiceSubservice(uint8_t service, uint8_t subservice);
|
void addServiceSubservice(uint8_t service, uint8_t subservice);
|
||||||
@ -48,11 +50,7 @@ class TmStore : public SystemObject {
|
|||||||
private:
|
private:
|
||||||
static constexpr size_t MAX_FILESIZE = 8192;
|
static constexpr size_t MAX_FILESIZE = 8192;
|
||||||
|
|
||||||
/**
|
MessageQueueIF* tcQueue;
|
||||||
* To get the queue where commands shall be sent.
|
|
||||||
* @return Id of command queue.
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getCommandQueue();
|
|
||||||
PacketFilter filter;
|
PacketFilter filter;
|
||||||
CdsShortTimeStamper timeReader;
|
CdsShortTimeStamper timeReader;
|
||||||
bool baseDirUninitialized = true;
|
bool baseDirUninitialized = true;
|
||||||
@ -67,9 +65,15 @@ class TmStore : public SystemObject {
|
|||||||
SdCardMountedIF& sdcMan;
|
SdCardMountedIF& sdcMan;
|
||||||
StorageManagerIF& tmStore;
|
StorageManagerIF& tmStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To get the queue where commands shall be sent.
|
||||||
|
* @return Id of command queue.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount);
|
void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount);
|
||||||
void assignAndOrCreateMostRecentFile();
|
void assignAndOrCreateMostRecentFile();
|
||||||
void pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod);
|
static void pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod);
|
||||||
void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel);
|
void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel);
|
||||||
ReturnValue_t storePacket(PusTmReader& reader);
|
ReturnValue_t storePacket(PusTmReader& reader);
|
||||||
};
|
};
|
||||||
|
@ -51,35 +51,44 @@ PusTmFunnel::~PusTmFunnel() = default;
|
|||||||
|
|
||||||
ReturnValue_t PusTmFunnel::performOperation(uint8_t) {
|
ReturnValue_t PusTmFunnel::performOperation(uint8_t) {
|
||||||
CommandMessage cmdMessage;
|
CommandMessage cmdMessage;
|
||||||
ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage);
|
ReturnValue_t result = okStore.handleCommandQueue(ipcStore, *this);
|
||||||
if (status == returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
ReturnValue_t result = handleTcRequest(cmdMessage);
|
sif::error << "PusTmFunnel::performOperation: Issue handling OK store command" << std::endl;
|
||||||
if (result != returnvalue::OK) {
|
}
|
||||||
sif::error << "PusTmFunnel::performOperation: Error handling TC request" << std::endl;
|
result = notOkStore.handleCommandQueue(ipcStore, *this);
|
||||||
}
|
if (result != returnvalue::OK) {
|
||||||
|
sif::error << "PusTmFunnel::performOperation: Issue handling NOT OK store command" << std::endl;
|
||||||
|
}
|
||||||
|
result = hkStore.handleCommandQueue(ipcStore, *this);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::error << "PusTmFunnel::performOperation: Issue handling HK store command" << std::endl;
|
||||||
|
}
|
||||||
|
result = miscStore.handleCommandQueue(ipcStore, *this);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
sif::error << "PusTmFunnel::performOperation: Issue handling MISC store command" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcMessage currentMessage;
|
TmTcMessage currentMessage;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
ReturnValue_t status = tmQueue->receiveMessage(¤tMessage);
|
result = tmQueue->receiveMessage(¤tMessage);
|
||||||
while (status == returnvalue::OK) {
|
while (result == returnvalue::OK) {
|
||||||
status = handleTmPacket(tmMessage);
|
result = handleTmPacket(currentMessage);
|
||||||
if (status != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "TmFunnel packet handling failed" << std::endl;
|
sif::warning << "TmFunnel packet handling failed" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
if(count == 500) {
|
if (count == 500) {
|
||||||
sif::error << "PusTmFunnel: Possible message storm detected" << std::endl;
|
sif::error << "PusTmFunnel: Possible message storm detected" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
status = tmQueue->receiveMessage(¤tMessage);
|
result = tmQueue->receiveMessage(¤tMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == MessageQueueIF::EMPTY) {
|
if (result == MessageQueueIF::EMPTY) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
return status;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) {
|
ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) {
|
||||||
@ -137,56 +146,3 @@ ReturnValue_t PusTmFunnel::initialize() {
|
|||||||
initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt));
|
initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PusTmFunnel::handleTcRequest(CommandMessage &cmdMessage) {
|
|
||||||
if (cmdMessage.getMessageType() == messagetypes::TM_STORE) {
|
|
||||||
Command_t cmd = cmdMessage.getCommand();
|
|
||||||
object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage);
|
|
||||||
TmStore *tmStore = nullptr;
|
|
||||||
switch (objectId) {
|
|
||||||
case (objects::HK_TM_STORE): {
|
|
||||||
tmStore = &hkStore;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (objects::OK_TM_STORE): {
|
|
||||||
tmStore = &okStore;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (objects::NOT_OK_TM_STORE): {
|
|
||||||
tmStore = ¬OkStore;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (objects::MISC_TM_STORE): {
|
|
||||||
tmStore = &miscStore;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tmStore == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) {
|
|
||||||
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
|
|
||||||
auto accessor = ipcStore.getData(storeId);
|
|
||||||
uint32_t deleteUpToUnixSeconds = 0;
|
|
||||||
size_t size = accessor.second.size();
|
|
||||||
SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size,
|
|
||||||
SerializeIF::Endianness::NETWORK);
|
|
||||||
tmStore->deleteUpTo(deleteUpToUnixSeconds);
|
|
||||||
} else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
|
|
||||||
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
|
|
||||||
auto accessor = ipcStore.getData(storeId);
|
|
||||||
uint32_t dumpFromUnixSeconds;
|
|
||||||
uint32_t dumpUntilUnixSeconds;
|
|
||||||
size_t size = accessor.second.size();
|
|
||||||
SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size,
|
|
||||||
SerializeIF::Endianness::NETWORK);
|
|
||||||
SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size,
|
|
||||||
SerializeIF::Endianness::NETWORK);
|
|
||||||
// TODO: TM store missing, and maybe there is a better way to do this?
|
|
||||||
tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, *this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
@ -44,7 +44,6 @@ class PusTmFunnel : public TmFunnelBase {
|
|||||||
TmStore hkStore;
|
TmStore hkStore;
|
||||||
SdCardMountedIF &sdcMan;
|
SdCardMountedIF &sdcMan;
|
||||||
|
|
||||||
ReturnValue_t handleTcRequest(CommandMessage &msg);
|
|
||||||
ReturnValue_t handleTmPacket(TmTcMessage &message);
|
ReturnValue_t handleTmPacket(TmTcMessage &message);
|
||||||
void initStoresIfPossible(bool sdCardUsable);
|
void initStoresIfPossible(bool sdCardUsable);
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
@ -30,14 +30,10 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice,
|
|||||||
const uint8_t *tcData, size_t tcDataLen,
|
const uint8_t *tcData, size_t tcDataLen,
|
||||||
MessageQueueId_t *id,
|
MessageQueueId_t *id,
|
||||||
object_id_t *objectId) {
|
object_id_t *objectId) {
|
||||||
object_id_t targetObjectId;
|
if (tcDataLen < 4) {
|
||||||
SerializeAdapter::deSerialize(&targetObjectId, &tcData, &tcDataLen,
|
return CommandingServiceBase::INVALID_TC;
|
||||||
SerializeIF::Endianness::NETWORK);
|
|
||||||
if (targetObjectId == objects::CFDP_TM_STORE) {
|
|
||||||
*objectId = objects::CFDP_TM_FUNNEL;
|
|
||||||
} else {
|
|
||||||
*objectId = objects::PUS_TM_FUNNEL;
|
|
||||||
}
|
}
|
||||||
|
SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::NETWORK);
|
||||||
auto *frontendIF = ObjectManager::instance()->get<TmStoreFrontendSimpleIF>(*objectId);
|
auto *frontendIF = ObjectManager::instance()->get<TmStoreFrontendSimpleIF>(*objectId);
|
||||||
if (frontendIF == nullptr) {
|
if (frontendIF == nullptr) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
muellerr marked this conversation as resolved
Outdated
gaisser
commented
I think there is an Error code for unknown object. (CommandingServiceBase::INVALID_OBJECT) I think there is an Error code for unknown object. (CommandingServiceBase::INVALID_OBJECT)
|
|||||||
|
@ -7,7 +7,6 @@
|
|||||||
TmFunnelBase::TmFunnelBase(FunnelCfg cfg)
|
TmFunnelBase::TmFunnelBase(FunnelCfg cfg)
|
||||||
: SystemObject(cfg.objectId), tmStore(cfg.tmStore), ipcStore(cfg.ipcStore) {
|
: SystemObject(cfg.objectId), tmStore(cfg.tmStore), ipcStore(cfg.ipcStore) {
|
||||||
tmQueue = QueueFactory::instance()->createMessageQueue(cfg.tmMsgDepth);
|
tmQueue = QueueFactory::instance()->createMessageQueue(cfg.tmMsgDepth);
|
||||||
tcQueue = QueueFactory::instance()->createMessageQueue(cfg.tcMsgDepth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TmFunnelBase::~TmFunnelBase() { QueueFactory::instance()->deleteMessageQueue(tmQueue); }
|
TmFunnelBase::~TmFunnelBase() { QueueFactory::instance()->deleteMessageQueue(tmQueue); }
|
||||||
@ -56,5 +55,3 @@ ReturnValue_t TmFunnelBase::sendPacketToDestinations(store_address_t origStoreId
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t TmFunnelBase::getCommandQueue() const { return tcQueue->getId(); }
|
|
||||||
|
@ -9,32 +9,25 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class TmFunnelBase : public TmStoreFrontendSimpleIF,
|
class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject {
|
||||||
public AcceptsTelemetryIF,
|
|
||||||
public SystemObject {
|
|
||||||
public:
|
public:
|
||||||
struct FunnelCfg {
|
struct FunnelCfg {
|
||||||
FunnelCfg(object_id_t objId, StorageManagerIF& tmStore, StorageManagerIF& ipcStore,
|
FunnelCfg(object_id_t objId, StorageManagerIF& tmStore, StorageManagerIF& ipcStore,
|
||||||
uint32_t tmMsgDepth, uint32_t tcMsgDepth)
|
uint32_t tmMsgDepth)
|
||||||
: objectId(objId),
|
: objectId(objId), tmStore(tmStore), ipcStore(ipcStore), tmMsgDepth(tmMsgDepth) {}
|
||||||
tmStore(tmStore),
|
|
||||||
ipcStore(ipcStore),
|
|
||||||
tmMsgDepth(tmMsgDepth),
|
|
||||||
tcMsgDepth(tcMsgDepth) {}
|
|
||||||
object_id_t objectId;
|
object_id_t objectId;
|
||||||
StorageManagerIF& tmStore;
|
StorageManagerIF& tmStore;
|
||||||
StorageManagerIF& ipcStore;
|
StorageManagerIF& ipcStore;
|
||||||
uint32_t tmMsgDepth;
|
uint32_t tmMsgDepth;
|
||||||
uint32_t tcMsgDepth;
|
|
||||||
};
|
};
|
||||||
TmFunnelBase(FunnelCfg cfg);
|
explicit TmFunnelBase(FunnelCfg cfg);
|
||||||
void addDestination(const char* name, const AcceptsTelemetryIF& downlinkDestination,
|
void addDestination(const char* name, const AcceptsTelemetryIF& downlinkDestination,
|
||||||
uint8_t vcid = 0);
|
uint8_t vcid = 0);
|
||||||
ReturnValue_t sendPacketToDestinations(store_address_t origStoreId, TmTcMessage& message,
|
ReturnValue_t sendPacketToDestinations(store_address_t origStoreId, TmTcMessage& message,
|
||||||
const uint8_t* packetData, size_t size);
|
const uint8_t* packetData, size_t size);
|
||||||
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
[[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override;
|
||||||
|
|
||||||
virtual ~TmFunnelBase();
|
~TmFunnelBase() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StorageManagerIF& tmStore;
|
StorageManagerIF& tmStore;
|
||||||
@ -52,9 +45,6 @@ class TmFunnelBase : public TmStoreFrontendSimpleIF,
|
|||||||
std::vector<Destination> destinations;
|
std::vector<Destination> destinations;
|
||||||
|
|
||||||
MessageQueueIF* tmQueue = nullptr;
|
MessageQueueIF* tmQueue = nullptr;
|
||||||
MessageQueueIF* tcQueue = nullptr;
|
|
||||||
|
|
||||||
MessageQueueId_t getCommandQueue() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_TMTC_TMFUNNELBASE_H_ */
|
#endif /* MISSION_TMTC_TMFUNNELBASE_H_ */
|
||||||
|
@ -50,7 +50,7 @@ ReturnValue_t VirtualChannel::performOperation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
if(count == 500) {
|
if (count == 500) {
|
||||||
sif::error << "VirtualChannel: Possible message storm detected" << std::endl;
|
sif::error << "VirtualChannel: Possible message storm detected" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user
I don't get why the stores need a reference to a central time. They can look that up by their own I think. Is it necessary to have all stores working on the exact same time?
No. I'll probably update the code so each persistent store calls `Clock::getClock_timeval