48 TrainService* traction_service)
49 __attribute__((weak));
54 if (system == TractionDefs::PROXYTYPE_MARKLIN_DIGITAL)
58 else if (system == TractionDefs::PROXYTYPE_DCC)
61 if (addr_hi == 0 && addr_lo < 128)
68 (
static_cast<uint16_t
>(addr_hi) << 8) | addr_lo));
71 if (!impl)
return nullptr;
83 : trainService_(train_service)
84 , proxyNode_(proxy_node)
85 , proxyEventProducer_(proxyNode_)
97 return traction_service()->iface();
116 this, Defs::MTI_TRACTION_PROXY_COMMAND, 0xffff);
122 this, Defs::MTI_TRACTION_PROXY_COMMAND, 0xffff);
128 if (!
nmsg()->dstNode)
130 LOG(
VERBOSE,
"Traction proxy message for unknown node.");
131 return release_and_exit();
133 if (
nmsg()->dstNode != impl_->node())
136 return release_and_exit();
140 return call_immediately(
STATE(handle_cmd));
144 return allocate_and_call(
154 response_ = get_allocation_result(
160 LOG(
VERBOSE,
"Traction proxy message with no command byte.");
166 case TractionDefs::PROXYREQ_MANAGE:
168 return call_immediately(
STATE(handle_manage));
170 case TractionDefs::PROXYREQ_ALLOCATE:
172 return call_immediately(
STATE(handle_allocate));
176 LOG(
VERBOSE,
"Unknown traction proxy command %x.", cmd);
191 case TractionDefs::PROXYREQ_MANAGE_RESERVE:
204 p.push_back(TractionDefs::PROXYRESP_MANAGE);
205 p.push_back(TractionDefs::PROXYRESP_MANAGE_RESERVE_REPLY);
207 response_->data()->reset(Defs::MTI_TRACTION_PROXY_REPLY,
208 nmsg()->dstNode->node_id(),
213 return release_and_exit();
215 case TractionDefs::PROXYREQ_MANAGE_RELEASE:
218 return release_and_exit();
221 LOG(
VERBOSE,
"Unknown Traction proxy manage subcommand %x",
231 LOG(
VERBOSE,
"proxy allocate with too short message or not DCC "
232 "legacy technology ID.");
236 uint8_t addr_hi =
payload()[2];
237 uint8_t addr_lo =
payload()[3];
243 LOG(
VERBOSE,
"proxy allocate could not create impl.");
247 b.push_back(TractionDefs::PROXYRESP_ALLOCATE);
250 b.push_back(addr_hi);
251 b.push_back(addr_lo);
252 auto node_id = train_node->node_id();
253 for (
int i = 56; i >= 0; i -= 8)
255 b.push_back((node_id >> i) & 0xff);
257 response_->data()->reset(Defs::MTI_TRACTION_PROXY_REPLY,
258 nmsg()->dstNode->node_id(),
nmsg()->src,
262 return release_and_exit();
274 return reinterpret_cast<const uint8_t *
>(
nmsg()->
payload.data());
281 response_->data()->reset(
283 nmsg()->dstNode->node_id(),
nmsg()->src,
287 return release_and_exit();
293 unsigned reserved_ : 1;
299 ProxyRequestFlow handlerFlow_;
302TractionProxyService::TractionProxyService(
TrainService *train_service,
304 :
Service(train_service->iface()->executor())
306 impl_ =
new Impl(train_service, proxy_node);
309TractionProxyService::~TractionProxyService()
#define STATE(_fn)
Turns a function name into an argument to be supplied to functions expecting a state.
Base class for all QMember types that hold data in an expandable format.
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.
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.
Base::Action Action
Allows using Action without having StateFlowBase:: prefix in front of it.
TrainImpl class for a DCC locomotive.
TrainImpl structure for Marklin-Motorola v2 protocol locomotives.
Class that advertises an event ID to be produced.
Abstract class representing an OpenLCB Interface.
MessageDispatchFlow * dispatcher()
MessageHandler * addressed_message_write_flow()
Base class for incoming message handler flows.
GenMessage * nmsg()
Returns the NMRAnet message we received.
Base class for NMRAnet nodes conforming to the asynchronous interface.
State flow handling incoming OpenLCB messages of MTI == Traction proxy Request.
Action reject_permanent()
Rejects the incoming message with a permanent error.
const uint8_t * payload()
Returns the incoming message payload (bytes).
Action entry() OVERRIDE
Entry into the StateFlow activity.
size_t size()
Returns the size of the incoming message payload.
Abstract base class for train implementations.
Train node class with a an OpenLCB Node ID from the DCC pool. Used for command stations.
Virtual node class for an OpenLCB train protocol node.
Collection of control flows necessary for implementing the Traction Protocol.
#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.
#define OVERRIDE
Function attribute for virtual functions declaring that this funciton is overriding a funciton that s...
string Payload
Container that carries the data bytes in an NMRAnet message.
Node * allocate_train_node(uint8_t system, uint8_t addr_hi, uint8_t addr_lo, TrainService *traction_service)
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...
Strongly typed wrapper representing a long DCC address.
Strongly typed wrapper representing a short DCC address.
Strongly typed wrapper representing a marklin-motorola protocol address.
@ MTI_OPTIONAL_INTERACTION_REJECTED
rejected request
string payload
Data content in the message body.
PImpl Implementation structure for the Traction Proxy service.