21 #ifndef PLUGINS_ARTNET_ARTNETNODE_H_
22 #define PLUGINS_ARTNET_ARTNETNODE_H_
33 #include "ola/Clock.h"
35 #include "ola/network/IPV4Address.h"
36 #include "ola/network/Interface.h"
37 #include "ola/io/SelectServerInterface.h"
38 #include "ola/network/Socket.h"
43 #include "ola/timecode/TimeCode.h"
44 #include "plugins/artnet/ArtNetPackets.h"
77 static const uint8_t ARTNET_DISABLE_PORT = 0xf0;
82 : always_broadcast(
false),
83 use_limited_broadcast_address(
false),
85 broadcast_threshold(30),
89 bool always_broadcast;
90 bool use_limited_broadcast_address;
91 unsigned int rdm_queue_size;
92 unsigned int broadcast_threshold;
93 uint8_t input_port_count;
124 bool SetShortName(
const string &name);
125 string ShortName()
const {
return m_short_name; }
126 bool SetLongName(
const string &name);
127 string LongName()
const {
return m_long_name; }
129 uint8_t NetAddress()
const {
return m_net_address; }
130 bool SetNetAddress(uint8_t net_address);
132 bool SetSubnetAddress(uint8_t subnet_address);
133 uint8_t SubnetAddress()
const {
134 return m_output_ports[0].universe_address >> 4;
137 uint8_t InputPortCount()
const;
140 void DisableInputPort(uint8_t port_id);
141 bool InputPortState(uint8_t port_id)
const;
143 bool SetOutputPortUniverse(uint8_t port_id, uint8_t universe_id);
144 uint8_t GetOutputPortUniverse(uint8_t port_id);
145 void DisableOutputPort(uint8_t port_id);
146 bool OutputPortState(uint8_t port_id)
const;
148 void SetBroadcastThreshold(
unsigned int threshold) {
149 m_broadcast_threshold = threshold;
152 bool SetMergeMode(uint8_t port_id, artnet_merge_mode merge_mode);
159 void RunFullDiscovery(uint8_t port_id,
161 void RunIncrementalDiscovery(uint8_t port_id,
163 void SendRDMRequest(uint8_t port_id,
166 bool SetUnsolicitedUIDSetHandler(
170 std::vector<IPV4Address> *node_addresses);
173 bool SetDMXHandler(uint8_t port_id,
176 bool SendTod(uint8_t port_id,
const UIDSet &uid_set);
177 bool SetOutputPortRDMHandlers(
188 typedef vector<InputPort*> InputPorts;
192 typedef map<UID, std::pair<IPV4Address, uint8_t> > uid_map;
194 enum { MAX_MERGE_SOURCES = 2 };
204 uint8_t universe_address;
205 uint8_t sequence_number;
207 artnet_merge_mode merge_mode;
209 DMXSource sources[MAX_MERGE_SOURCES];
211 map<UID, IPV4Address> uid_map;
219 uint8_t m_net_address;
220 bool m_send_reply_on_change;
223 unsigned int m_broadcast_threshold;
224 unsigned int m_unsolicited_replies;
226 bool m_always_broadcast;
227 bool m_use_limited_broadcast_address;
230 bool m_in_configuration_mode;
231 bool m_artpoll_required;
232 bool m_artpollreply_required;
234 InputPorts m_input_ports;
235 OutputPort m_output_ports[ARTNET_MAX_PORTS];
237 std::auto_ptr<ola::network::UDPSocketInterface> m_socket;
243 bool SendPollIfAllowed();
244 bool SendPollReplyIfRequired();
245 bool SendPollReply(
const IPV4Address &destination);
247 void HandlePacket(
const IPV4Address &source_address,
249 unsigned int packet_size);
250 void HandlePollPacket(
const IPV4Address &source_address,
252 unsigned int packet_size);
253 void HandleReplyPacket(
const IPV4Address &source_address,
255 unsigned int packet_size);
256 void HandleDataPacket(
const IPV4Address &source_address,
258 unsigned int packet_size);
259 void HandleTodRequest(
const IPV4Address &source_address,
261 unsigned int packet_size);
262 void HandleTodData(
const IPV4Address &source_address,
264 unsigned int packet_size);
265 void HandleTodControl(
const IPV4Address &source_address,
267 unsigned int packet_size);
270 unsigned int packet_size);
273 uint8_t universe_address,
274 ola::rdm::rdm_response_code code,
276 const std::vector<std::string> &packets);
278 const string &rdm_data,
280 void HandleIPProgram(
const IPV4Address &source_address,
282 unsigned int packet_size);
283 void PopulatePacketHeader(
artnet_packet *packet, uint16_t op_code);
288 bool SendRDMCommand(
const RDMCommand &command,
291 void UpdatePortFromSource(OutputPort *port,
const DMXSource &source);
292 bool CheckPacketVersion(
const IPV4Address &source_address,
293 const string &packet_type,
295 bool CheckPacketSize(
const IPV4Address &source_address,
296 const string &packet_type,
297 unsigned int actual_size,
298 unsigned int expected_size);
301 InputPort *GetInputPort(uint8_t port_id,
bool warn =
true);
302 const InputPort *GetInputPort(uint8_t port_id)
const;
303 InputPort *GetEnabledInputPort(uint8_t port_id,
const string &action);
305 OutputPort *GetOutputPort(uint8_t port_id);
306 const OutputPort *GetOutputPort(uint8_t port_id)
const;
307 OutputPort *GetEnabledOutputPort(uint8_t port_id,
const string &action);
309 void UpdatePortFromTodPacket(
InputPort *port,
312 unsigned int packet_size);
314 void ReleaseDiscoveryLock(
InputPort *port);
319 static const char ARTNET_ID[];
320 static const uint16_t ARTNET_PORT = 6454;
321 static const uint16_t OEM_CODE = 0x0431;
322 static const uint16_t ARTNET_VERSION = 14;
325 static const uint8_t NODE_CODE = 0x00;
326 static const uint16_t MAX_UIDS_PER_UNIVERSE = 0xffff;
327 static const uint8_t RDM_VERSION = 0x01;
328 static const uint8_t TOD_FLUSH_COMMAND = 0x01;
329 static const unsigned int MERGE_TIMEOUT = 10;
331 static const unsigned int NODE_TIMEOUT = 31;
333 static const unsigned int RDM_TOD_TIMEOUT_MS = 4000;
335 static const unsigned int RDM_MISSED_TODDATA_LIMIT = 3;
338 static const unsigned int RDM_REQUEST_QUEUE_LIMIT = 100;
340 static const unsigned int RDM_REQUEST_TIMEOUT_MS = 2000;
359 m_impl->SendRDMRequest(m_port_id, request, on_complete);
363 m_impl->RunFullDiscovery(m_port_id, callback);
367 m_impl->RunIncrementalDiscovery(m_port_id, callback);
371 ArtNetNodeImpl *m_impl;
387 bool Start() {
return m_impl.Start(); }
388 bool Stop() {
return m_impl.Stop(); }
390 bool EnterConfigurationMode() {
393 bool ExitConfigurationMode() {
398 bool SetShortName(
const string &name) {
return m_impl.SetShortName(name); }
399 string ShortName()
const {
return m_impl.ShortName(); }
400 bool SetLongName(
const string &name) {
return m_impl.SetLongName(name); }
401 string LongName()
const {
return m_impl.LongName(); }
403 uint8_t NetAddress()
const {
return m_impl.NetAddress(); }
404 bool SetNetAddress(uint8_t net_address) {
405 return m_impl.SetNetAddress(net_address);
407 bool SetSubnetAddress(uint8_t subnet_address) {
408 return m_impl.SetSubnetAddress(subnet_address);
410 uint8_t SubnetAddress()
const {
411 return m_impl.SubnetAddress();
414 uint8_t InputPortCount()
const {
415 return m_impl.InputPortCount();
418 bool SetInputPortUniverse(uint8_t port_id, uint8_t universe_id) {
421 uint8_t GetInputPortUniverse(uint8_t port_id)
const {
424 void DisableInputPort(uint8_t port_id) {
425 m_impl.DisableInputPort(port_id);
427 bool InputPortState(uint8_t port_id)
const {
428 return m_impl.InputPortState(port_id);
431 bool SetOutputPortUniverse(uint8_t port_id, uint8_t universe_id) {
432 return m_impl.SetOutputPortUniverse(port_id, universe_id);
434 uint8_t GetOutputPortUniverse(uint8_t port_id) {
435 return m_impl.GetOutputPortUniverse(port_id);
437 void DisableOutputPort(uint8_t port_id) {
438 m_impl.DisableOutputPort(port_id);
440 bool OutputPortState(uint8_t port_id)
const {
441 return m_impl.OutputPortState(port_id);
444 void SetBroadcastThreshold(
unsigned int threshold) {
445 m_impl.SetBroadcastThreshold(threshold);
448 bool SetMergeMode(uint8_t port_id, artnet_merge_mode merge_mode) {
449 return m_impl.SetMergeMode(port_id, merge_mode);
454 return m_impl.SendPoll();
459 return m_impl.SendDMX(port_id, buffer);
473 bool SetUnsolicitedUIDSetHandler(
476 return m_impl.SetUnsolicitedUIDSetHandler(port_id, on_tod);
478 void GetSubscribedNodes(uint8_t port_id,
479 std::vector<IPV4Address> *node_addresses) {
484 bool SetDMXHandler(uint8_t port_id,
487 return m_impl.SetDMXHandler(port_id, buffer, handler);
489 bool SendTod(uint8_t port_id,
const UIDSet &uid_set) {
490 return m_impl.SendTod(port_id, uid_set);
492 bool SetOutputPortRDMHandlers(
497 return m_impl.SetOutputPortRDMHandlers(port_id,
510 vector<ArtNetNodeImplRDMWrapper*> m_wrappers;
511 vector<ola::rdm::DiscoverableQueueingRDMController*> m_controllers;
513 bool CheckInputPortId(uint8_t port_id);
518 #endif // PLUGINS_ARTNET_ARTNETNODE_H_