38#include "openlcb/DatagramImpl.hxx"
68 auto *b = get_allocation_result(if_can()->frame_write_flow());
69 struct can_frame *f = b->data()->mutable_frame();
73 uint32_t can_id = 0x1A000000;
78 bool need_more_frames =
false;
84 need_more_frames =
true;
115 SET_CAN_FRAME_ID_EFF(*f, can_id);
118 if (need_more_frames)
120 return call_immediately(
STATE(get_can_frame_buffer));
151 const struct can_frame *f = &
message()->data()->frame();
153 uint32_t
id = GET_CAN_FRAME_ID_EFF(*f);
157 if (can_frame_type < 2 || can_frame_type > 5)
160 return release_and_exit();
177 return release_and_exit();
181 bool last_frame =
true;
183 switch (can_frame_type)
202 DatagramClient::OUT_OF_ORDER;
239 return release_and_exit();
245 DatagramClient::RESEND_OK | DatagramClient::OUT_OF_ORDER;
250 LOG(
WARNING,
"AsyncDatagramCan: too long incoming datagram arrived."
252 (
int)(buf->size() + f->can_dlc));
264 return allocate_and_call(if_can()->addressed_message_write_flow(),
269 buf->append(
reinterpret_cast<const char *
>(&f->data[0]), f->can_dlc);
275 return allocate_and_call(if_can()->dispatcher(),
291 get_allocation_result(if_can()->addressed_message_write_flow());
304 auto *f = get_allocation_result(if_can()->dispatcher());
332 unsigned short srcAlias_ : 12;
344CanDatagramService::CanDatagramService(
IfCan *iface,
345 int num_registry_entries,
352 for (
int i = 0; i < num_clients; ++i)
356 client_allocator()->insert(
static_cast<DatagramClient *
>(client_flow));
365CanDatagramService::~CanDatagramService()
369CanDatagramParser::CanDatagramParser(IfCan *iface)
370 : CanFrameStateFlow(iface)
372 if_can()->frame_dispatcher()->register_handler(
this,
378 if_can()->frame_dispatcher()->register_handler(
this,
386CanDatagramParser::~CanDatagramParser()
388 if_can()->frame_dispatcher()->unregister_handler_all(
this);
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
OutgoingFrameHandler * frame_write_flow()
An object that can be scheduled on an executor to run.
virtual void send(MessageType *message, unsigned priority=UINT_MAX)=0
Entry point to the flow.
Though at the surface, this may seem like an unnecessary abstraction of std::map, it has the purpose ...
Iterator end()
Get an iterator index pointing one past the last element in mapping.
void clear()
Removes all elements in the map.
size_t erase(Key key)
Remove an element from the tree.
Iterator find(const Key &key)
Find an element matching the given key.
void release() OVERRIDE
Unrefs the current buffer.
Base::Action Action
Allows using Action without having StateFlowBase:: prefix in front of it.
void send(MessageType *msg, unsigned priority=UINT_MAX) OVERRIDE
Sends a message to the state flow for processing.
The addressed write flow is responsible for sending addressed messages to the CANbus.
NodeAlias lookup(NodeID id)
Lookup a node's alias based on its Node ID.
Frame handler that assembles incoming datagram fragments into a single datagram message.
Action datagram_complete()
Requests the datagram in buf_, dstNode_ etc... to be sent to the AsyncIf for processing.
uint16_t errorCode_
If non-zero, contains a Rejection error code and the datagram should not be forwarded to the upper la...
StlMap< uint64_t, DatagramPayload > pendingBuffers_
Open datagram buffers.
Action entry() override
Handler callback for incoming frames.
DatagramPayload localBuffer_
A local buffer that owns the datagram payload bytes after we took the entry from the pending buffers ...
Action send_rejection()
Sends a datagram rejection.
Datagram client implementation for CANbus-based datagram protocol.
Base class for incoming CAN frame handlers.
uint8_t dataOffset_
for continuation frames: which offset in the Buffer should we start the payload at.
NodeAlias dstAlias_
Destination node alias.
NodeAlias srcAlias_
Source node alias.
Datagram client implementation for CANbus-based datagram protocol.
Use this class to send datagrams.
Transport-agnostic dispatcher of datagrams.
Implementation of the OpenLCB interface abstraction for the CAN-bus interface standard.
AliasCache * local_aliases()
AliasCache * remote_aliases()
void add_owned_flow(Executable *e) override
Transfers ownership of a module to the interface.
MessageDispatchFlow * dispatcher()
Node * lookup_local_node(NodeID id)
Looks up a node ID in the local nodes' registry.
MessageHandler * addressed_message_write_flow()
Base class for NMRAnet nodes conforming to the asynchronous interface.
virtual Action send_finished()
Virtual method called after the send is completed, i.e., all the frames are generated and sent to the...
GenMessage * nmsg()
Implementations shall call this function when they are done with sending the packet.
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int VERBOSE
Loglevel that is usually not printed, reporting debugging information.
static const int WARNING
Loglevel that is always printed, reporting a warning or a retryable error.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
long long DATAGRAM_RESPONSE_TIMEOUT_NSEC
Defines how long the datagram client flow should wait for the datagram ack/nack response message.
Executable * TEST_CreateCanDatagramParser(IfCan *if_can)
Creates a CAN datagram parser flow. Exposed for testing only.
uint16_t NodeAlias
Alias to a 48-bit NMRAnet Node ID type.
Payload DatagramPayload
Contents of a Datagram message.
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...
static const uint32_t CAN_EXT_FRAME_MASK
Mask to OR onto a can mask to tell the dispatcher to only consider extended can frames.
static const uint32_t CAN_EXT_FRAME_FILTER
Filter to OR onto a can ID to tell the dispatcher to only consider extended can frames.
@ NMRANET_MSG
normal NMRAnet message
static void set_dst(uint32_t *can_id, NodeAlias dst)
Set the destination field value of the CAN ID.
static void set_src(uint32_t *can_id, NodeAlias src)
Set the source field value of the CAN ID.
static void set_can_frame_type(uint32_t *can_id, CanFrameType type)
Set the CAN frame type field value of the CAN ID.
@ DATAGRAM_MIDDLE_FRAME
middle frame of multi-frame datagram
@ DATAGRAM_FINAL_FRAME
last frame of multi-frame datagram
@ DATAGRAM_FIRST_FRAME
first frame of multi-frame datagram
@ DATAGRAM_ONE_FRAME
a single frame datagram
@ NORMAL_PRIORITY
normal priority CAN message
@ FRAME_TYPE_MASK
mask for frame type field of CAN ID
@ SRC_MASK
mask for source field of CAN ID
@ FRAME_TYPE_SHIFT
shift for frame type field of CAN ID
@ CAN_FRAME_TYPE_SHIFT
shift for can frame type field of CAN ID
@ CAN_FRAME_TYPE_MASK
mask for can frame type field of CAN ID
@ PRIORITY_SHIFT
shift for priority field of CAN ID
@ DST_MASK
mask for MTI field of CAN ID
@ PRIORITY_MASK
mask for priority field of CAN ID
@ DST_SHIFT
shift for MTI field of CAN ID
@ SRC_SHIFT
shift for source field of CAN ID
@ MAX_SIZE
maximum size in bytes of a datagram
@ MTI_DATAGRAM_REJECTED
datagram rejected by receiver
This class is used in the dispatching of incoming or outgoing NMRAnet messages to the message handler...
NodeHandle dst
Destination node.
Node * dstNode
If the destination node is local, this value is non-NULL.
NodeHandle src
Source node.
Defs::MTI mti
OpenLCB MTI of the incoming message.
string payload
Data content in the message body.
Container of both a NodeID and NodeAlias.
NodeID id
48-bit NMRAnet Node ID
NodeAlias alias
alias to NMRAnet Node ID