SW Update #113

Merged
meierj merged 5 commits from mueller/utility-updates into develop 2021-12-01 09:08:02 +01:00
7 changed files with 85 additions and 73 deletions

View File

@ -26,8 +26,8 @@ ReturnValue_t Q7STestTask::performOneShotAction() {
//testJsonLibDirect(); //testJsonLibDirect();
//testDummyParams(); //testDummyParams();
//testProtHandler(); //testProtHandler();
//FsOpCodes opCode = FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY; FsOpCodes opCode = FsOpCodes::APPEND_TO_FILE;
//testFileSystemHandlerDirect(opCode); testFileSystemHandlerDirect(opCode);
return TestTask::performOneShotAction(); return TestTask::performOneShotAction();
} }
@ -252,7 +252,7 @@ void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
cfg.useMountPrefix = false; cfg.useMountPrefix = false;
sif::info << "Creating empty file in /tmp folder" << std::endl; sif::info << "Creating empty file in /tmp folder" << std::endl;
// Do not delete file, user can check existence in shell // Do not delete file, user can check existence in shell
fsHandler->createFile("/tmp", "test.txt", nullptr, 0, &cfg); fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
break; break;
} }
case(FsOpCodes::REMOVE_TMP_FILE): { case(FsOpCodes::REMOVE_TMP_FILE): {
@ -262,7 +262,7 @@ void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
if(not std::filesystem::exists("/tmp/test.txt")) { if(not std::filesystem::exists("/tmp/test.txt")) {
// Creating sample file // Creating sample file
sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl; sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl;
fsHandler->createFile("/tmp", "test.txt", nullptr, 0, &cfg); fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
} }
result = fsHandler->removeFile("/tmp", "test.txt", &cfg); result = fsHandler->removeFile("/tmp", "test.txt", &cfg);
if(result == HasReturnvaluesIF::RETURN_OK) { if(result == HasReturnvaluesIF::RETURN_OK) {
@ -278,7 +278,7 @@ void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
cfg.useMountPrefix = false; cfg.useMountPrefix = false;
sif::info << "Creating empty file in /tmp folder" << std::endl; sif::info << "Creating empty file in /tmp folder" << std::endl;
// Do not delete file, user can check existence in shell // Do not delete file, user can check existence in shell
ReturnValue_t result = fsHandler->createDirectory("/tmp", "test", false, &cfg); ReturnValue_t result = fsHandler->createDirectory("/tmp/", "test", false, &cfg);
if(result == HasReturnvaluesIF::RETURN_OK) { if(result == HasReturnvaluesIF::RETURN_OK) {
sif::info << "Directory created successfully" << std::endl; sif::info << "Directory created successfully" << std::endl;
} }
@ -297,7 +297,7 @@ void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
// Delete any leftover files to regular dir removal works // Delete any leftover files to regular dir removal works
std::remove("/tmp/test/*"); std::remove("/tmp/test/*");
} }
result = fsHandler->removeDirectory("/tmp", "test", false, &cfg); result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
if(result == HasReturnvaluesIF::RETURN_OK) { if(result == HasReturnvaluesIF::RETURN_OK) {
sif::info << "Directory removed successfully" << std::endl; sif::info << "Directory removed successfully" << std::endl;
} }
@ -311,7 +311,7 @@ void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return; return;
} }
result = fsHandler->removeDirectory("/tmp", "test", true, &cfg); result = fsHandler->removeDirectory("/tmp/", "test", true, &cfg);
if(result == HasReturnvaluesIF::RETURN_OK) { if(result == HasReturnvaluesIF::RETURN_OK) {
sif::info << "Directory removed recursively successfully" << std::endl; sif::info << "Directory removed recursively successfully" << std::endl;
} }
@ -325,13 +325,42 @@ void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
return; return;
} }
result = fsHandler->removeDirectory("/tmp", "test", false, &cfg); result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
sif::info << "Directory removal attempt failed as expected" << std::endl; sif::info << "Directory removal attempt failed as expected" << std::endl;
} }
else { else {
sif::warning << "Directory removal worked when it should not have!" << std::endl; sif::warning << "Directory removal worked when it should not have!" << std::endl;
} }
break;
}
case(FsOpCodes::RENAME_FILE): {
// No mount prefix, cause file is created in tmp
cfg.useMountPrefix = false;
if(std::filesystem::exists("/tmp/test.txt")) {
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
}
sif::info << "Creating empty file /tmp/test.txt and rename to /tmp/test2.txt" << std::endl;
// Do not delete file, user can check existence in shell
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
fsHandler->renameFile("/tmp/", "test.txt", "test2.txt", &cfg);
break;
}
case(FsOpCodes::APPEND_TO_FILE): {
// No mount prefix, cause file is created in tmp
cfg.useMountPrefix = false;
if(std::filesystem::exists("/tmp/test.txt")) {
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
}
if(std::filesystem::exists("/tmp/test.txt")) {
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
}
sif::info << "Creating empty file /tmp/test.txt and adding content" << std::endl;
std::string content = "Hello World\n";
// Do not delete file, user can check existence in shell
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
fsHandler->appendToFile("/tmp/", "test.txt", reinterpret_cast<const uint8_t*>(
content.data()), content.size(), 0, &cfg);
} }
} }
} }

