Skip to content

Commit

Permalink
Add stream crossover component (#2070)
Browse files Browse the repository at this point in the history
* stream crossover component

* Add StreamCrossover Documentation

* Add unit tests, update expect.txt

* Add coverage for send error

* update test name from ToDo to TestBuffer

* Check recvStatus, and deallocate on error

* Check recvBuffer size, rename errorDeallocate
  • Loading branch information
ethancheez authored and thomas-bc committed Aug 4, 2023
1 parent a98975a commit 7cca7cb
Show file tree
Hide file tree
Showing 10 changed files with 412 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ ERRORCHECK
errorlevel
errornum
ert
ethanchee
etime
ETIMEDOUT
eturn
Expand Down
1 change: 1 addition & 0 deletions Drv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxGpioDriver/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxUartDriver/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxSpiDriver/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LinuxI2cDriver/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/StreamCrossover/")

# IP Socket is only supported for Linux, Darwin, VxWorks
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR ${CMAKE_SYSTEM_NAME} STREQUAL "VxWorks")
Expand Down
22 changes: 22 additions & 0 deletions Drv/StreamCrossover/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
####
# F prime CMakeLists.txt:
#
# SOURCE_FILES: combined list of source and autocoding files
# MOD_DEPS: (optional) module dependencies
#
####
set(SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/StreamCrossover.fpp"
"${CMAKE_CURRENT_LIST_DIR}/StreamCrossover.cpp"
)

register_fprime_module()

# Register the unit test build
set(UT_SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/StreamCrossover.fpp"
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Tester.cpp"
"${CMAKE_CURRENT_LIST_DIR}/test/ut/TestMain.cpp"
)
set(UT_AUTO_HELPERS ON)
register_fprime_ut()
57 changes: 57 additions & 0 deletions Drv/StreamCrossover/StreamCrossover.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// ======================================================================
// \title StreamCrossover.cpp
// \author ethanchee
// \brief cpp file for StreamCrossover component implementation class
// ======================================================================


#include <Drv/StreamCrossover/StreamCrossover.hpp>
#include <FpConfig.hpp>

namespace Drv {

// ----------------------------------------------------------------------
// Construction, initialization, and destruction
// ----------------------------------------------------------------------

StreamCrossover ::
StreamCrossover(
const char *const compName
) : StreamCrossoverComponentBase(compName)
{

}

StreamCrossover ::
~StreamCrossover()
{

}

// ----------------------------------------------------------------------
// Handler implementations for user-defined typed input ports
// ----------------------------------------------------------------------

void StreamCrossover ::
streamIn_handler(
const NATIVE_INT_TYPE portNum,
Fw::Buffer &recvBuffer,
const Drv::RecvStatus &recvStatus
)
{
if(recvStatus == Drv::RecvStatus::RECV_ERROR || recvBuffer.getSize() == 0)
{
this->log_WARNING_HI_StreamOutError(Drv::SendStatus::SEND_ERROR);
this->errorDeallocate_out(0, recvBuffer);
return;
}

Drv::SendStatus sendStatus = this->streamOut_out(0, recvBuffer);

if(sendStatus != Drv::SendStatus::SEND_OK)
{
this->log_WARNING_HI_StreamOutError(sendStatus);
}
}

} // end namespace Drv
28 changes: 28 additions & 0 deletions Drv/StreamCrossover/StreamCrossover.fpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Drv {

passive component StreamCrossover {

output port streamOut: Drv.ByteStreamSend

sync input port streamIn: Drv.ByteStreamRecv

@ Indicates buffer failed to send to streamOut.
event StreamOutError(sendStatus: Drv.SendStatus) \
severity warning high \
format "StreamCrossover StreamOut Error: {}"

@ Allows for deallocation after bad receive status
output port errorDeallocate: Fw.BufferSend

@ Port for requesting the current time
time get port timeCaller

@ Port for sending textual representation of events
text event port logTextOut

@ Port for sending events to downlink
event port logOut

}

}
53 changes: 53 additions & 0 deletions Drv/StreamCrossover/StreamCrossover.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// ======================================================================
// \title StreamCrossover.hpp
// \author ethanchee
// \brief hpp file for StreamCrossover component implementation class
// ======================================================================

#ifndef StreamCrossover_HPP
#define StreamCrossover_HPP

#include "Drv/StreamCrossover/StreamCrossoverComponentAc.hpp"

namespace Drv {

class StreamCrossover :
public StreamCrossoverComponentBase
{

public:

// ----------------------------------------------------------------------
// Construction, initialization, and destruction
// ----------------------------------------------------------------------

//! Construct object StreamCrossover
//!
StreamCrossover(
const char *const compName /*!< The component name*/
);

//! Destroy object StreamCrossover
//!
~StreamCrossover();

PRIVATE:

// ----------------------------------------------------------------------
// Handler implementations for user-defined typed input ports
// ----------------------------------------------------------------------

//! Handler implementation for streamIn
//!
void streamIn_handler(
const NATIVE_INT_TYPE portNum, /*!< The port number*/
Fw::Buffer &recvBuffer,
const Drv::RecvStatus &recvStatus
);


};

} // end namespace Drv

