|
Open Model Railroad Network (OpenMRN)
|
Datagram client implementation for CANbus-based datagram protocol. More...
#include <DatagramImpl.hxx>
Classes | |
| class | ReplyListener |
| This object is registered to receive response messages at the interface level. More... | |
Public Member Functions | |
| DatagramClientImpl (If *iface, MessageHandler *send_flow) | |
| Constructor. | |
| void | write_datagram (Buffer< GenMessage > *b, unsigned priority) OVERRIDE |
| Triggers sending a datagram. | |
| void | cancel () OVERRIDE |
| Requests cancelling the datagram send operation. | |
Public Member Functions inherited from openlcb::DatagramClient | |
| uint32_t | result () |
| Returns a bitmask of ResultCodes for the transmission operation. | |
Public Member Functions inherited from QMember | |
| void | init () |
| Initiailize a QMember, in place of a public placement construction. | |
Public Member Functions inherited from StateFlowBase | |
| void | run () override |
| Callback from the executor. | |
| void | notify () override |
| Wakeup call arrived. | |
| Service * | service () |
| Return a pointer to the service I am bound to. | |
Public Member Functions inherited from Executable | |
| void | test_deletion () |
Public Member Functions inherited from LinkedObject< DatagramClientImpl > | |
| DatagramClientImpl * | link_next () |
Private Member Functions | |
| void | reset_message (Buffer< GenMessage > *b, unsigned priority) |
| Equivalent to enqueuing a new datagram to send. | |
| Action | start_send () |
| Entry point to the flow processing. | |
| Action | acquire_srcdst_lock () |
| Ensures that there is no other datagram client with the same src:dst pair. | |
| Action | do_send () |
| Hands off the datagram to the send flow. | |
| void | register_handlers () |
| Action | timeout_looking_for_dst () |
| Action | timeout_waiting_for_dg_response () |
| void | unregister_response_handler () |
| Action | datagram_finalize () |
| void | handle_response (GenMessage *message) |
| Callback when a matching response comes in on the bus. | |
| void | stop_waiting_for_response () |
| To be called from the handler. | |
| void | notify () override |
| Overrides the default notify implementation to make sure we obey the priority values. | |
| void | set_priority (unsigned p) |
| Sets the stateflow priority. | |
| If * | iface () |
Private Attributes | |
| Buffer< GenMessage > * | message_ {nullptr} |
| Datagram message we are trying to send now. We own it. | |
| BarrierNotifiable * | done_ {nullptr} |
| This notifiable is saved from the datagram buffer. | |
| NodeHandle | src_ |
| Source of the datagram we are currently sending. | |
| NodeHandle | dst_ |
| Destination of the datagram we are currently sending. | |
| MessageHandler * | sendFlow_ |
| Addressed datagram send flow from the interface. Externally owned. | |
| ReplyListener | listener_ |
| Instance of the listener object. | |
| StateFlowTimer | timer_ {this} |
| Helper object for sleep. | |
| TypedQueue< Executable > | waitingClients_ |
| List of other datagram clients that are trying to send to the same target node. | |
| unsigned | isSleeping_: 1 |
| 1 when we are in the sleep call waiting for the datagram Ack or Reject message. | |
| unsigned | hasResponse_: 1 |
| unsigned | sendPending_: 1 |
| 1 when we have the handlers registered. | |
| unsigned | priority_: 24 |
| Priority in the executor. | |
Static Private Attributes | |
| static constexpr unsigned | MAX_PRIORITY = (1 << 24) - 1 |
| Constant used to clamp the incoming priority value to something that first in priority_ bit field. | |
Additional Inherited Members | |
Public Types inherited from openlcb::DatagramClient | |
| enum | ResultCodes { PERMANENT_ERROR = 0x1000 , RESEND_OK = 0x2000 , TRANSPORT_ERROR = 0x4000 , BUFFER_UNAVAILABLE = 0x0020 , OUT_OF_ORDER = 0x0040 , SOURCE_NOT_PERMITTED = 0x0020 , DATAGRAMS_NOT_ACCEPTED = 0x0040 , OPERATION_SUCCESS = 0x10000 , OPERATION_PENDING = 0x20000 , DST_NOT_FOUND = Defs::ERROR_DST_NOT_FOUND , TIMEOUT = Defs::OPENMRN_TIMEOUT , DST_REBOOT = Defs::ERROR_DST_REBOOT , RESPONSE_FLAGS_SHIFT = 24 , RESPONSE_CODE_MASK = (1<<RESPONSE_FLAGS_SHIFT) - 1 , OK_REPLY_PENDING = (1 << 31) } |
| Known result codes from the DatagramClient. More... | |
| enum | ResponseFlag { REPLY_PENDING = 0x80 , REPLY_TIMEOUT_SEC = 0x1 , REPLY_TIMEOUT_MASK = 0xf } |
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. | |
Static Public Member Functions inherited from LinkedObject< DatagramClientImpl > | |
| static DatagramClientImpl * | link_head () |
| static Atomic * | head_mu () |
| Locks the list for modification (at any entry!). | |
Protected Types inherited from StateFlowBase | |
| typedef Action(StateFlowBase::* | Callback) () |
| State Flow callback prototype. | |
Protected Member Functions inherited from QMember | |
| QMember () | |
| Constructor. | |
| ~QMember () | |
| Destructor. | |
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 LinkedObject< DatagramClientImpl > | |
| DatagramClientImpl * | link_this () |
| LinkedObject () | |
| Constructor. Puts *this on the linked list. | |
| ~LinkedObject () | |
| Constructor. Removes *this from the linked list. | |
Protected Attributes inherited from openlcb::DatagramClient | |
| uint32_t | result_ |
Protected Attributes inherited from QMember | |
| QMember * | next |
| pointer to the next member in the queue | |
Protected Attributes inherited from LinkedObject< DatagramClientImpl > | |
| DatagramClientImpl * | link_ |
| Linked list pointer. | |
Static Protected Attributes inherited from LinkedObject< DatagramClientImpl > | |
| static DatagramClientImpl * | head_ |
| Beginning of the list. | |
Datagram client implementation for CANbus-based datagram protocol.
This flow is responsible for the outgoing CAN datagram framing, and listens for incoming datagram response messages.
The base class of AddressedCanMessageWriteFlow is responsible for the discovery and address resolution of the destination node.
Definition at line 52 of file DatagramImpl.hxx.
|
private |
Definition at line 159 of file DatagramImpl.hxx.
|
inline |
Constructor.
| iface | is the service on which to run this flow |
| send_flow | can receive an (addressed) Datagram message and send it to the appropriate destination – takes care of fragmenting etc. |
Definition at line 61 of file DatagramImpl.hxx.
|
inlineprivate |
Ensures that there is no other datagram client with the same src:dst pair.
This is required by the standard.
Definition at line 113 of file DatagramImpl.hxx.
|
inlinevirtual |
Requests cancelling the datagram send operation.
Will notify the done callback when the canceling is completed.
Implements openlcb::DatagramClient.
Definition at line 84 of file DatagramImpl.hxx.
|
inlineprivate |
Definition at line 223 of file DatagramImpl.hxx.
|
inlineprivate |
Hands off the datagram to the send flow.
Definition at line 141 of file DatagramImpl.hxx.
|
inlineprivate |
Callback when a matching response comes in on the bus.
| message | is the incoming generic message (from the response buffer). |
Definition at line 259 of file DatagramImpl.hxx.
|
inlineprivate |
Definition at line 392 of file DatagramImpl.hxx.
|
inlineoverrideprivatevirtual |
Overrides the default notify implementation to make sure we obey the priority values.
Implements Notifiable.
Definition at line 379 of file DatagramImpl.hxx.
|
inlineprivate |
Definition at line 173 of file DatagramImpl.hxx.
|
inlineprivate |
Equivalent to enqueuing a new datagram to send.
| b | datagram to send. |
| priority | executor priority. |
Definition at line 93 of file DatagramImpl.hxx.
|
inlineprivate |
Sets the stateflow priority.
| p | the stateflow's priority on the executor. |
Definition at line 386 of file DatagramImpl.hxx.
|
inlineprivate |
Entry point to the flow processing.
Definition at line 101 of file DatagramImpl.hxx.
|
inlineprivate |
To be called from the handler.
Wakes up main flow and terminates it (with whatever is in the result_ code right now).
@TODO(balazs.racz) Here we might want to decide whether to start a retry.
Definition at line 360 of file DatagramImpl.hxx.
|
inlineprivate |
Definition at line 187 of file DatagramImpl.hxx.
|
inlineprivate |
Definition at line 194 of file DatagramImpl.hxx.
|
inlineprivate |
Definition at line 206 of file DatagramImpl.hxx.
|
inlinevirtual |
Triggers sending a datagram.
| b | is the datagra buffer. |
| priority | is the priority of the datagram client in the executor. |
Callers should set the done closure of the Buffer. After that closure is notified, the caller must ensure that the datagram client is released back to the freelist.
@TODO(balazs.racz): revisit the type of DatagramPayload and ensure that there will be no extra copy of the data happening.
Implements openlcb::DatagramClient.
Definition at line 70 of file DatagramImpl.hxx.
|
private |
This notifiable is saved from the datagram buffer.
Will be notified when the entire interaction is completed, but the buffer itself is transferred to the send flow.
Definition at line 402 of file DatagramImpl.hxx.
|
private |
Destination of the datagram we are currently sending.
Definition at line 406 of file DatagramImpl.hxx.
|
private |
Definition at line 420 of file DatagramImpl.hxx.
|
private |
1 when we are in the sleep call waiting for the datagram Ack or Reject message.
Definition at line 419 of file DatagramImpl.hxx.
|
private |
Instance of the listener object.
Definition at line 410 of file DatagramImpl.hxx.
|
staticconstexprprivate |
Constant used to clamp the incoming priority value to something that first in priority_ bit field.
Definition at line 428 of file DatagramImpl.hxx.
|
private |
Datagram message we are trying to send now. We own it.
Definition at line 398 of file DatagramImpl.hxx.
|
private |
Priority in the executor.
Definition at line 425 of file DatagramImpl.hxx.
|
private |
Addressed datagram send flow from the interface. Externally owned.
Definition at line 408 of file DatagramImpl.hxx.
|
private |
1 when we have the handlers registered.
During this time we have exclusive lock on the specific src/dst node pair.
Definition at line 423 of file DatagramImpl.hxx.
|
private |
Source of the datagram we are currently sending.
Definition at line 404 of file DatagramImpl.hxx.
|
private |
Helper object for sleep.
Definition at line 412 of file DatagramImpl.hxx.
|
private |
List of other datagram clients that are trying to send to the same target node.
We need to wake up one of this list when we are done sending.
Definition at line 416 of file DatagramImpl.hxx.