View File

@ -27,6 +27,8 @@ private:
REMOVE_EMPTY_DIR_IN_TMP, REMOVE_EMPTY_DIR_IN_TMP,
ATTEMPT_DIR_REMOVAL_NON_EMPTY, ATTEMPT_DIR_REMOVAL_NON_EMPTY,
REMOVE_FILLED_DIR_IN_TMP, REMOVE_FILLED_DIR_IN_TMP,
RENAME_FILE,
APPEND_TO_FILE,
}; };
void testFileSystemHandlerDirect(FsOpCodes opCode); void testFileSystemHandlerDirect(FsOpCodes opCode);
}; };

View File

@ -136,13 +136,11 @@ ReturnValue_t FileSystemHandler::initialize() {
ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath, ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath,
const char* filename, const uint8_t* data, size_t size, const char* filename, const uint8_t* data, size_t size,
uint16_t packetNumber, FileSystemArgsIF* args) { uint16_t packetNumber, FileSystemArgsIF* args) {
// A double slash between repo and filename should not be an issue, so add it in any case auto path = getInitPath(args) / repositoryPath / filename;
std::string fullPath = currentMountPrefix + std::string(repositoryPath) + "/" + if(not std::filesystem::exists(path)) {
std::string(filename);
if(not std::filesystem::exists(fullPath)) {
return FILE_DOES_NOT_EXIST; return FILE_DOES_NOT_EXIST;
} }
std::ofstream file(fullPath, std::ios_base::app|std::ios_base::out); std::ofstream file(path, std::ios_base::app|std::ios_base::out);
file.write(reinterpret_cast<const char*>(data), size); file.write(reinterpret_cast<const char*>(data), size);
if(not file.good()) { if(not file.good()) {
return GENERIC_FILE_ERROR; return GENERIC_FILE_ERROR;
@ -152,19 +150,11 @@ ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath,
ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath, ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath,
const char* filename, const uint8_t* data, size_t size, FileSystemArgsIF* args) { const char* filename, const uint8_t* data, size_t size, FileSystemArgsIF* args) {
std::string fullPath; auto path = getInitPath(args) / filename;
bool useMountPrefix = true; if(std::filesystem::exists(path)) {
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
if(useMountPrefix) {
fullPath += currentMountPrefix;
}
// A double slash between repo and filename should not be an issue, so add it in any case
fullPath += std::string(repositoryPath) + "/" + std::string(filename);
if(std::filesystem::exists(fullPath)) {
return FILE_ALREADY_EXISTS; return FILE_ALREADY_EXISTS;
} }
std::ofstream file(fullPath); std::ofstream file(path);
file.write(reinterpret_cast<const char*>(data), size); file.write(reinterpret_cast<const char*>(data), size);
if(not file.good()) { if(not file.good()) {
return GENERIC_FILE_ERROR; return GENERIC_FILE_ERROR;
@ -174,19 +164,11 @@ ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath,
ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath, ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath,
const char* filename, FileSystemArgsIF* args) { const char* filename, FileSystemArgsIF* args) {
std::string fullPath; auto path = getInitPath(args) / repositoryPath / filename;
bool useMountPrefix = true; if(not std::filesystem::exists(path)) {
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
if(useMountPrefix) {
fullPath += currentMountPrefix;
}
// A double slash between repo and filename should not be an issue, so add it in any case
fullPath += std::string(repositoryPath) + "/" + std::string(filename);
if(not std::filesystem::exists(fullPath)) {
return FILE_DOES_NOT_EXIST; return FILE_DOES_NOT_EXIST;
} }
int result = std::remove(fullPath.c_str()); int result = std::remove(path.c_str());
if(result != 0) { if(result != 0) {
sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl; sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl;
return GENERIC_FILE_ERROR; return GENERIC_FILE_ERROR;
@ -196,42 +178,26 @@ ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath,
ReturnValue_t FileSystemHandler:: createDirectory(const char* repositoryPath, const char* dirname, ReturnValue_t FileSystemHandler:: createDirectory(const char* repositoryPath, const char* dirname,
bool createParentDirs, FileSystemArgsIF* args) { bool createParentDirs, FileSystemArgsIF* args) {
std::string fullPath; auto path = getInitPath(args) / repositoryPath / dirname;
bool useMountPrefix = true; if(std::filesystem::exists(path)) {
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
if(useMountPrefix) {
fullPath += currentMountPrefix;
}
fullPath += std::string(repositoryPath);
fullPath += "/" + std::string(dirname);
if(std::filesystem::exists(fullPath)) {
return DIRECTORY_ALREADY_EXISTS; return DIRECTORY_ALREADY_EXISTS;
} }
if(std::filesystem::create_directory(fullPath)) { if(std::filesystem::create_directory(path)) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
sif::warning << "Creating directory " << fullPath << " failed" << std::endl; sif::warning << "Creating directory " << path << " failed" << std::endl;
return GENERIC_FILE_ERROR; return GENERIC_FILE_ERROR;
} }
ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, const char* dirname, ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, const char* dirname,
bool deleteRecurively, FileSystemArgsIF* args) { bool deleteRecurively, FileSystemArgsIF* args) {
std::string fullPath; auto path = getInitPath(args) / repositoryPath / dirname;
bool useMountPrefix = true; if(not std::filesystem::exists(path)) {
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
if(useMountPrefix) {
fullPath += currentMountPrefix;
}
fullPath += std::string(repositoryPath);
fullPath += "/" + std::string(dirname);
if(not std::filesystem::exists(fullPath)) {
return DIRECTORY_DOES_NOT_EXIST; return DIRECTORY_DOES_NOT_EXIST;
} }
std::error_code err; std::error_code err;
if(not deleteRecurively) { if(not deleteRecurively) {
if(std::filesystem::remove(fullPath, err)) { if(std::filesystem::remove(path, err)) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
@ -248,7 +214,7 @@ ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, con
} }
} }
else { else {
if(std::filesystem::remove_all(fullPath, err)) { if(std::filesystem::remove_all(path, err)) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
else { else {
@ -267,14 +233,25 @@ ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, con
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t FileSystemHandler::renameFile(const char *repositoryPath, const char *oldFilename,
const char *newFilename, FileSystemArgsIF *args) {
auto basepath = getInitPath(args) / repositoryPath;
std::filesystem::rename(basepath / oldFilename, basepath / newFilename);
return HasReturnvaluesIF::RETURN_OK;
}
void FileSystemHandler::parseCfg(FsCommandCfg *cfg, bool& useMountPrefix) { void FileSystemHandler::parseCfg(FsCommandCfg *cfg, bool& useMountPrefix) {
if(cfg != nullptr) { if(cfg != nullptr) {
useMountPrefix = cfg->useMountPrefix; useMountPrefix = cfg->useMountPrefix;
} }
} }
ReturnValue_t FileSystemHandler::renameFile(const char *repositoryPath, const char *oldFilename, std::filesystem::path FileSystemHandler::getInitPath(FileSystemArgsIF* args) {
const char *newFilename, FileSystemArgsIF *args) { bool useMountPrefix = true;
// TODO: Implement parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
return HasReturnvaluesIF::RETURN_OK; std::string path;
if(useMountPrefix) {
path = currentMountPrefix;
}
return std::filesystem::path(path);
} }

View File

@ -10,6 +10,7 @@
#include "fsfw/memory/HasFileSystemIF.h" #include "fsfw/memory/HasFileSystemIF.h"
#include <string> #include <string>
#include <filesystem>
class CoreController; class CoreController;
@ -61,6 +62,7 @@ private:
void fileSystemHandlerLoop(); void fileSystemHandlerLoop();
void fileSystemCheckup(); void fileSystemCheckup();
std::filesystem::path getInitPath(FileSystemArgsIF* args);
void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix); void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix);
}; };

2
fsfw

@ -1 +1 @@
Subproject commit d8580074c2730d861353ab47e659afeb707afe71 Subproject commit ceb87b5abb2992a18266328e0ea34d9af15db7af

View File

@ -257,7 +257,7 @@ bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
switch(frameAna) { switch(frameAna) {
case(FrameAna_t::ABANDONED_CLTU): { case(FrameAna_t::ABANDONED_CLTU): {
triggerEvent(INVALID_TC_FRAME, ABANDONED_CLTU); triggerEvent(INVALID_TC_FRAME, ABANDONED_CLTU);
sif::debug << "PdecHandler::checkFrameAna: Abondoned CLTU" << std::endl; sif::warning << "PdecHandler::checkFrameAna: Abondoned CLTU" << std::endl;
break; break;
} }
case(FrameAna_t::FRAME_DIRTY): { case(FrameAna_t::FRAME_DIRTY): {
@ -266,36 +266,38 @@ bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
break; break;
} }
case(FrameAna_t::FRAME_ILLEGAL): { case(FrameAna_t::FRAME_ILLEGAL): {
sif::debug << "PdecHandler::checkFrameAna: Frame illegal for one reason" << std::endl; sif::warning << "PdecHandler::checkFrameAna: Frame illegal for one reason" << std::endl;
handleIReason(pdecFar, FRAME_ILLEGAL_ONE_REASON); handleIReason(pdecFar, FRAME_ILLEGAL_ONE_REASON);
break; break;
} }
case(FrameAna_t::FRAME_ILLEGAL_MULTI_REASON): { case(FrameAna_t::FRAME_ILLEGAL_MULTI_REASON): {
sif::debug << "PdecHandler::checkFrameAna: Frame illegal for multiple reasons" sif::warning << "PdecHandler::checkFrameAna: Frame illegal for multiple reasons"
<< std::endl; << std::endl;
handleIReason(pdecFar, FRAME_ILLEGAL_MULTIPLE_REASONS); handleIReason(pdecFar, FRAME_ILLEGAL_MULTIPLE_REASONS);
break; break;
} }
case(FrameAna_t::AD_DISCARDED_LOCKOUT): { case(FrameAna_t::AD_DISCARDED_LOCKOUT): {
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT); triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT);
sif::debug << "PdecHandler::checkFrameAna: AD frame discarded because of lockout" sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because of lockout"
<< std::endl; << std::endl;
break; break;
} }
case(FrameAna_t::AD_DISCARDED_WAIT): { case(FrameAna_t::AD_DISCARDED_WAIT): {
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT); triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT);
sif::debug << "PdecHandler::checkFrameAna: AD frame discarded because of wait" sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because of wait"
<< std::endl; << std::endl;
break; break;
} }
case(FrameAna_t::AD_DISCARDED_NS_VR): { case(FrameAna_t::AD_DISCARDED_NS_VR): {
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_NS_VS); triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_NS_VS);
sif::debug << "PdecHandler::checkFrameAna: AD frame discarded because N(S) or V(R)" sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because N(S) or V(R)"
<< std::endl; << std::endl;
break; break;
} }
case(FrameAna_t::FRAME_ACCEPTED): { case(FrameAna_t::FRAME_ACCEPTED): {
sif::debug << "PdecHandler::checkFrameAna: Accepted TC frame" << std::endl; #if OBSW_DEBUG_PDEC_HANDLER == 1
sif::info << "PdecHandler::checkFrameAna: Accepted TC frame" << std::endl;
#endif
frameValid = true; frameValid = true;
break; break;
} }

View File

@ -101,18 +101,18 @@ void ObjectFactory::produceGenericObjects() {
#if OBSW_ADD_TCPIP_BRIDGE == 1 #if OBSW_ADD_TCPIP_BRIDGE == 1
#if OBSW_USE_TCP_BRIDGE == 0 #if OBSW_USE_TCP_BRIDGE == 0
auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
tmtcBridge->setMaxNumberOfPacketsStored(50);
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
sif::info << "Created UDP server for TMTC commanding with listener port " << sif::info << "Created UDP server for TMTC commanding with listener port " <<
udpBridge->getUdpPort() << std::endl; udpBridge->getUdpPort() << std::endl;
#else #else
auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR); auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
tmtcBridge->setMaxNumberOfPacketsStored(50);
auto tcpServer = new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE); auto tcpServer = new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
// TCP is stream based. Use packet ID as start marker when parsing for space packets // TCP is stream based. Use packet ID as start marker when parsing for space packets
tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID}); tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID});
sif::info << "Created TCP server for TMTC commanding with listener port " sif::info << "Created TCP server for TMTC commanding with listener port "
<< tcpServer->getTcpPort() << std::endl; << tcpServer->getTcpPort() << std::endl;
#endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */ #endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */
tmtcBridge->setMaxNumberOfPacketsStored(70);
#endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */ #endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */
} }