23 #include "config/FileManagerConfig.hpp" 37 m_sandboxConfigured(false),
69 if (resolved[resolvedLen - 1] !=
'/') {
71 resolved[resolvedLen] =
'/';
72 resolved[resolvedLen + 1] =
'\0';
75 this->m_sandboxDir = resolved;
76 this->m_sandboxConfigured =
true;
83 bool accepted =
false;
84 if (this->m_sandboxConfigured) {
91 resolved = resolvedBuffer;
109 void FileManager ::CreateDirectory_cmdHandler(
const FwOpcodeType opCode,
113 if (!this->resolveInSandbox(dirName, resolvedDirName, opCode, cmdSeq)) {
118 bool errorIfDirExists =
true;
125 this->emitTelemetry(status);
126 this->sendCommandResponse(opCode, cmdSeq, status);
129 void FileManager ::RemoveFile_cmdHandler(
const FwOpcodeType opCode,
132 const bool ignoreErrors) {
134 if (!this->resolveInSandbox(fileName, resolvedFileName, opCode, cmdSeq)) {
142 if (ignoreErrors ==
true) {
151 this->emitTelemetry(status);
152 this->sendCommandResponse(opCode, cmdSeq, status);
155 void FileManager ::MoveFile_cmdHandler(
const FwOpcodeType opCode,
161 if (!this->resolveInSandbox(sourceFileName, resolvedSource, opCode, cmdSeq) ||
162 !this->resolveInSandbox(destFileName, resolvedDest, opCode, cmdSeq)) {
174 this->emitTelemetry(status);
175 this->sendCommandResponse(opCode, cmdSeq, status);
178 void FileManager ::RemoveDirectory_cmdHandler(
const FwOpcodeType opCode,
182 if (!this->resolveInSandbox(dirName, resolvedDirName, opCode, cmdSeq)) {
193 this->emitTelemetry(status);
194 this->sendCommandResponse(opCode, cmdSeq, status);
197 void FileManager ::AppendFile_cmdHandler(
const FwOpcodeType opCode,
203 if (!this->resolveInSandbox(source, resolvedSource, opCode, cmdSeq) ||
204 !this->resolveInSandbox(target, resolvedTarget, opCode, cmdSeq)) {
219 this->emitTelemetry(status);
220 this->sendCommandResponse(opCode, cmdSeq, status);
225 if (!this->resolveInSandbox(fileName, resolvedFileName, opCode, cmdSeq)) {
238 this->emitTelemetry(status);
239 this->sendCommandResponse(opCode, cmdSeq, status);
242 void FileManager ::ListDirectory_cmdHandler(
const FwOpcodeType opCode,
246 if (m_listState == LISTING_IN_PROGRESS) {
254 if (!this->resolveInSandbox(dirName, resolvedDirName, opCode, cmdSeq)) {
271 m_listState = LISTING_IN_PROGRESS;
272 m_currentDirName = dirName;
273 m_currentOpCode = opCode;
274 m_currentCmdSeq = cmdSeq;
287 if (!this->resolveInSandbox(filename, resolvedFilename, opCode, cmdSeq)) {
307 void FileManager ::GenerateDp_cmdHandler(
FwOpcodeType opCode,
314 const FileManager_GenerateDpMode& mode) {
318 if (this->m_dpState != DP_IDLE) {
332 U32 effectiveChunkSize = chunkSize;
338 if (!this->resolveInSandbox(fileName, resolvedFileName, opCode, cmdSeq)) {
350 status = this->m_dpFile.
size(fileSize);
352 this->m_dpFile.
close();
361 U64 effectiveEnd = endOffset;
362 if ((effectiveEnd == 0) || (effectiveEnd > static_cast<U64>(fileSize))) {
363 effectiveEnd =
static_cast<U64
>(fileSize);
366 const bool emptyFile = (fileSize == 0);
367 const bool badRange = (beginOffset >
static_cast<U64
>(fileSize)) || (!emptyFile && (beginOffset >= effectiveEnd));
369 this->m_dpFile.
close();
376 if (beginOffset > 0) {
377 status = this->m_dpFile.
seek(static_cast<FwSignedSizeType>(beginOffset), Os::File::SeekType::ABSOLUTE);
379 this->m_dpFile.
close();
381 static_cast<U32>(status));
388 this->m_dpFileSize = fileSize;
389 this->m_dpOffset = beginOffset;
390 this->m_dpEndOffset = effectiveEnd;
391 this->m_dpChunkSize = effectiveChunkSize;
392 this->m_dpChunkCount = 0;
393 this->m_dpOpCode = opCode;
394 this->m_dpCmdSeq = cmdSeq;
398 this->m_dpState = DP_IN_PROGRESS;
405 if (this->m_dpOffset >= this->m_dpEndOffset) {
407 this->finishDpGeneration();
415 this->processDpChunks(0);
419 void FileManager ::processDpChunks(U32 chunkLimit) {
423 const bool paced = (chunkLimit > 0);
425 for (U32 chunk = 0; !paced || (chunk < chunkLimit); chunk++) {
430 const FwSizeType requestedSize = (remaining < static_cast<FwSizeType>(this->m_dpChunkSize))
432 :
static_cast<FwSizeType>(this->m_dpChunkSize);
439 static_cast<U32>(status));
440 this->finishDpGeneration();
446 DpContainer container;
450 this->finishDpGeneration();
453 container.setPriority(this->m_dpPriority);
457 const FileManager_FileChunkHeader header(this->m_dpFileName, this->m_dpOffset, static_cast<U32>(readSize));
458 Fw::SerializeStatus serializeStatus = container.serializeRecord_FileChunkHeaderRecord(header);
460 serializeStatus = container.serializeRecord_FileChunkDataRecord(this->m_dpBuffer, readSize);
464 static_cast<U32>(serializeStatus));
465 this->finishDpGeneration();
471 this->m_dpOffset +=
static_cast<U64
>(readSize);
472 this->m_dpChunkCount++;
475 if (this->m_dpOffset >= this->m_dpEndOffset) {
477 this->finishDpGeneration();
483 void FileManager ::finishDpGeneration() {
484 this->m_dpFile.
close();
485 this->m_dpState = DP_IDLE;
486 this->m_dpOffset = 0;
487 this->m_dpEndOffset = 0;
488 this->m_dpFileSize = 0;
494 void FileManager ::pingIn_handler(
const FwIndexType portNum, U32 key) {
499 void FileManager ::schedIn_handler(
const FwIndexType portNum, U32 context) {
500 bool isQueued =
false;
504 bool expects_enqueue = this->m_runQueued.compare_exchange_strong(isQueued,
true);
505 if (expects_enqueue) {
510 void FileManager ::run_internalInterfaceHandler() {
512 this->m_runQueued =
false;
514 if (this->m_dpState == DP_IN_PROGRESS) {
519 if (m_listState == LISTING_IN_PROGRESS) {
527 m_currentDir.
close();
548 static_cast<Fw::StringFormatStatus::T>(formatStatus));
554 m_currentDirName, filename,
568 m_currentDir.
close();
586 ++this->commandCount;
594 void FileManager ::sendCommandResponse(
const FwOpcodeType opCode,
bool isConnected_productSendOut_OutputPort(FwIndexType portNum) const
Serialization/Deserialization operation was successful.
A request arrived while another was in progress.
void log_WARNING_HI_ListDirectoryError(const Fw::StringBase &dirName, U32 status) const
void log_ACTIVITY_HI_DirectoryListingSubdir(const Fw::StringBase &dirName, const Fw::StringBase &subdirName) const
void log_ACTIVITY_HI_CreateDirectoryStarted(const Fw::StringBase &dirName) const
static constexpr FwSizeType SIZE_OF_FileChunkDataRecord_RECORD(FwSizeType arraySize)
Record sizes.
FwIdType FwOpcodeType
The type of a command opcode.
Fw::Success::T dpGet_FileDpContainer(FwSizeType dataSize, DpContainer &container)
Status calculateCrc(U32 &crc)
calculate the CRC32 of the entire file
void log_ACTIVITY_HI_RemoveDirectorySucceeded(const Fw::StringBase &dirName) const
void log_ACTIVITY_HI_DirectoryListing(const Fw::StringBase &dirName, const Fw::StringBase &fileName, FwSizeType fileSize) const
PlatformSizeType FwSizeType
static Status moveFile(const char *sourcePath, const char *destPath)
Move a file from sourcePath to destPath.
U32 FwDpPriorityType
The type of a data product priority.
void log_ACTIVITY_HI_CalculateCrcStarted(const Fw::StringBase &fileName) const
static constexpr U32 CHUNKS_PER_RATE_TICK
void log_WARNING_HI_FileSizeError(const Fw::StringBase &fileName, U32 status) const
void run_internalInterfaceInvoke()
Internal interface base-class function for run.
FileManager(const char *const compName)
Reading a chunk from the source file.
void log_ACTIVITY_HI_GenerateDpStarted(const Fw::StringBase &fileName, U64 bytesToWrite) const
static Status removeDirectory(const char *path)
Remove a directory at the specified path.
StringTemplate< FW_FIXED_LENGTH_STRING_SIZE > String
void log_ACTIVITY_HI_FileSizeSucceeded(const Fw::StringBase &fileName, FwSizeType size) const
static Status appendFile(const char *sourcePath, const char *destPath, bool createMissingDest=false)
Append the source file to the destination file.
void log_ACTIVITY_HI_ListDirectorySucceeded(const Fw::StringBase &dirName, U32 fileCount) const
Auto-generated base for FileManager component.
Status size(FwSizeType &size_result) override
get size of currently open file
bool isConnected_productGetOut_OutputPort(FwIndexType portNum) const
void log_ACTIVITY_HI_CalculateCrcSucceeded(const Fw::StringBase &fileName, U32 crc) const
Status checkContainment(const char *resolvedPath, const char *allowedDirectory)
Check whether an already-resolved path is within an allowed directory.
void log_ACTIVITY_HI_ListDirectoryStarted(const Fw::StringBase &dirName) const
void log_ACTIVITY_HI_MoveFileStarted(const Fw::StringBase &sourceFileName, const Fw::StringBase &destFileName) const
void log_WARNING_HI_GenerateDpInvalidRange(const Fw::StringBase &fileName, U64 beginOffset, U64 endOffset, U64 fileSize) const
void pingOut_out(FwIndexType portNum, U32 key) const
Invoke output port pingOut.
void log_ACTIVITY_HI_AppendFileSucceeded(const Fw::StringBase &source, const Fw::StringBase &target) const
SerializeStatus
forward declaration for string
void log_WARNING_HI_PathOutsideSandbox(const Fw::StringBase &path, const Fw::StringBase &sandboxDir) const
void configure(const char *sandboxDir)
void log_WARNING_HI_GenerateDpBufferFailed(const Fw::StringBase &fileName) const
void log_ACTIVITY_HI_CreateDirectorySucceeded(const Fw::StringBase &dirName) const
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
A catch-all for other errors. Have to look in implementation-specific code.
void log_WARNING_HI_GenerateDpFailed(const Fw::StringBase &fileName, const Svc::FileManager_GenerateDpStage &stage, U32 status) const
void log_ACTIVITY_HI_RemoveDirectoryStarted(const Fw::StringBase &dirName) const
void close() override
Close directory.
Status seek(FwSignedSizeType offset, SeekType seekType) override
seek the file pointer to the given offset
static constexpr FwSizeType MAX_PATH_LENGTH
Maximum supported path length for resolution buffers.
Status read(char *fileNameBuffer, FwSizeType buffSize) override
Get next filename from directory stream.
Querying the size of the source file.
static constexpr U32 GENERATE_DP_MAX_CHUNK_SIZE
void close() override
close the file, if not opened then do nothing
void cmdResponse_out(FwOpcodeType opCode, U32 cmdSeq, Fw::CmdResponse response)
Emit command response.
Directory stream has no more files.
const char * toChar() const
Convert to a C-style char*.
void log_ACTIVITY_HI_FileSizeStarted(const Fw::StringBase &fileName) const
void log_WARNING_HI_FileNameFormatError(const Fw::StringBase &fileName, const Fw::StringFormatStatus &status) const
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
Command successfully executed.
void log_ACTIVITY_HI_GenerateDpComplete(const Fw::StringBase &fileName, U32 chunks) const
void log_ACTIVITY_HI_MoveFileSucceeded(const Fw::StringBase &sourceFileName, const Fw::StringBase &destFileName) const
static Status getFileSize(const char *path, FwSizeType &size)
Get the size of the file (in bytes) at the specified path.
static Status createDirectory(const char *path, bool errorIfAlreadyExists=false)
Create a new directory at the specified path.
static constexpr FwSizeType SIZE_OF_FileChunkHeaderRecord_RECORD
Status read(U8 *buffer, FwSizeType &size)
read data from this file into supplied buffer bounded by size
Seeking to the requested begin offset.
Path is valid and within the allowed directory.
void log_WARNING_HI_DirectoryRemoveError(const Fw::StringBase &dirName, U32 status) const
Command had execution error.
static PathType getPathType(const char *path)
Return the type of the path (file, directory, or doesn't exist)
void log_ACTIVITY_HI_AppendFileStarted(const Fw::StringBase &source, const Fw::StringBase &target) const
Operation was successful.
Status resolveFromCwd(const char *path, char *resolvedOut, FwSizeType resolvedSize)
Resolve a path using CWD as the base for relative paths.
void tlmWrite_Errors(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
void log_ACTIVITY_HI_RemoveFileStarted(const Fw::StringBase &fileName) const
PlatformIndexType FwIndexType
Operation was successful.
void log_WARNING_HI_AppendFileFailed(const Fw::StringBase &source, const Fw::StringBase &target, U32 status) const
Status open(const char *path, OpenMode mode) override
Open or create a directory.
Command failed validation.
RateGroupDivider component implementation.
Emit all chunks in the command handler, completing immediately.
void log_WARNING_HI_CalculateCrcFailed(const Fw::StringBase &fileName, U32 status) const
Operation was successful.
static constexpr U32 FILES_PER_RATE_TICK
void log_WARNING_HI_DirectoryCreateError(const Fw::StringBase &dirName, U32 status) const
void log_ACTIVITY_HI_RemoveFileSucceeded(const Fw::StringBase &fileName) const
void log_WARNING_HI_FileMoveError(const Fw::StringBase &sourceFileName, const Fw::StringBase &destFileName, U32 status) const
void tlmWrite_CommandsExecuted(U32 arg, Fw::Time _tlmTime=Fw::Time()) const
static Status removeFile(const char *path)
Remove a file at the specified path.
Serializing a chunk into the container.
void log_WARNING_HI_FileRemoveError(const Fw::StringBase &fileName, U32 status) const
void dpSend(DpContainer &container, Fw::Time timeTag=Fw::ZERO_TIME)
Send a data product.
FwSizeType string_length(const CHAR *source, FwSizeType buffer_size)
get the length of the source string
FormatStatus
status of string format calls