Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Datagram.cxx
Go to the documentation of this file.
1
35#include "openlcb/Datagram.hxx"
36
37namespace openlcb
38{
39
43
45 size_t num_registry_entries)
46 : Service(iface->executor()), iface_(iface), dispatcher_(iface_, num_registry_entries)
47{
49 );
50}
51
52DatagramService::~DatagramService()
53{
55 );
56}
57
59{
60 if (!nmsg()->dstNode)
61 {
62 return release_and_exit();
63 }
64 return allocate_and_call<IncomingDatagram>(nullptr, STATE(incoming_datagram_allocated), g_incoming_datagram_allocator);
65}
66
69{
71 get_allocation_result<IncomingDatagram>(nullptr);
72 IncomingDatagram* d = b->data();
73 d->src = nmsg()->src;
74 d->dst = nmsg()->dstNode;
75
76 // Takes over ownership of payload.
78 d->payload.swap(nmsg()->payload);
79
80 release();
81
82 // Saves the datagram buffer pointer.
83 d_ = b;
84
85 unsigned datagram_id = -1;
86 if (d->payload.empty())
87 {
89 "Invalid arguments: incoming datagram from node %012" PRIx64
90 " alias %x has no payload.",
91 d->src.id, d->src.alias);
92 resultCode_ = DatagramClient::PERMANENT_ERROR;
93 return allocate_and_call(iface()->addressed_message_write_flow(),
94 STATE(respond_rejection));
95 }
96 datagram_id = *reinterpret_cast<const uint8_t*>(d->payload.data());
97
98 // Looks up the datagram handler.
99 DatagramHandler* h = registry_.lookup(d->dst, datagram_id);
100
101 if (!h)
102 {
103 LOG(VERBOSE, "No datagram handler found for node %p id %x", d->dst,
104 datagram_id);
105 resultCode_ = DatagramClient::PERMANENT_ERROR;
106 return allocate_and_call(iface()->addressed_message_write_flow(),
107 STATE(respond_rejection));
108 }
109
110 h->send(d_);
111 d_ = nullptr;
112 return exit();
113}
114
116DatagramService::DatagramDispatcher::respond_rejection()
117{
118 auto* f = get_allocation_result(iface()->addressed_message_write_flow());
119
120 f->data()->reset(Defs::MTI_DATAGRAM_REJECTED, d_->data()->dst->node_id(),
121 d_->data()->src, error_to_buffer(resultCode_));
122
123 iface()->addressed_message_write_flow()->send(f);
124
125 d_->unref();
126 d_ = nullptr;
127 return exit();
128}
129
130} // namespace openlcb
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Definition StateFlow.hxx:61
Base class for all QMember types that hold data in an expandable format.
Definition Buffer.hxx:195
T * data()
get a pointer to the start of the data.
Definition Buffer.hxx:215
void register_handler(HandlerType *handler, ID id, ID mask)
Adds a new handler to this dispatcher.
void unregister_handler(HandlerType *handler, ID id, ID mask)
Removes a specific instance of a handler from this dispatcher.
Abstract class for message recipients.
virtual void send(MessageType *message, unsigned priority=UINT_MAX)=0
Entry point to the flow.
Collection of related state machines that pend on incoming messages.
Return type for a state flow callback.
Action entry() override
Entry into the StateFlow activity.
Definition Datagram.cxx:58
DatagramService(If *iface, size_t num_registry_entries)
Creates a datagram dispatcher.
Definition Datagram.cxx:44
If * iface_
Interface on which we are registered.
Definition Datagram.hxx:240
DatagramDispatcher dispatcher_
Datagram dispatch handler.
Definition Datagram.hxx:246
Abstract class representing an OpenLCB Interface.
Definition If.hxx:185
MessageDispatchFlow * dispatcher()
Definition If.hxx:224
MessageHandler * addressed_message_write_flow()
Definition If.hxx:210
GenMessage * nmsg()
Returns the NMRAnet message we received.
Definition If.hxx:413
#define LOG(level, message...)
Conditionally write a message to the logging output.
Definition logging.h:99
static const int VERBOSE
Loglevel that is usually not printed, reporting debugging information.
Definition logging.h:59
static const int WARNING
Loglevel that is always printed, reporting a warning or a retryable error.
Definition logging.h:55
long long DATAGRAM_RESPONSE_TIMEOUT_NSEC
Defines how long the datagram client flow should wait for the datagram ack/nack response message.
Definition Datagram.cxx:42
Pool *const g_incoming_datagram_allocator
Allocator to be used for Buffer<IncomingDatagram> objects.
string error_to_buffer(uint16_t error_code, uint16_t mti)
Formats a payload for response of error response messages such as OPtioanl Interaction Rejected or Te...
Definition If.cxx:90
#define SEC_TO_NSEC(_sec)
Convert a second value to a nanosecond value.
Definition os.h:286
@ MTI_DATAGRAM_REJECTED
datagram rejected by receiver
@ MTI_DATAGRAM
datagram
Message structure for incoming datagram handlers.
Definition Datagram.hxx:55
DatagramPayload payload
Owned by the current IncomingDatagram object.
Definition Datagram.hxx:62
Node * dst
Virtual node that the datagram was addressed to.
Definition Datagram.hxx:59
NodeHandle src
Originator of the incoming datagram.
Definition Datagram.hxx:57
NodeID id
48-bit NMRAnet Node ID
NodeAlias alias
alias to NMRAnet Node ID