Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
traction_modem::RxFlow Class Reference

Object responsible for reading in a stream of bytes over the modem interface and forming the stream of bytes into complete messages. More...

#include <TractionModem.hxx>

Inheritance diagram for traction_modem::RxFlow:
StateFlowBase Executable Notifiable QMember Destructable

Public Types

using BufferType = Buffer< TxMessage >
 
using Receiver = PacketFlowInterface
 

Public Member Functions

 RxFlow (Service *service)
 Constructor.
 
void start (int fd)
 Start the flow using the given interface.
 
void set_listener (Receiver *rcv)
 Register a listener to send incoming messages to.
 
long long get_character_nsec ()
 Get the wire time for a single character.
 
- Public Member Functions inherited from StateFlowBase
void run () override
 Callback from the executor.
 
void notify () override
 Wakeup call arrived.
 
Serviceservice ()
 Return a pointer to the service I am bound to.
 
- Public Member Functions inherited from Executable
void test_deletion ()
 
- Public Member Functions inherited from QMember
void init ()
 Initiailize a QMember, in place of a public placement construction.
 

Private Member Functions

Action reset ()
 Resets the message reception state machine.
 
Action wait_for_base_data ()
 Wait until we have at least as much data as a minimum size message.
 
Action base_data_received ()
 Received at least as much data as the minimum message size.
 
Action header_complete ()
 We think we have a complete header because we just validated a preamble.
 
Action maybe_message_complete ()
 We might have a complete message if we have received enough data.
 
Action resync ()
 Something went wrong in decoding the data stream.
 

Private Attributes

StateFlowTimedSelectHelper helper_ {this}
 Helper for reading in a select flow.
 
string payload_
 We assemble the message here.
 
size_t recvCnt_
 Number of bytes that have been received into payload_, which may be less than payload_.size() since we reserve space ahead of time.
 
Receiverreceiver_
 Incoming messages get routed to this object.
 
int fd_ = -1
 Interface fd.
 

Static Private Attributes

static constexpr long long CHARACTER_NSEC = 10 * SEC_TO_NSEC(1) / 250000
 Used to place a bounds on a timeout of a message.
 
static constexpr unsigned MIN_MESSAGE_SIZE = Defs::LEN_BASE
 Minimum size of a message.
 
static constexpr unsigned MAX_DATA_LEN = Defs::MAX_LEN
 Maximum size of the data portion of a message.
 

Additional Inherited Members

- Static Public Member Functions inherited from StateFlowBase
template<class T , typename... Args>
static void invoke_subflow_and_ignore_result (FlowInterface< Buffer< T > > *target_flow, Args &&... args)
 Calls a helper flow to perform some actions.
 
- Protected Types inherited from StateFlowBase
typedef Action(StateFlowBase::* Callback) ()
 State Flow callback prototype.
 
- Protected Member Functions inherited from StateFlowBase
 StateFlowBase (Service *service)
 Constructor.
 
 ~StateFlowBase ()
 Destructor.
 
void reset_flow (Callback c)
 Resets the flow to the specified state.
 
bool is_state (Callback c)
 
bool is_terminated ()
 
void start_flow (Callback c)
 Resets the flow to the specified state and starts it.
 
Action again ()
 Call the current state again via call_immediately.
 
Action exit ()
 Terminate current StateFlow activity.
 
Action delete_this ()
 Terminates the flow and deletes *this.
 
Action set_terminated ()
 Sets the flow to terminated state.
 
Action call_immediately (Callback c)
 Imediately call the next state upon return.
 
Action wait ()
 Wait for an asynchronous call.
 
Action wait_and_call (Callback c)
 Wait for resource to become available before proceeding to next state.
 
template<class T >
Action allocate_and_call (FlowInterface< Buffer< T > > *target_flow, Callback c, Pool *pool=nullptr)
 Allocates a buffer from a pool and proceed to the next state when allocation is successful.
 
Action allocate_and_call (Callback c, QAsync *queue)
 Allocates an entry from an asynchronous queue, and transitions to a state once the allocation is complete.
 
template<class T >
Buffer< T > * full_allocation_result (FlowInterface< Buffer< T > > *target_flow)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
T * full_allocation_result (TypedQAsync< T > *queue)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
void cast_allocation_result (T **member)
 Takes the result of the asynchronous allocation without resetting the object.
 
template<class T >
Buffer< T > * get_allocation_result (FlowInterface< Buffer< T > > *target_flow)
 Takes the result of the asynchronous allocation.
 
Action yield_and_call (Callback c)
 Place the current flow to the back of the executor, and transition to a new state after we get the CPU again.
 
Action yield ()
 Place the current flow to the back of the executor, and re-try the current state after we get the CPU again.
 
Action sleep_and_call (::Timer *timer, long long timeout_nsec, Callback c)
 Suspends execution of this control flow for a specified time.
 
template<class T , typename... Args>
Action invoke_subflow_and_wait (FlowInterface< Buffer< T > > *target_flow, Callback c, Args &&... args)
 Calls a helper flow to perform some actions.
 