#endif
30 changes: 30 additions & 0 deletions Drv/StreamCrossover/docs/sdd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
\page DrvStreamCrossover Drv::StreamCrossover Stream Crossover Component
# Drv::StreamCrossover Stream Crossover Component

The Stream Crossover component allows a connection of byte stream driver model ports of type ByteStreamRecv and
ByteStreamSend.

## Design

The Drv::StreamCrossover utilizes the byte stream driver model to handle the incoming stream of bytes. Upon calling
the "streamIn" port, the `Fw::Buffer` containing the data will be forwarded to the "streamOut" port. This enables a
connection from a ByteStreamRecv port to a ByteStreamSend port.

## Port Descriptions
| Name | Description |
|---|---|
| streamOut | A ByteStreamSend port for outgoing data stored in `Fw::Buffer` |
| streamIn | A ByteStreamRecv port for incoming data stored in `Fw::Buffer` |
| errorDeallocate | Deallocate a `Fw::Buffer` on error |

## Requirements
Add requirements in the chart below
| Name | Description | Validation |
|---|---|---|
| STREAM-CROSSOVER-COMP-001 | The stream crossover component shall provide the capability to forward bytes | Unit Test |

## Change Log
| Date | Description |
|---|---|
| 2023-06-05 | Initial Draft |
| 2023-06-09 | Implement Error Handling |
20 changes: 20 additions & 0 deletions Drv/StreamCrossover/test/ut/TestMain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ----------------------------------------------------------------------
// TestMain.cpp
// ----------------------------------------------------------------------

#include "Tester.hpp"

TEST(Nominal, TestBuffer) {
Drv::Tester tester;
tester.sendTestBuffer();
}

TEST(Nominal, TestFail) {
Drv::Tester tester;
tester.testFail();
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
101 changes: 101 additions & 0 deletions Drv/StreamCrossover/test/ut/Tester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// ======================================================================
// \title StreamCrossover.hpp
// \author ethanchee
// \brief cpp file for StreamCrossover test harness implementation class
// ======================================================================

#include "Tester.hpp"

namespace Drv {

// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------

Tester ::
Tester() :
StreamCrossoverGTestBase("Tester", Tester::MAX_HISTORY_SIZE),
component("StreamCrossover")
{
this->initComponents();
this->connectPorts();
}

Tester ::
~Tester()
{

}

// ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------

void Tester ::
sendTestBuffer()
{
U8 testStr[6] = "test\n";
Fw::Buffer sendBuffer(testStr, sizeof(testStr));
this->invoke_to_streamIn(0, sendBuffer, Drv::RecvStatus::RECV_OK);

// Ensure only one buffer was sent to streamOut
ASSERT_from_streamOut_SIZE(1);

// Ensure the sendBuffer was sent
ASSERT_from_streamOut(0, sendBuffer);
}

void Tester ::
testFail()
{
U8 testStr[6] = "test\n";
Fw::Buffer sendBuffer(testStr, sizeof(testStr));
this->invoke_to_streamIn(0, sendBuffer, Drv::RecvStatus::RECV_ERROR);

// Ensure only one buffer was sent to errorDeallocate port on RECV_ERROR
ASSERT_from_errorDeallocate_SIZE(1);

// Ensure the sendBuffer was sent
ASSERT_from_errorDeallocate(0, sendBuffer);

// Ensure the error event was sent
ASSERT_EVENTS_StreamOutError_SIZE(1);

// Ensure the error is SEND_ERROR
ASSERT_EVENTS_StreamOutError(0, Drv::SendStatus::SEND_ERROR);
}

// ----------------------------------------------------------------------
// Handlers for typed from ports
// ----------------------------------------------------------------------

Drv::SendStatus Tester ::
from_streamOut_handler(
const NATIVE_INT_TYPE portNum,
Fw::Buffer &sendBuffer
)
{
this->pushFromPortEntry_streamOut(sendBuffer);

U8 testStr[6] = "test\n";
Fw::Buffer cmpBuffer(testStr, sizeof(testStr));

if(!(cmpBuffer == sendBuffer))
{
return Drv::SendStatus::SEND_ERROR;
}

return Drv::SendStatus::SEND_OK;
}

void Tester ::
from_errorDeallocate_handler(
const NATIVE_INT_TYPE portNum,
Fw::Buffer &fwBuffer
)
{
this->pushFromPortEntry_errorDeallocate(fwBuffer);
}


} // end namespace Drv
Loading

0 comments on commit 7cca7cb

Please sign in to comment.