Skip to content

Commit 5067881

Browse files
timcanhamLeStarch
andauthored
Add Svc.FileDispatcher component (#4552)
* Initial commit * FileDispatcher config * FileDispatch port added * Spell check * Restructuring based on GitHub review comments * Added file table validation, SDD updates, and fixed unit tests * Fixed formatting * Fixes for PR * Formatting * Fix issue --------- Co-authored-by: M Starch <[email protected]>
1 parent fa28787 commit 5067881

File tree

16 files changed

+885
-0
lines changed

16 files changed

+885
-0
lines changed

.github/actions/spelling/expect.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ACTIVERATEGROUPTESTER
66
ACTIVETEXTLOGGERIMPL
77
ADDRSTRLEN
88
adminlist
9+
afile
910
aleem
1011
ALLEXTERNALS
1112
alphanums
@@ -27,6 +28,7 @@ autocode
2728
autocoded
2829
autocoders
2930
autocoding
31+
autorun
3032
AYYYY
3133
baremetal
3234
batchmode
@@ -223,6 +225,7 @@ evt
223225
externalproject
224226
FAKELOGGER
225227
fbuild
228+
FDISP
226229
fdp
227230
featherm
228231
fecf
@@ -233,6 +236,8 @@ ffff
233236
Ffs
234237
fge
235238
fgt
239+
FILEDISPATCHER
240+
FILEDISPATCHERCFG
236241
FILEDOWNLINK
237242
FILEDOWNLINKCFG
238243
FILEHANDLING
@@ -636,6 +641,7 @@ spdx
636641
spi
637642
spidev
638643
spsc
644+
sqa
639645
srandom
640646
SRCS
641647
sreddy

Svc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpPorts/")
3333
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpWriter/")
3434
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/EventManager/")
3535
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FatalHandler/")
36+
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDispatcher/")
3637
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDownlinkPorts/")
3738
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDownlink/")
3839
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileManager/")

Svc/FileDispatcher/CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
####
2+
# F Prime CMakeLists.txt:
3+
#
4+
# SOURCES: list of source files (to be compiled)
5+
# AUTOCODER_INPUTS: list of files to be passed to the autocoders
6+
# DEPENDS: list of libraries that this module depends on
7+
#
8+
# More information in the F´ CMake API documentation:
9+
# https://fprime.jpl.nasa.gov/latest/docs/reference/api/cmake/API/
10+
#
11+
####
12+
13+
# Module names are derived from the path from the nearest project/library/framework
14+
# root when not specifically overridden by the developer. i.e. The module defined by
15+
# `Ref/SignalGen/CMakeLists.txt` will be named `Ref_SignalGen`.
16+
17+
register_fprime_library(
18+
AUTOCODER_INPUTS
19+
"${CMAKE_CURRENT_LIST_DIR}/FileDispatcher.fpp"
20+
SOURCES
21+
"${CMAKE_CURRENT_LIST_DIR}/FileDispatcher.cpp"
22+
# DEPENDS
23+
# MyPackage_MyOtherModule
24+
)
25+
26+
## Unit Tests ###
27+
register_fprime_ut(
28+
AUTOCODER_INPUTS
29+
"${CMAKE_CURRENT_LIST_DIR}/FileDispatcher.fpp"
30+
SOURCES
31+
"${CMAKE_CURRENT_LIST_DIR}/test/ut/FileDispatcherTestMain.cpp"
32+
"${CMAKE_CURRENT_LIST_DIR}/test/ut/FileDispatcherTester.cpp"
33+
DEPENDS
34+
STest # For rules-based testing
35+
UT_AUTO_HELPERS
36+
)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// ======================================================================
2+
// \title FileDispatcher.cpp
3+
// \author tcanham
4+
// \brief cpp file for FileDispatcher component implementation class
5+
// ======================================================================
6+
7+
#include "Svc/FileDispatcher/FileDispatcher.hpp"
8+
#include "Fw/Types/StringUtils.hpp"
9+
10+
namespace Svc {
11+
12+
// ----------------------------------------------------------------------
13+
// Component construction and destruction
14+
// ----------------------------------------------------------------------
15+
16+
FileDispatcher ::FileDispatcher(const char* const compName) : FileDispatcherComponentBase(compName) {
17+
// disable entries
18+
for (FwSizeType i = 0; i < Svc::FileDispatcherCfg::FILE_DISPATCHER_MAX_TABLE_SIZE; i++) {
19+
this->m_dispatchTable.entries[i].enabled = false;
20+
}
21+
this->m_dispatchTable.numEntries = 0;
22+
}
23+
24+
FileDispatcher ::~FileDispatcher() {}
25+
26+
void FileDispatcher ::configure(const FileDispatcherTable& table) {
27+
// validate table
28+
FW_ASSERT(table.numEntries <= Svc::FileDispatcherCfg::FILE_DISPATCHER_MAX_TABLE_SIZE);
29+
for (FwSizeType entry = 0; entry < table.numEntries; entry++) {
30+
FW_ASSERT(table.entries[entry].port.isValid(),
31+
table.entries[entry].port.e); // valid output port
32+
FW_ASSERT(table.entries[entry].fileExt.length() > 0,
33+
static_cast<FwAssertArgType>(table.entries[entry].fileExt.length())); // non-zero length
34+
// Copy over table entry
35+
this->m_dispatchTable.entries[entry].port = table.entries[entry].port;
36+
this->m_dispatchTable.entries[entry].fileExt = table.entries[entry].fileExt;
37+
this->m_dispatchTable.entries[entry].enabled = table.entries[entry].enabled;
38+
}
39+
// Set number of entries
40+
this->m_dispatchTable.numEntries = table.numEntries;
41+
}
42+
43+
// ----------------------------------------------------------------------
44+
// Handler implementations for typed input ports
45+
// ----------------------------------------------------------------------
46+
47+
void FileDispatcher ::fileAnnounceRecv_handler(FwIndexType portNum, Fw::StringBase& file_name) {
48+
// determine file extension and dispatch accordingly
49+
50+
// walk table to find match
51+
for (FwSizeType i = 0; i < this->m_dispatchTable.numEntries; i++) {
52+
if (!this->m_dispatchTable.entries[i].enabled) {
53+
continue;
54+
}
55+
56+
auto loc = Fw::StringUtils::substring_find_last(file_name.toChar(), file_name.length(),
57+
this->m_dispatchTable.entries[i].fileExt.toChar(),
58+
this->m_dispatchTable.entries[i].fileExt.length());
59+
60+
if ((loc != -1) && // matches at all
61+
(file_name.length() - this->m_dispatchTable.entries[i].fileExt.length() ==
62+
static_cast<FwSizeType>(loc)) // match at end of string
63+
) {
64+
// dispatch on this port
65+
this->fileDispatch_out(this->m_dispatchTable.entries[i].port.e, file_name);
66+
this->log_ACTIVITY_HI_FileDispatched(file_name, this->m_dispatchTable.entries[i].port);
67+
}
68+
}
69+
}
70+
71+
// ----------------------------------------------------------------------
72+
// Handler implementations for commands
73+
// ----------------------------------------------------------------------
74+
75+
void FileDispatcher ::ENABLE_DISPATCH_cmdHandler(FwOpcodeType opCode,
76+
U32 cmdSeq,
77+
Svc::FileDispatcherCfg::FileDispatchPort file_type,
78+
Fw::Enabled enable) {
79+
for (FwSizeType i = 0; i < this->m_dispatchTable.numEntries; i++) {
80+
if (this->m_dispatchTable.entries[i].port == file_type) {
81+
this->m_dispatchTable.entries[i].enabled = (enable == Fw::Enabled::ENABLED);
82+
}
83+
}
84+
this->log_ACTIVITY_HI_FileDispatchState(file_type, enable);
85+
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
86+
}
87+
88+
void FileDispatcher ::pingIn_handler(FwIndexType portNum, U32 key) {
89+
// return key
90+
this->pingOut_out(0, key);
91+
}
92+
93+
} // namespace Svc
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
module Svc {
2+
@ Component to dispatch uplinked files to various services
3+
active component FileDispatcher {
4+
5+
# @ disable dispatch of a file type
6+
async command ENABLE_DISPATCH(
7+
file_type: Svc.FileDispatcherCfg.FileDispatchPort @< the file type dispatch to enable/disable
8+
enable: Fw.Enabled
9+
) \
10+
opcode 0
11+
12+
##############################################################################
13+
#### Uncomment the following examples to start customizing your component ####
14+
##############################################################################
15+
16+
# @ File type dispatch enabled/disabled event
17+
event FileDispatchState(file_type: Svc.FileDispatcherCfg.FileDispatchPort, enabled: Fw.Enabled) severity activity high format "File dispatch {} state changed: to {}"
18+
19+
# @ File dispatched event
20+
event FileDispatched(file_name: string size FileNameStringSize, file_type: Svc.FileDispatcherCfg.FileDispatchPort) severity activity high format "File {} dispatched to {}"
21+
22+
###############################################################################
23+
# Standard AC Ports: Required for Channels, Events, Commands, and Parameters #
24+
###############################################################################
25+
@ Port for requesting the current time
26+
time get port timeCaller
27+
28+
@ Port for sending command registrations
29+
command reg port cmdRegOut
30+
31+
@ Port for receiving commands
32+
command recv port cmdIn
33+
34+
@ Port for sending command responses
35+
command resp port cmdResponseOut
36+
37+
@ Port for sending textual representation of events
38+
text event port logTextOut
39+
40+
@ Port for sending events to downlink
41+
event port logOut
42+
43+
###############################################################################
44+
# Input ports #
45+
###############################################################################
46+
47+
@ Port for receiving files to dispatch
48+
async input port fileAnnounceRecv: Svc.FileAnnounce
49+
50+
@ Ping in
51+
async input port pingIn: Svc.Ping
52+
53+
###############################################################################
54+
# Output ports #
55+
###############################################################################
56+
57+
@ Port for sending files to dispatch
58+
output port fileDispatch: [Svc.FileDispatcherCfg.FileDispatchPort.MAX_FILE_DISPATCH_PORTS] Svc.FileDispatch
59+
60+
@ Ping out
61+
output port pingOut: Svc.Ping
62+
63+
}
64+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// ======================================================================
2+
// \title FileDispatcher.hpp
3+
// \author tcanham
4+
// \brief hpp file for FileDispatcher component implementation class
5+
// ======================================================================
6+
7+
#ifndef Svc_FileDispatcher_HPP
8+
#define Svc_FileDispatcher_HPP
9+
10+
#include "Svc/FileDispatcher/FileDispatcherComponentAc.hpp"
11+
12+
namespace Svc {
13+
14+
struct FileDispatcherEntry {
15+
Fw::String fileExt; // file extension for dispatch
16+
Svc::FileDispatcherCfg::FileDispatchPort port; // port to dispatch to
17+
bool enabled; // whether dispatching is enabled for this type
18+
};
19+
20+
struct FileDispatcherTable {
21+
FileDispatcherEntry entries[Svc::FileDispatcherCfg::FILE_DISPATCHER_MAX_TABLE_SIZE];
22+
FwSizeType numEntries;
23+
};
24+
25+
class FileDispatcher final : public FileDispatcherComponentBase {
26+
public:
27+
// ----------------------------------------------------------------------
28+
// Component construction and destruction
29+
// ----------------------------------------------------------------------
30+
31+
//! Construct FileDispatcher object
32+
FileDispatcher(const char* const compName //!< The component name
33+
);
34+
35+
//! Destroy FileDispatcher object
36+
~FileDispatcher();
37+
38+
//! configure the component
39+
void configure(const FileDispatcherTable& table);
40+
41+
private:
42+
// ----------------------------------------------------------------------
43+
// Handler implementations for commands
44+
// ----------------------------------------------------------------------
45+
46+
//! Handler implementation for fileRecv
47+
//!
48+
//! Port for receiving files to dispatch
49+
void fileAnnounceRecv_handler(FwIndexType portNum, //!< The port number
50+
Fw::StringBase& file_name //!< The successfully uplinked file
51+
) override;
52+
53+
private:
54+
// ----------------------------------------------------------------------
55+
// Handler implementations for commands
56+
// ----------------------------------------------------------------------
57+
58+
//! Handler implementation for command DISABLE_DISPATCH
59+
void ENABLE_DISPATCH_cmdHandler(
60+
FwOpcodeType opCode, //!< The opcode
61+
U32 cmdSeq, //!< The command sequence number
62+
Svc::FileDispatcherCfg::FileDispatchPort file_type, //!< the file type dispatch to disable
63+
Fw::Enabled enable //!< whether to enable or disable dispatch
64+
) override;
65+
66+
//! Handler implementation for pingIn
67+
//!
68+
//! Ping in
69+
void pingIn_handler(FwIndexType portNum, //!< The port number
70+
U32 key //!< Value to return to pinger
71+
) override;
72+
73+
//! table of dispatch entries
74+
FileDispatcherTable m_dispatchTable;
75+
};
76+
77+
} // namespace Svc
78+
79+
#endif

0 commit comments

Comments
 (0)