Action read_repeated (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Blocks until size bytes are read and then invokes the next state.
 
Action read_single (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Attempts to read at most size_t bytes, and blocks the caller until at least one byte is read.
 
Action read_nonblocking (StateFlowSelectHelper *helper, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Attempts to read at most size bytes, and then invokes the next state, even if only zero bytes are available right now.
 
Action read_repeated_with_timeout (StateFlowTimedSelectHelper *helper, long long timeout_nsec, int fd, void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Blocks until size bytes are read, or a timeout expires.
 
Action internal_try_read ()
 Implementation state that gets repeatedly called upon every wakeup and tries to make progress on reading.
 
Action write_repeated (StateFlowSelectHelper *helper, int fd, const void *buf, size_t size, Callback c, unsigned priority=Selectable::MAX_PRIO)
 Writes some data into a file descriptor, repeating the operation as necessary until all bytes are written.
 
Action internal_try_write ()
 Implementation state that gets repeatedly called upon every wakeup and tries to make progress on writing.
 
- Protected Member Functions inherited from QMember
 QMember ()
 Constructor.
 
 ~QMember ()
 Destructor.
 
- Protected Attributes inherited from QMember
QMembernext
 pointer to the next member in the queue
 

Detailed Description

Object responsible for reading in a stream of bytes over the modem interface and forming the stream of bytes into complete messages.

Definition at line 142 of file TractionModem.hxx.

Member Typedef Documentation

◆ BufferType

◆ Receiver

Constructor & Destructor Documentation

◆ RxFlow()

traction_modem::RxFlow::RxFlow ( Service service)
inline

Constructor.

Parameters
serviceservice that the flow is bound to

Definition at line 150 of file TractionModem.hxx.

Member Function Documentation

◆ base_data_received()

Action traction_modem::RxFlow::base_data_received ( )
inlineprivate

Received at least as much data as the minimum message size.

Returns
next state is header_complete if valid preamble found, else next state is resync to look for a valid header.

Definition at line 238 of file TractionModem.hxx.

◆ get_character_nsec()

long long traction_modem::RxFlow::get_character_nsec ( )
inline

Get the wire time for a single character.

Parameters
wiretime for a single character in nanoseconds
Todo:
Once we support multi-baud, this should be modified to provide the character nsec at the current baud rate.

Definition at line 172 of file TractionModem.hxx.

◆ header_complete()

Action traction_modem::RxFlow::header_complete ( )
inlineprivate

We think we have a complete header because we just validated a preamble.

Validate that the header meta data (data length) is legit.

Returns
next state is resync on error (invalid data length), else next state is maybe_message_complete.

Definition at line 263 of file TractionModem.hxx.

◆ maybe_message_complete()

Action traction_modem::RxFlow::maybe_message_complete ( )
inlineprivate

We might have a complete message if we have received enough data.

Returns
next state is resync if a timeout occurred or a CRC error is detected, else if we have the likely start to the next message next state is wait_for_base_data, else next state is reset.

Definition at line 295 of file TractionModem.hxx.

◆ reset()

Action traction_modem::RxFlow::reset ( )
inlineprivate

Resets the message reception state machine.

Returns
next state wait_for_base_data()

Definition at line 186 of file TractionModem.hxx.

◆ resync()

Action traction_modem::RxFlow::resync ( )
inlineprivate

Something went wrong in decoding the data stream.

Try to resync on a preamble word.

Returns
next state is wait_for_base_data if a valid preamble word is found, else next state is reset to start over with new data.
Todo:
Should we be sending out a framing error? I think so. How to dispatch that? Maybe an error field in the TxMessage? If we send this to the dispatcher, be sure to add the appropriate EXPECT_CALL(s) to the unit tests.

Definition at line 360 of file TractionModem.hxx.

◆ set_listener()

void traction_modem::RxFlow::set_listener ( Receiver rcv)
inline

Register a listener to send incoming messages to.

Parameters
rcvlister that will receive incoming messages

Definition at line 165 of file TractionModem.hxx.

◆ start()

void traction_modem::RxFlow::start ( int  fd)
inline

Start the flow using the given interface.

Parameters
fdinterface to receive messages on

Definition at line 157 of file TractionModem.hxx.

◆ wait_for_base_data()

Action traction_modem::RxFlow::wait_for_base_data ( )
inlineprivate

Wait until we have at least as much data as a minimum size message.

Returns
next state base_data_received

Definition at line 206 of file TractionModem.hxx.

Member Data Documentation

◆ CHARACTER_NSEC

constexpr long long traction_modem::RxFlow::CHARACTER_NSEC = 10 * SEC_TO_NSEC(1) / 250000
staticconstexprprivate

Used to place a bounds on a timeout of a message.

Definition at line 399 of file TractionModem.hxx.

◆ fd_

int traction_modem::RxFlow::fd_ = -1
private

Interface fd.

Definition at line 418 of file TractionModem.hxx.

◆ helper_

StateFlowTimedSelectHelper traction_modem::RxFlow::helper_ {this}
private

Helper for reading in a select flow.

Definition at line 408 of file TractionModem.hxx.

◆ MAX_DATA_LEN

constexpr unsigned traction_modem::RxFlow::MAX_DATA_LEN = Defs::MAX_LEN
staticconstexprprivate

Maximum size of the data portion of a message.

Definition at line 405 of file TractionModem.hxx.

◆ MIN_MESSAGE_SIZE

constexpr unsigned traction_modem::RxFlow::MIN_MESSAGE_SIZE = Defs::LEN_BASE
staticconstexprprivate

Minimum size of a message.

Definition at line 402 of file TractionModem.hxx.

◆ payload_

string traction_modem::RxFlow::payload_
private

We assemble the message here.

Definition at line 410 of file TractionModem.hxx.

◆ receiver_

Receiver* traction_modem::RxFlow::receiver_
private

Incoming messages get routed to this object.

Definition at line 415 of file TractionModem.hxx.

◆ recvCnt_

size_t traction_modem::RxFlow::recvCnt_
private

Number of bytes that have been received into payload_, which may be less than payload_.size() since we reserve space ahead of time.

Definition at line 413 of file TractionModem.hxx.


The documentation for this class was generated from the following file: