-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add new Svc::ComRetry component #4367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
valdaarhun
wants to merge
7
commits into
nasa:devel
Choose a base branch
from
valdaarhun:com_retry
base: devel
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
81abad0
Add new Svc::ComRetry component
valdaarhun 4d5dca0
Add name to gh-action's spelling/expect.txt
valdaarhun 3e84e90
Fix compilation errors
valdaarhun c553ee9
Add CMakeLists.txt for ComRetry
valdaarhun c9d134d
Add 'ComRetry' tests
valdaarhun f88acf9
Add documentation
valdaarhun 437174a
Fix errors identified by check-spelling job
valdaarhun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| #### | ||
| # F Prime CMakeLists.txt: | ||
| # | ||
| # SOURCES: list of source files (to be compiled) | ||
| # AUTOCODER_INPUTS: list of files to be passed to the autocoders | ||
| # DEPENDS: list of libraries that this module depends on | ||
| # | ||
| # More information in the F´ CMake API documentation: | ||
| # https://fprime.jpl.nasa.gov/latest/docs/reference/api/cmake/API/ | ||
| # | ||
| #### | ||
|
|
||
| register_fprime_library( | ||
| AUTOCODER_INPUTS | ||
| "${CMAKE_CURRENT_LIST_DIR}/ComRetry.fpp" | ||
| SOURCES | ||
| "${CMAKE_CURRENT_LIST_DIR}/ComRetry.cpp" | ||
| DEPENDS | ||
| Fw_Types | ||
| Fw_Buffer | ||
| ) | ||
|
|
||
| ### UTs ### | ||
| register_fprime_ut( | ||
| SOURCES | ||
| "${CMAKE_CURRENT_LIST_DIR}/test/ut/ComRetryTestMain.cpp" | ||
| "${CMAKE_CURRENT_LIST_DIR}/test/ut/ComRetryTester.cpp" | ||
| AUTOCODER_INPUTS | ||
| "${CMAKE_CURRENT_LIST_DIR}/ComRetry.fpp" | ||
| UT_AUTO_HELPERS | ||
| ) | ||
|
|
||
| set (UT_TARGET_NAME "${FPRIME_CURRENT_MODULE}_ut_exe") | ||
| if (TARGET "${UT_TARGET_NAME}") | ||
| target_compile_options("${UT_TARGET_NAME}" PRIVATE -Wno-conversion) | ||
| endif() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| // ====================================================================== | ||
| // \title ComRetry.cpp | ||
| // \author valdaarhun | ||
| // \brief cpp file for ComRetry component implementation class | ||
| // ====================================================================== | ||
|
|
||
| #include "Svc/ComRetry/ComRetry.hpp" | ||
| #include "ComRetry.hpp" | ||
|
|
||
| namespace Svc { | ||
|
|
||
| // ---------------------------------------------------------------------- | ||
| // Component construction and destruction | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| ComRetry ::ComRetry(const char* const compName) | ||
| : ComRetryComponentBase(compName), | ||
| m_num_retries(1), | ||
| m_retry_count(0), | ||
| m_bufferState(Fw::Buffer::OwnershipState::OWNED) {} | ||
|
|
||
| ComRetry ::~ComRetry() {} | ||
|
|
||
| void ComRetry::configure(U32 num_retries) { | ||
| this->m_num_retries = num_retries; | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------------- | ||
| // Handler implementations for typed input ports | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| void ComRetry ::comStatusIn_handler(FwIndexType portNum, Fw::Success& condition) { | ||
| if (condition == Fw::Success::SUCCESS) { | ||
| this->m_retry_count = 0; | ||
| this->dataReturnOut_out(0, this->m_buffer, this->m_context); | ||
| this->comStatusOut_out(0, condition); | ||
| } | ||
| // Delivery of last message failed | ||
| else if (this->m_retry_count < this->m_num_retries) { | ||
| FW_ASSERT(this->m_bufferState == Fw::Buffer::OwnershipState::OWNED); | ||
| this->m_retry_count++; | ||
| this->m_bufferState = Fw::Buffer::OwnershipState::NOT_OWNED; | ||
| this->dataOut_out(0, this->m_buffer, this->m_context); | ||
| } | ||
| // All retries failed, send FAILURE to upstream component | ||
| else { | ||
| this->m_retry_count = 0; | ||
| condition = Fw::Success::FAILURE; | ||
| this->dataReturnOut_out(0, this->m_buffer, this->m_context); | ||
| this->comStatusOut_out(0, condition); | ||
| } | ||
| } | ||
|
|
||
| void ComRetry ::dataIn_handler(FwIndexType portNum, Fw::Buffer& buffer, const ComCfg::FrameContext& context) { | ||
| FW_ASSERT(this->m_bufferState == Fw::Buffer::OwnershipState::OWNED); | ||
| this->m_bufferState = Fw::Buffer::OwnershipState::NOT_OWNED; | ||
| this->dataOut_out(0, buffer, context); | ||
| } | ||
|
|
||
| void ComRetry ::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& buffer, const ComCfg::FrameContext& context) { | ||
| FW_ASSERT(this->m_bufferState == Fw::Buffer::OwnershipState::NOT_OWNED); | ||
| this->m_bufferState = Fw::Buffer::OwnershipState::OWNED; | ||
| this->m_buffer = buffer; | ||
| this->m_context = context; | ||
| } | ||
|
|
||
| } // namespace Svc | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| module Svc { | ||
| @ A component for retrying message delivery on failure | ||
| passive component ComRetry { | ||
| import Svc.Framer | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // ====================================================================== | ||
| // \title ComRetry.hpp | ||
| // \author valdaarhun | ||
| // \brief hpp file for ComRetry component implementation class | ||
| // ====================================================================== | ||
|
|
||
| #ifndef Svc_ComRetry_HPP | ||
| #define Svc_ComRetry_HPP | ||
|
|
||
| #include "Svc/ComRetry/ComRetryComponentAc.hpp" | ||
|
|
||
| namespace Svc { | ||
|
|
||
| class ComRetry final : public ComRetryComponentBase { | ||
| public: | ||
| // ---------------------------------------------------------------------- | ||
| // Component construction and destruction | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| //! Construct ComRetry object | ||
| ComRetry(const char* const compName //!< The component name | ||
| ); | ||
|
|
||
| //! Destroy ComRetry object | ||
| ~ComRetry(); | ||
|
|
||
| //! Configure the number of retries | ||
| void configure(U32 num_retries //!< Number of retries allowed | ||
| ); | ||
|
|
||
| private: | ||
| // ---------------------------------------------------------------------- | ||
| // Handler implementations for typed input ports | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| //! Handler implementation for comStatusIn | ||
| //! | ||
| //! Resend last delivered message on failure | ||
| void comStatusIn_handler(FwIndexType portNum, //!< The port number | ||
| Fw::Success& condition //!< Condition success/failure | ||
| ) override; | ||
|
|
||
| //! Handler implementation for dataIn | ||
| //! | ||
| //! Port to receive data in a Fw::Buffer with optional context | ||
| void dataIn_handler(FwIndexType portNum, //!< The port number | ||
| Fw::Buffer& data, | ||
| const ComCfg::FrameContext& context) override; | ||
|
|
||
| //! Handler implementation for dataReturnIn | ||
| //! | ||
| //! Buffer coming from a deallocate call in a ComDriver component | ||
| void dataReturnIn_handler(FwIndexType portNum, //!< The port number | ||
| Fw::Buffer& data, | ||
| const ComCfg::FrameContext& context) override; | ||
|
|
||
| private: | ||
| // ---------------------------------------------------------------------- | ||
| // Member variables | ||
| // ---------------------------------------------------------------------- | ||
| U32 m_num_retries; //!< Maximum number of retries | ||
| U32 m_retry_count; //!< Track number of attempted retries | ||
| ComCfg::FrameContext m_context; //!< Context for the current frame | ||
| Fw::Buffer m_buffer; //!< Store incoming buffer | ||
| Fw::Buffer::OwnershipState m_bufferState; //!< Track ownership of stored buffer | ||
| }; | ||
|
|
||
| } // namespace Svc | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # Svc::ComRetry | ||
|
|
||
| ## 1. Introduction | ||
|
|
||
| The `Svc::ComRetry` component forwards messages from upstream to downstream components, resending messages on failure. Any topology requiring retry capabilities must place this component in the pipeline before a `ComStub` or `Radio` component. This component expects a `ComStatus` response. It acts as a pass-through component in case of a successful delivery, i.e. when it receives `Fw::Success::SUCCESS`. On receiving `Fw::Success::FAILURE`, it resends the message until it exceeds the maximum number of retries. | ||
|
|
||
| `Svc::ComRetry` can be used alongside the other F´ communication components (`Svc::Framer`, `Svc::Deframer`, `Svc::ComQueue`). | ||
|
|
||
| ## 2. Requirements | ||
|
|
||
| | Requirement | Description | Rationale | Verification Method | | ||
| |-----------------|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|---------------------| | ||
| | SVC-COMRETRY-001 | `Svc::ComRetry` shall accept incoming downlink data as `Fw::Buffer` and pass them to an `Svc.ComDataWithContext` port | The component must forward messages without modifying them | Unit Test | | ||
| | SVC-COMRETRY-002 | `Svc::ComRetry` shall store `Fw::Buffer` and its context on receiving buffer ownership through `dataReturnIn` | Store the buffer in case a retry is required | Unit test | | ||
| | SVC-COMRETRY-003 | `Svc::ComRetry` shall resend the stored `Fw::Buffer` on receiving `Fw::Success::FAILURE` | Retry delivery of message | Unit test | | ||
| | SVC-COMRETRY-004 | The maximum number of retries shall be configurable | The number of retries should be adaptable for projects | Inspection | | ||
| | SVC-COMRETRY-005 | `Svc::ComRetry` shall return buffer ownership to the upstream component on receiving `Fw::Success::SUCCESS` or after all retry attempts fail | Memory management | Unit Test | | ||
| | SVC-COMRETRY-006 | `Svc::ComRetry` shall send `ComStatus` upstream on successful delivery or after all retry attempts fail | Upstream component must receive status of message delivery from downstream | Unit Test | | ||
|
|
||
| ## 3. Design | ||
|
|
||
| `Svc::ComRetry` implements `Svc.Framer`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // ====================================================================== | ||
| // \title ComRetryTestMain.cpp | ||
| // \author valdaarhun | ||
| // \brief cpp file for ComRetry test main function | ||
| // ====================================================================== | ||
|
|
||
| #include "ComRetryTester.hpp" | ||
|
|
||
| TEST(Nominal, Send) { | ||
| Svc::ComRetryTester tester; | ||
| tester.testBufferSend(); | ||
| } | ||
|
|
||
| TEST(Nominal, Retry) { | ||
| Svc::ComRetryTester tester; | ||
| tester.testBufferRetry(); | ||
| } | ||
|
|
||
| TEST(Nominal, RetryTillFailure) { | ||
| Svc::ComRetryTester tester; | ||
| tester.testBufferRetryTillFailure(); | ||
| } | ||
|
|
||
| int main(int argc, char** argv) { | ||
| ::testing::InitGoogleTest(&argc, argv); | ||
| return RUN_ALL_TESTS(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| // ====================================================================== | ||
| // \title ComRetryTester.cpp | ||
| // \author valdaarhun | ||
| // \brief cpp file for ComRetry test harness implementation class | ||
| // ====================================================================== | ||
|
|
||
| #include "ComRetryTester.hpp" | ||
|
|
||
| namespace Svc { | ||
|
|
||
| // ---------------------------------------------------------------------- | ||
| // Construction and destruction | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| ComRetryTester ::ComRetryTester() | ||
| : ComRetryGTestBase("ComRetryTester", ComRetryTester::MAX_HISTORY_SIZE), component("ComRetry") { | ||
| this->initComponents(); | ||
| this->connectPorts(); | ||
| } | ||
|
|
||
| ComRetryTester ::~ComRetryTester() {} | ||
|
|
||
| void ComRetryTester ::configure(U32 num_retries=1) { | ||
| component.configure(num_retries); | ||
| } | ||
|
|
||
| void ComRetryTester ::receiveBuffer(Fw::Buffer &buffer, ComCfg::FrameContext &context) { | ||
| invoke_to_dataIn(0, buffer, context); | ||
| invoke_to_dataReturnIn(0, buffer, context); | ||
| } | ||
|
|
||
| void ComRetryTester ::checkDataOut(FwIndexType expectedIndex, U8* expectedData, FwSizeType expectedDataSize) { | ||
| Fw::Buffer emittedBuffer = this->fromPortHistory_dataOut->at(expectedIndex).data; | ||
| ASSERT_EQ(expectedDataSize, emittedBuffer.getSize()); | ||
| for (FwSizeType i = 0; i < expectedDataSize; i++) { | ||
| ASSERT_EQ(emittedBuffer.getData()[i], expectedData[i]); | ||
| } | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------------- | ||
| // Tests | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| void ComRetryTester ::testBufferSend() { | ||
| U8 data_a[BUFFER_LENGTH] = DATA_A; | ||
| U8 data_b[BUFFER_LENGTH] = DATA_B; | ||
| Fw::Buffer buffer_a(&data_a[0], sizeof(data_a)); | ||
| Fw::Buffer buffer_b(&data_b[0], sizeof(data_b)); | ||
| ComCfg::FrameContext nullContext; | ||
| Fw::Success state = Fw::Success::SUCCESS; | ||
| configure(); | ||
|
|
||
| receiveBuffer(buffer_a, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| ASSERT_from_dataReturnOut(0, buffer_a, nullContext); | ||
| ASSERT_from_comStatusOut(0, state); | ||
|
|
||
| receiveBuffer(buffer_b, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| ASSERT_from_dataReturnOut(1, buffer_b, nullContext); | ||
| ASSERT_from_comStatusOut(1, state); | ||
|
|
||
| checkDataOut(0, buffer_a.getData(), buffer_a.getSize()); | ||
| checkDataOut(1, buffer_b.getData(), buffer_b.getSize()); | ||
| } | ||
|
|
||
| void ComRetryTester ::testBufferRetry() { | ||
| U8 data_a[BUFFER_LENGTH] = DATA_A; | ||
| U8 data_b[BUFFER_LENGTH] = DATA_B; | ||
| Fw::Buffer buffer_a(&data_a[0], sizeof(data_a)); | ||
| Fw::Buffer buffer_b(&data_b[0], sizeof(data_b)); | ||
| ComCfg::FrameContext nullContext; | ||
| Fw::Success state = Fw::Success::FAILURE; | ||
| configure(); | ||
|
|
||
| receiveBuffer(buffer_a, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| invoke_to_dataReturnIn(0, buffer_a, nullContext); | ||
|
|
||
| state = Fw::Success::SUCCESS; | ||
| invoke_to_comStatusIn(0, state); | ||
| ASSERT_from_dataReturnOut(0, buffer_a, nullContext); | ||
| ASSERT_from_comStatusOut(0, state); | ||
|
|
||
| receiveBuffer(buffer_b, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| ASSERT_from_dataReturnOut(1, buffer_b, nullContext); | ||
| ASSERT_from_comStatusOut(1, state); | ||
|
|
||
| checkDataOut(0, buffer_a.getData(), buffer_a.getSize()); | ||
| checkDataOut(1, buffer_a.getData(), buffer_a.getSize()); | ||
| checkDataOut(2, buffer_b.getData(), buffer_b.getSize()); | ||
| } | ||
|
|
||
| void ComRetryTester ::testBufferRetryTillFailure() { | ||
| U8 data_a[BUFFER_LENGTH] = DATA_A; | ||
| U8 data_b[BUFFER_LENGTH] = DATA_B; | ||
| Fw::Buffer buffer_a(&data_a[0], sizeof(data_a)); | ||
| Fw::Buffer buffer_b(&data_b[0], sizeof(data_b)); | ||
| ComCfg::FrameContext nullContext; | ||
| Fw::Success state = Fw::Success::FAILURE; | ||
|
|
||
| FwIndexType num_retries = 3; | ||
| configure(num_retries); | ||
|
|
||
| receiveBuffer(buffer_a, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| checkDataOut(0, buffer_a.getData(), buffer_a.getSize()); | ||
|
|
||
| for (FwIndexType i = 1; i <= num_retries; i++) { | ||
| invoke_to_dataReturnIn(0, buffer_a, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| checkDataOut(i, buffer_a.getData(), buffer_a.getSize()); | ||
| } | ||
|
|
||
| ASSERT_from_dataReturnOut(0, buffer_a, nullContext); | ||
| ASSERT_from_comStatusOut(0, state); | ||
|
|
||
| state = Fw::Success::SUCCESS; | ||
| receiveBuffer(buffer_b, nullContext); | ||
| invoke_to_comStatusIn(0, state); | ||
| ASSERT_from_dataReturnOut(1, buffer_b, nullContext); | ||
| ASSERT_from_comStatusOut(1, state); | ||
| checkDataOut(num_retries + 1, buffer_b.getData(), buffer_b.getSize()); | ||
| } | ||
|
|
||
| } // namespace Svc |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.