the Art-Net packet definitions
This commit is contained in:
parent
7826d17d40
commit
5710631724
|
@ -1,4 +1,6 @@
|
|||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
|
||||
artnet/artnet.h
|
||||
artnet/packet.h
|
||||
artnet/packet.cpp
|
||||
)
|
||||
|
|
|
@ -0,0 +1,556 @@
|
|||
/*
|
||||
artnet.h
|
||||
|
||||
Copyright (c) 2022 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* @brief \cite ARTNET Art-Net is an Ethernet protocol based on the TCP/IP protocol
|
||||
* suite.
|
||||
*
|
||||
* Its purpose is to allow transfer of large amounts of DMX512 data
|
||||
* over a wide area using standard networking technology.
|
||||
*/
|
||||
namespace ARTNET {
|
||||
|
||||
/// @brief \cite ARTNET Universe Addressing
|
||||
///
|
||||
/// > The Port-Address of each DMX512 Universe is encoded as a 15-bit number
|
||||
struct PortAddress {
|
||||
/**
|
||||
* @brief PortAddress
|
||||
* @param v
|
||||
*/
|
||||
PortAddress(uint16_t v = 0) : value(v) {};
|
||||
/**
|
||||
* @brief PortAddress
|
||||
* @param n
|
||||
* @param s
|
||||
*/
|
||||
PortAddress(uint8_t n, uint8_t s) : subuni(s), net(n) {}
|
||||
|
||||
union {
|
||||
uint16_t value;
|
||||
struct {
|
||||
union {
|
||||
uint8_t subuni;
|
||||
struct {
|
||||
uint8_t universe : 4; //!< A single DMX512 frame of 512 channels is referred to as a Universe.
|
||||
uint8_t subnet : 4; //!< A group of 16 consecutive universes is referred to as a sub-net.
|
||||
};
|
||||
};
|
||||
union{
|
||||
uint8_t _net;
|
||||
struct {
|
||||
uint8_t net : 7; //!< A group of 16 consecutive Sub-Nets or 256 consecutive Universes is referred to as a net. There are 128 Nets in total.
|
||||
bool reserved : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/// @brief \cite ARTNET Protocol Operation
|
||||
///
|
||||
/// > The UDP port used as both source and destination is 0x1936.
|
||||
static const uint16_t UDP_PORT = 6454;
|
||||
|
||||
/// @brief Packet ID
|
||||
///
|
||||
/// > Array of 8 characters, the final character is a null termination.
|
||||
/// > Value = ‘A’ ‘r’ ‘t’ ‘-‘ ‘N’ ‘e’ ‘t’ 0x00
|
||||
static const uint8_t PACKET_IDENTIFIER[] = { 0x41, 0x72, 0x74, 0x2D,
|
||||
0x4E, 0x65, 0x74, 0x00};
|
||||
|
||||
/// @brief \cite ARTNET Art-Net protocol revision number.
|
||||
///
|
||||
/// Current value 14. Controllers should ignore communication with nodes
|
||||
/// using a protocol version lower than 14.
|
||||
static const uint16_t VERSION = 14;
|
||||
|
||||
/// @brief \cite ARTNET Table 1 - OpCodes
|
||||
///
|
||||
/// The OpCode defines the class of data following within the UDP packet.
|
||||
/// The following table details the legal OpCode values used in Art-Net packets
|
||||
enum OpCode : uint16_t {
|
||||
OpNull = 0x0000, //!< no-op. Ignore this packet.
|
||||
OpPoll = 0x2000, //!< an ArtPoll packet, no other data is contained in this UDP packet.
|
||||
OpPollReply = 0x2100, //!< an ArtPollReply Packet. It contains device status information.
|
||||
OpDiagData = 0x2300, //!< Diagnostics and data logging packet.
|
||||
OpCommand = 0x2400, //!< Used to send text based parameter commands.
|
||||
// OpOutput = 0x5000, //!< an ArtDmx data packet. It contains zero start code DMX512 information for a single Universe.
|
||||
OpDmx = 0x5000, //!< an ArtDmx data packet. It contains zero start code DMX512 information for a single Universe.
|
||||
OpNzs = 0x5100, //!< an ArtNzs data packet. It contains non-zero start code (except RDM) DMX512 information for a single Universe.
|
||||
OpSync = 0x5200, //!< an ArtSync data packet. It is used to force synchronous transfer of ArtDmx packets to a node’s output.
|
||||
OpAddress = 0x6000, //!< an ArtAddress packet. It contains remote programming information for a Node.
|
||||
OpInput = 0x7000, //!< an ArtInput packet. It contains enable – disable data for DMX inputs.
|
||||
OpTodRequest = 0x8000, //!< an ArtTodRequest packet. It is used to request a Table of Devices (ToD) for RDM discovery.
|
||||
OpTodData = 0x8100, //!< an ArtTodData packet. It is used to send a Table of Devices (ToD) for RDM discovery.
|
||||
OpTodControl = 0x8200, //!< an ArtTodControl packet. It is used to send RDM discovery control messages.
|
||||
OpRdm = 0x8300, //!< an ArtRdm packet. It is used to send all non discovery RDM messages.
|
||||
OpRdmSub = 0x8400, //!< an ArtRdmSub packet. It is used to send compressed, RDM Sub-Device data.
|
||||
OpVideoSetup = 0xA010, //!< an ArtVideoSetup packet. It contains video screen setup information for nodes that implement the extended video features.
|
||||
OpVideoPalette = 0xA020, //!< an ArtVideoPalette packet. It contains colour palette setup information for nodes that implement the extended video features.
|
||||
OpVideoData = 0xA040, //!< an ArtVideoData packet. It contains display data for nodes that implement the extended video features.
|
||||
OpMacMaster = 0xF000, //!< depreciated
|
||||
OpMacSlave = 0xF100, //!< depreciated
|
||||
OpFirmwareMaster = 0xF200, //!< an ArtFirmwareMaster packet. It is used to upload new firmware or firmware extensions to the Node.
|
||||
OpFirmwareReply = 0xF300, //!< an ArtFirmwareReply packet. It is returned by the node to acknowledge receipt of an ArtFirmwareMaster packet or ArtFileTnMaster packet.
|
||||
OpFileTnMaster = 0xF400, //!< Uploads user file to node.
|
||||
OpFileFnMaster = 0xF500, //!< Downloads user file from node.
|
||||
OpFileFnReply = 0xF600, //!< Server to Node acknowledge for download packets.
|
||||
OpIpProg = 0xF800, //!< an ArtIpProg packet. It is used to re- programme the IP, Mask and Port address of the Node.
|
||||
OpIpProgReply = 0xF900, //!< an ArtIpProgReply packet. It is returned by the node to acknowledge receipt of an ArtIpProg packet.
|
||||
OpMedia = 0x9000, //!< an ArtMedia packet. It is Unicast by a Media Server and acted upon by a Controller.
|
||||
OpMediaPatch = 0x9100, //!< an ArtMediaPatch packet. It is Unicast by a Controller and acted upon by a Media Server.
|
||||
OpMediaControl = 0x9200, //!< an ArtMediaControl packet. It is Unicast by a Controller and acted upon by a Media Server.
|
||||
OpMediaContrlReply = 0x9300, //!< an ArtMediaControlReply packet. It is Unicast by a Media Server and acted upon by a Controller.
|
||||
OpTimeCode = 0x9700, //!< an ArtTimeCode packet. It is used to transport time code over the network.
|
||||
OpTimeSync = 0x9800, //!< Used to synchronise real time date and clock
|
||||
OpTrigger = 0x9900, //!< Used to send trigger macros
|
||||
OpDirectory = 0x9A00, //!< Requests a node's file list
|
||||
OpDirectoryReply = 0x9B00 //!< Replies to OpDirectory with file list
|
||||
};
|
||||
|
||||
/// OEM is unknown or non-registered type
|
||||
static const uint16_t oem_unknown = 0x00ff;
|
||||
/// Used by ArtTrigger for general purpose codes
|
||||
static const uint16_t oem_gobal = 0xffff;
|
||||
|
||||
/// @brief \cite ARTNET Table 3 - NodeReport Codes
|
||||
enum NodeReport : uint16_t {
|
||||
RcDebug = 0x0000, //!< Booted in debug mode (Only used in development)
|
||||
RcPowerOk = 0x0001, //!< Power On Tests successful
|
||||
RcPowerFail = 0x0002, //!< Hardware tests failed at Power On
|
||||
RcSocketWr1 = 0x0003, //!< Last UDP from Node failed due to truncated length, Most likely caused by a collision.
|
||||
RcParseFail = 0x0004, //!< Unable to identify last UDP transmission. Check OpCode and packet length.
|
||||
RcUdpFail = 0x0005, //!< Unable to open Udp Socket in last transmission attempt
|
||||
RcShNameOk = 0x0006, //!< Confirms that Short Name programming via ArtAddress, was successful.
|
||||
RcLoNameOk = 0x0007, //!< Confirms that Long Name programming via ArtAddress, was successful.
|
||||
RcDmxError = 0x0008, //!< DMX512 receive errors detected.
|
||||
RcDmxUdpFull = 0x0009, //!< Ran out of internal DMX transmit buffers.
|
||||
RcDmxRxFull = 0x000A, //!< Ran out of internal DMX Rx buffers.
|
||||
RcSwitchErr = 0x000B, //!< Rx Universe switches conflict.
|
||||
RcConfigErr = 0x000C, //!< Product configuration does not match firmware.
|
||||
RcDmxShort = 0x000D, //!< DMX output short detected. See GoodOutput field.
|
||||
RcFirmwareFail = 0x000E, //!< Last attempt to upload new firmware failed.
|
||||
RcUserFail = 0x000F, //!< User changed switch settings when address locked by remote programming. User changes ignored.
|
||||
RcFactoryRes = 0x0010 //!< Factory reset has occurred.
|
||||
};
|
||||
|
||||
/// \cite ARTNET Table 4 - Style Codes
|
||||
enum Style : uint8_t {
|
||||
StNode = 0x00, //!< A DMX to / from Art-Net device
|
||||
StController = 0x01, //!< A lighting console.
|
||||
StMedia = 0x02, //!< A Media Server.
|
||||
StRoute = 0x03, //!< A network routing device.
|
||||
StBackup = 0x04, //!< A backup device.
|
||||
StConfig = 0x05, //!< A configuration or diagnostic tool
|
||||
StVisual = 0x06 //!< A visualiser
|
||||
};
|
||||
|
||||
/// \cite ARTNET Table 5 - Priority Codes
|
||||
enum Priority : uint8_t {
|
||||
DpLow = 0x10, //!< Low priority message.
|
||||
DpMed = 0x40, //!< Medium priority message.
|
||||
DpHigh = 0x80, //!< High priority message.
|
||||
DpCritial = 0xE0, //!< Critical priority message.
|
||||
DpVolatile = 0xF0 //!< Volatile message.
|
||||
};
|
||||
|
||||
|
||||
/// Set the communication behavior during ArtPoll
|
||||
struct TalkToMe {
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
bool depreciated : 1;
|
||||
bool reply_on_change : 1; //!< Send ArtPollReply whenever Node conditions change.
|
||||
bool diag_enable : 1; //!< Send me diagnostics messages.
|
||||
bool diag_unicast : 1; //!< Diagnostics messages are unicast. (if bit 2).
|
||||
bool VLC_disable : 1; //!< Disable VLC transmission.
|
||||
uint8_t reserved : 3;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The OEM word
|
||||
*
|
||||
* Describes the equipment vendor and the feature set available.
|
||||
* Bit 15 high indicates extended features available.
|
||||
*/
|
||||
struct OEM {
|
||||
union {
|
||||
uint16_t word = oem_unknown;
|
||||
struct {
|
||||
uint16_t manufacturer : 15;
|
||||
bool extended_features : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Authority enum
|
||||
*/
|
||||
enum Authority : uint8_t {
|
||||
AuthorityUnkown = 0b00, //!< Port-Address Programming Authority unknown.
|
||||
AuthorityLocal = 0b01, //!< Port-Address set by front panel controls.
|
||||
AuthorityRemote = 0b10, //!< All or part of Port-Address programmed by network
|
||||
AuthorityUnused = 0b11, //!< not used
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Indicator enum
|
||||
*/
|
||||
enum Indicator : uint8_t {
|
||||
IndicatorUnknown = 0b00, //!< Indicator state unknown.
|
||||
IndicatorIdentify = 0b01, //!< Indicators in Locate / Identify Mode.
|
||||
IndicatorMute = 0b10, //!< Indicators in Mute Mode.
|
||||
IndicatorNormal = 0b11, //!< Indicators in Normal Mode.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The FailoverMode enum
|
||||
*/
|
||||
enum FailoverMode : uint8_t {
|
||||
FailoverHoldLast = 0b00, //!< Hold last state.
|
||||
FailoverAllZeros = 0b01, //!< All output to zero.
|
||||
FailoverAllFull = 0b10, //!< All output to full.
|
||||
FailoverScenePlayback = 0b11, //!< Playback failover scene.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The General_Status register
|
||||
*/
|
||||
struct GeneralStatus {
|
||||
union {
|
||||
uint8_t _raw1 = 0;
|
||||
struct {
|
||||
bool ubea_valid : 1; //!< UBEA present and not corrupt.
|
||||
bool rdm_capable : 1; //!< Capable of Remote Device Management (RDM).
|
||||
bool boot_failsafe : 1; //!< Booted from ROM
|
||||
bool reserved1 : 1; //!< not implimented
|
||||
Authority authority : 2; //!< Port-Address Programming Authority
|
||||
Indicator indicator : 2; //!< Indicator State
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t _raw2 = 0;
|
||||
struct {
|
||||
bool web_config_available : 1; //!< supports web browser configuration.
|
||||
bool DHCP_active : 1; //!< Node’s IP is DHCP configured.
|
||||
bool DHCP_capable : 1; //!< Node is DHCP capable.
|
||||
bool port_address_15b : 1; //!< Node supports 15 bit Port-Address
|
||||
bool sACN_capable : 1; //!< Node is able to switch between Art-Net and sACN.
|
||||
bool squawking : 1; //!< is sqawking
|
||||
bool io_remote_set : 1; //!> Node supports switching of output style using ArtCommand.
|
||||
bool remote_RDM : 1; //!> Node supports control of RDM using ArtCommand.
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t _raw3 = 0;
|
||||
struct {
|
||||
uint8_t reserved3 : 5; //!< Not used, set to zero
|
||||
bool failover_capable : 1; //!< Node supports fail-over.
|
||||
FailoverMode failover_mode : 2; //!< network data loss behavior.
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The KnownProtocols enum
|
||||
*
|
||||
* Protocols elegible to be reported in the PortTypes array
|
||||
*/
|
||||
enum KnownProtocols : uint8_t {
|
||||
Protocol_DMX = 0b000000,
|
||||
Protocol_MIDI = 0b000001,
|
||||
Protocol_Avab = 0b000010,
|
||||
Protocol_CMX = 0b000011,
|
||||
Protocol_ADB = 0b000100,
|
||||
Protocol_ArtNet = 0b000101,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The PortTypes struct
|
||||
*
|
||||
* An array of 4 PortTypes are reported in the ArtPollReply packet.
|
||||
*/
|
||||
struct PortTypes {
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
KnownProtocols protocol : 6;
|
||||
bool can_input : 1;
|
||||
bool can_output : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The GoodInput struct
|
||||
*
|
||||
* An array of 4 GoodInput are reported in the ArtPollReply packet.
|
||||
*/
|
||||
struct GoodInput {
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
uint8_t reserved : 2; //!< Unused and transmitted as zero.
|
||||
bool rx_errors : 1; //!< Receive errors detected.
|
||||
bool disabled : 1; //!< Input is disabled.
|
||||
bool DMX_text : 1; //!< includes DMX512 text packets.
|
||||
bool DMX_SIP : 1; //!< includes DMX512 SIP’s.
|
||||
bool DMX_test : 1; //!< includes DMX512 test packets.
|
||||
bool active : 1; //!< Data received.
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The GoodOutput struct
|
||||
*
|
||||
* An array of 4 GoodOutput are reported in the ArtPollReply packet.
|
||||
*/
|
||||
struct GoodOutput {
|
||||
union {
|
||||
uint8_t _rawA = 0;
|
||||
struct {
|
||||
bool sACN_enabled : 1; //!< Output is selected to transmit sACN.
|
||||
bool merge_LTP : 1; //!< Merge Mode is LTP.
|
||||
bool output_short : 1; //!< DMX output short detected on power up.
|
||||
bool merge_ArtNet : 1; //!< Output is merging ArtNet data.
|
||||
bool DMX_text : 1; //!< includes DMX512 text packets.
|
||||
bool DMX_SIP : 1; //!< includes DMX512 SIP’s.
|
||||
bool DMX_test : 1; //!< includes DMX512 test packets.
|
||||
bool active : 1; //!< Data received.
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t _rawB = 0;
|
||||
struct {
|
||||
uint8_t reserved : 6; //!< Not used, set to zero
|
||||
bool output_continuous : 1; //!< oposite of changes-only
|
||||
bool rdm_disabled : 1; //!< RDM disabled
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ActivityReport struct
|
||||
*
|
||||
* reported in the ArtPollReply packet as SwMacro and SwRemote
|
||||
*/
|
||||
struct ActivityReport {
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
bool active_1 : 1;
|
||||
bool active_2 : 1;
|
||||
bool active_3 : 1;
|
||||
bool active_4 : 1;
|
||||
bool active_5 : 1;
|
||||
bool active_6 : 1;
|
||||
bool active_7 : 1;
|
||||
bool active_8 : 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The AddressCommand enum
|
||||
*/
|
||||
enum AddressCommand : uint8_t {
|
||||
// Node configuration commands:
|
||||
AcNone = 0x00, //!< No action
|
||||
AcCancelMerge = 0x01, //!< if in merge mode, cancel
|
||||
AcLedNormal = 0x02, //!< set front panel indicators to normal
|
||||
AcLedMute = 0x03, //!< switch off front panel indicators
|
||||
AcLedLocate = 0x04, //!< flash front panel indicators
|
||||
AcResetRxFlags = 0x05, //!< reset SIP, Text, Test and Error flags
|
||||
// Fail-over configuration commands:
|
||||
AcFailHold = 0x08, //!< hold last look
|
||||
AcFailZero = 0x09, //!< output zeros on data loss
|
||||
AcFailFull = 0x0a, //!< output full on data loss
|
||||
AcFailScene = 0x0b, //!< output scene on data loss
|
||||
AcFailRecord = 0x0c, //!< record current output state as failover scene
|
||||
// Port configuration commands:
|
||||
AcMergeLtp0 = 0x10, //!< set port 0 to merge LTP
|
||||
AcMergeLtp1 = 0x11, //!< set port 1 to merge LTP
|
||||
AcMergeLtp2 = 0x12, //!< set port 2 to merge LTP
|
||||
AcMergeLtp3 = 0x13, //!< set port 3 to merge LTP
|
||||
AcMergeHtp0 = 0x50, //!< set port 0 to merge HTP
|
||||
AcMergeHtp1 = 0x51, //!< set port 1 to merge HTP
|
||||
AcMergeHtp2 = 0x52, //!< set port 2 to merge HTP
|
||||
AcMergeHtp3 = 0x53, //!< set port 3 to merge HTP
|
||||
AcArtNetSel0 = 0x60, //!< set port 0 protocol to Art-Net
|
||||
AcArtNetSel1 = 0x61, //!< set port 1 protocol to Art-Net
|
||||
AcArtNetSel2 = 0x62, //!< set port 2 protocol to Art-Net
|
||||
AcArtNetSel3 = 0x63, //!< set port 3 protocol to Art-Net
|
||||
AcAcnSel0 = 0x70, //!< set port 0 protocol to sACN
|
||||
AcAcnSel1 = 0x71, //!< set port 1 protocol to sACN
|
||||
AcAcnSel2 = 0x72, //!< set port 2 protocol to sACN
|
||||
AcAcnSel3 = 0x73, //!< set port 3 protocol to sACN
|
||||
AcClearOp0 = 0x90, //!< clear output buffer for port 0
|
||||
AcClearOp1 = 0x91, //!< clear output buffer for port 1
|
||||
AcClearOp2 = 0x92, //!< clear output buffer for port 2
|
||||
AcClearOp3 = 0x93, //!< clear output buffer for port 3
|
||||
AcStyleDelta0 = 0xa0, //!< set port 0 to changes-only
|
||||
AcStyleDelta1 = 0xa1, //!< set port 1 to changes-only
|
||||
AcStyleDelta2 = 0xa2, //!< set port 2 to changes-only
|
||||
AcStyleDelta3 = 0xa3, //!< set port 3 to changes-only
|
||||
AcStyleConst0 = 0xb0, //!< set port 0 to constant output
|
||||
AcStyleConst1 = 0xb1, //!< set port 1 to constant output
|
||||
AcStyleConst2 = 0xb2, //!< set port 2 to constant output
|
||||
AcStyleConst3 = 0xb3, //!< set port 3 to constant output
|
||||
AcRdEnable0 = 0xc0, //!< enable RDM for port 0
|
||||
AcRdEnable1 = 0xc1, //!< enable RDM for port 1
|
||||
AcRdEnable2 = 0xc2, //!< enable RDM for port 2
|
||||
AcRdEnable3 = 0xc3, //!< enable RDM for port 3
|
||||
AcRdmDisable0 = 0xd0, //!< disable RDM for port 0
|
||||
AcRdmDisable1 = 0xd1, //!< disable RDM for port 1
|
||||
AcRdmDisable2 = 0xd2, //!< disable RDM for port 2
|
||||
AcRdmDisable3 = 0xd3, //!< disable RDM for port 3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The TimecodeType enum
|
||||
*/
|
||||
enum TimecodeType : uint8_t {
|
||||
Film = 0, //!< 24 fps
|
||||
EBU = 1, //!< 25 fps
|
||||
DF = 3, //!< 29.97 fps
|
||||
SMPTE = 4, //!< 30 fps
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Timecode struct
|
||||
*/
|
||||
struct Timecode {
|
||||
uint8_t frame; //!< 24-30, depending on type
|
||||
uint8_t seconds; //!< 0-59
|
||||
uint8_t minutes; //!< 0-59
|
||||
uint8_t hours; //!< 0-24
|
||||
TimecodeType type; //!< framerate
|
||||
};
|
||||
|
||||
// Table 7 – ArtTrigger Key Values.
|
||||
/// The SubKey field contains an ASCII character which the receiving device
|
||||
/// should process as if it were a keyboard press.
|
||||
static const uint8_t KeyAscii = 0;
|
||||
/// The SubKey field contains the number of a Macro which the receiving
|
||||
/// device should execute.
|
||||
static const uint8_t KeyMacro = 1;
|
||||
/// The SubKey field contains a soft-key number which the receiving device
|
||||
/// should process as if it were a soft-key keyboard press.
|
||||
static const uint8_t KeySoft = 2;
|
||||
/// The SubKey field contains the number of a Show which the receiving
|
||||
/// device should run.
|
||||
static const uint8_t KeyShow = 3;
|
||||
|
||||
static const std::size_t Short_Name_Length = 18; //!< string length
|
||||
static const std::size_t Long_Name_Length = 64; //!< string length
|
||||
static const std::size_t Node_Report_Length = 64; //!< string length
|
||||
|
||||
/// \cite ARTNET
|
||||
/// ...to allow transition between synchronous and non-synchronous modes, a
|
||||
/// node shall time out to non-synchronous operation if an ArtSync is not
|
||||
/// received for 4 seconds or more.
|
||||
static const uint16_t SYNC_LOSS_TIMEOUT = 4000;
|
||||
|
||||
|
||||
namespace VLC {
|
||||
/// The DMX512 start code of this (ArtVlc) packet is set to 0x91.
|
||||
static const uint8_t START_CODE = 0x91;
|
||||
/// Magic number used to identify this packet.
|
||||
static const uint8_t MagicNumber[] = {0x41, 0x4c, 0x45};
|
||||
/// Payload contains a simple text string representing a URL.
|
||||
static const uint16_t BeaconURL = 0x0000;
|
||||
/// Payload contains a simple ASCII text message
|
||||
static const uint16_t BeaconText = 0x0001;
|
||||
} // namespace ARTNET::VLC
|
||||
|
||||
|
||||
namespace FIRMWARE {
|
||||
/// Type of firmware master packet
|
||||
enum MasterType : uint8_t {
|
||||
FirmFirst = 0x00, //!< The first packet of a firmware upload.
|
||||
FirmCont = 0x01, //!< A consecutive continuation packet of a firmware upload.
|
||||
FirmLast = 0x02, //!< The last packet of a firmware upload.
|
||||
UbeaFirst = 0x03, //!< The first packet of a UBEA upload.
|
||||
UbeaCont = 0x04, //!< A consecutive continuation packet of a UBEA upload.
|
||||
UbeaLast = 0x05, //!< The last packet of a UBEA upload.
|
||||
};
|
||||
/// Type of firmware reply packet
|
||||
enum ResponseType : uint8_t {
|
||||
FirmBlockGood = 0x00, //!< Last packet recieved successfully.
|
||||
FirmAllGood = 0x01, //!< All firmware receieved successfully.
|
||||
FirmFail = 0xff, //!< Firmware upload failed.
|
||||
};
|
||||
} // namespace ARTNET::FIRMWARE
|
||||
|
||||
|
||||
namespace RDM {
|
||||
enum Version : uint8_t {
|
||||
Draft = 0x00, //!< RDM DRAFT V1.0
|
||||
Standard = 0x01, //!< RDM V1.0
|
||||
};
|
||||
enum TodRequestCommand : uint8_t {
|
||||
TodFull = 0x00, //!< Send the Entire TOD
|
||||
};
|
||||
enum TodCommandResponse : uint8_t {
|
||||
ResponseTodFull = 0x00, //!< entire or packet in sequence of the entire TOD.
|
||||
ResponseTodNak = 0xff, //!< TOD is not available or discovery is incomplete.
|
||||
};
|
||||
enum TodControlCommand : uint8_t {
|
||||
AtcNone = 0x00, //!< No action.
|
||||
AtcFlush = 0x01, //!< The node flushes its TOD and instigates full discovery.
|
||||
};
|
||||
enum RdmCommand : uint8_t {
|
||||
ArProcess = 0x00, //!< Process RDM Packet.
|
||||
};
|
||||
} // namespace ARTNET::RDM
|
||||
|
||||
|
||||
/// @brief Communication Activity
|
||||
///
|
||||
/// On if any Art-Net packets detected on network, timeout after 6 seconds.
|
||||
static const uint16_t DATA_LOSS_TIMEOUT = 6000;
|
||||
|
||||
} // namespace ARTNET
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,839 @@
|
|||
/*
|
||||
packet.h
|
||||
|
||||
Copyright (c) 2022 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "artnet.h"
|
||||
#include "config.h"
|
||||
#include "acn/pdu-stream.h"
|
||||
#include "rdm/uid.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ARTNET {
|
||||
|
||||
/**
|
||||
* @brief The packet_data struct
|
||||
*/
|
||||
struct packet_data
|
||||
: public ACN::PDU::pdu_stream_object
|
||||
{
|
||||
uint16_t version = VERSION; //!< Protocol Version
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The artpoll_data struct
|
||||
*
|
||||
* \cite ARTNET This packet is used to discover the presence of other
|
||||
* Controllers, Nodes and Media Servers. The ArtPoll packet is only sent by
|
||||
* a Controller. Both Controllers and Nodes respond to the packet.
|
||||
*/
|
||||
struct poll_data
|
||||
: public packet_data
|
||||
{
|
||||
poll_data()
|
||||
: diagnostic_level(DpLow)
|
||||
{};
|
||||
|
||||
TalkToMe talk_to_me; //!< Set behaviour of Node
|
||||
Priority diagnostic_level; //!< The lowest priority of diagnostics message
|
||||
|
||||
virtual size_t streamSize() const override { return 4; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The artpollreply_data struct
|
||||
*
|
||||
* A device, in response to a Controller’s ArtPoll, sends the ArtPollReply.
|
||||
* This packet is also broadcast to the Directed Broadcast address by all
|
||||
* Art-Net devices on power up.
|
||||
*/
|
||||
struct pollreply_data
|
||||
: public packet_data
|
||||
{
|
||||
pollreply_data()
|
||||
: udp_port(UDP_PORT)
|
||||
, esta_manufacturer(MY_ESTA_MANUFACTURER_ID)
|
||||
{};
|
||||
|
||||
uint32_t my_ip = 0; //!< the Node’s IPv4 address
|
||||
uint16_t udp_port; //!< The Port is always 0x1936
|
||||
PortAddress net_sub_switch; //!< Net and Subnet switch positions
|
||||
OEM oem; //!< the equipment vendor and the feature set
|
||||
uint8_t ubea_version = 0; //!< the firmware version of the User Bios Extension Area (UBEA)
|
||||
GeneralStatus status; //!< general status register
|
||||
uint16_t esta_manufacturer; //!< manufacturer ID
|
||||
std::string short_name = ""; //!< short name for the Node
|
||||
std::string long_name = ""; //!< long name for the Node
|
||||
uint16_t num_ports = 0; //!< the number of input or output ports. Max=4
|
||||
PortTypes port_types[4]; //!< operation and protocol of each port.
|
||||
GoodInput good_input[4]; //!< input status of the node.
|
||||
GoodOutput good_output[4]; //!< output status of the node.
|
||||
uint8_t SwIn[4]; //!< Bits 3-0 of the 15 bit Port-Address for each input port
|
||||
uint8_t SwOut[4]; //!< Bits 3-0 of the 15 bit Port-Address for each output port
|
||||
uint8_t SwVideo = 0; //!< This field is now deprecated.
|
||||
ActivityReport SwMacro; //!< used for remote event triggering or cueing.
|
||||
ActivityReport SwRemote; //!< used for remote event triggering or cueing.
|
||||
Style style; //!< the equipment style of the device.
|
||||
uint8_t mac_address[6] = {0}; //!< MAC Address
|
||||
uint32_t bind_ip = 0; //!< the IP of the root device.
|
||||
uint8_t bind_index = 1; //!< the order of bound devices.
|
||||
|
||||
/**
|
||||
* @brief textual report of the Node’s operating status or operational errors.
|
||||
* @return
|
||||
*/
|
||||
const std::string report() const { return _node_report; };
|
||||
void set_report(NodeReport, uint, std::string);
|
||||
|
||||
virtual size_t streamSize() const override { return 226; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
std::string _node_report = "";
|
||||
static const size_t _filler_length = 21; //!< length of filler at end of packet
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The artipprog_data struct
|
||||
*
|
||||
* Program the IPv4 address.
|
||||
*/
|
||||
struct ipprog_data
|
||||
: public packet_data
|
||||
{
|
||||
ipprog_data()
|
||||
: udp_port(UDP_PORT)
|
||||
{};
|
||||
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
bool program_ip : 1;
|
||||
bool program_netmask : 1;
|
||||
bool program_port : 1;
|
||||
bool reset_ip_mask_port : 1;
|
||||
uint8_t reserved : 2;
|
||||
bool enable_dhcp : 1;
|
||||
bool enable_programming : 1;
|
||||
};
|
||||
} command; //!< Action of this packet
|
||||
uint32_t ip_address = 0; //!< IP Address to be programmed into Node
|
||||
uint32_t subnet_mask = 0; //!< Subnet Mask to be programmed into Node
|
||||
uint16_t udp_port; //!< Depreciated
|
||||
|
||||
virtual size_t streamSize() const override { return 24; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
static const size_t _spare_length = 8;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The artipprogreply_data struct
|
||||
*/
|
||||
struct ipprogreply_data
|
||||
: public packet_data
|
||||
{
|
||||
ipprogreply_data()
|
||||
: udp_port(UDP_PORT)
|
||||
{};
|
||||
|
||||
uint32_t ip_address = 0; //!< IP Address of the Node
|
||||
uint32_t subnet_mask = 0; //!< Subnet Mask of the Node
|
||||
uint16_t udp_port; //!< Depreciated
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
uint8_t reserved1 : 6;
|
||||
bool dhcp_enabled : 1;
|
||||
bool reserved2 : 1;
|
||||
};
|
||||
} status; //!< Status flags
|
||||
|
||||
virtual size_t streamSize() const override { return 24; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
static const size_t _spare_length = 7;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The address_data struct
|
||||
*/
|
||||
struct address_data
|
||||
: public packet_data
|
||||
{
|
||||
PortAddress net_sub_switch; //!< Net and Subnet switch positions
|
||||
uint8_t bind_index = 1; //!< the order of bound devices.
|
||||
std::string short_name = ""; //!< short name for the Node
|
||||
std::string long_name = ""; //!< long name for the Node
|
||||
uint8_t SwIn[4]; //!< Bits 3-0 of the 15 bit Port-Address for each input port
|
||||
uint8_t SwOut[4]; //!< Bits 3-0 of the 15 bit Port-Address for each output port
|
||||
uint8_t SwVideo = 0; //!< This field is now deprecated.
|
||||
AddressCommand command; //!< Node configuration command.
|
||||
|
||||
virtual size_t streamSize() const override { return 97; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The diagdata_data struct
|
||||
*/
|
||||
struct diagdata_data
|
||||
: public packet_data
|
||||
{
|
||||
Priority priority; //!< priority of the diagnostic data
|
||||
std::string data = ""; //!< ASCII text
|
||||
|
||||
virtual size_t streamSize() const override { return 8 + data.length() + 1; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
static const uint16_t _max_data_length = 512; //!< max data length, including null terminator
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The timecode_data struct
|
||||
*/
|
||||
struct timecode_data
|
||||
: public packet_data
|
||||
{
|
||||
Timecode time; //!< time code
|
||||
|
||||
virtual size_t streamSize() const override { return 9; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The command_data struct
|
||||
*/
|
||||
struct command_data
|
||||
: public packet_data
|
||||
{
|
||||
uint16_t esta_manufacturer; //!< manufacturer ID
|
||||
std::string data = ""; //!< ASCII text
|
||||
|
||||
virtual size_t streamSize() const override { return 6 + data.length() + 1; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
static const uint16_t _max_data_length = 512; //!< max data length, including null terminator
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The trigger_data struct
|
||||
*/
|
||||
struct trigger_data
|
||||
: public packet_data
|
||||
{
|
||||
OEM oem; //!< the equipment vendor and the feature set
|
||||
uint8_t key; //!< the trigger key
|
||||
uint8_t subkey; //!< the trigger subkey
|
||||
uint8_t data[512] = {0}; //!< data array
|
||||
|
||||
virtual size_t streamSize() const override { return 520; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief The dmx_data struct
|
||||
*/
|
||||
struct dmx_data
|
||||
: public packet_data
|
||||
{
|
||||
uint8_t sequence; //!< to ensure that ArtDmx packets are used in the correct order.
|
||||
uint8_t physical; //!< the physical input port from which DMX was input
|
||||
PortAddress universe; //!< Net, Subnet, and universe number
|
||||
std::vector<uint8_t> data = {0}; //!< data array, initialize null start
|
||||
|
||||
virtual size_t streamSize() const override { return 7 + data.size(); };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The sync_data struct
|
||||
*/
|
||||
struct sync_data
|
||||
: public packet_data
|
||||
{
|
||||
virtual size_t streamSize() const override { return 4; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The nzs_data struct
|
||||
*/
|
||||
struct nzs_data
|
||||
: public packet_data
|
||||
{
|
||||
/**
|
||||
* @brief nzs_data
|
||||
* @param startcode
|
||||
*/
|
||||
nzs_data(uint8_t startcode = 0)
|
||||
{ data = {startcode}; }
|
||||
|
||||
uint8_t sequence; //!< to ensure that ArtDmx packets are used in the correct order.
|
||||
PortAddress universe; //!< Net, Subnet, and universe number
|
||||
std::vector<uint8_t> data; //!< data array with startcode
|
||||
|
||||
virtual size_t streamSize() const override { return 7 + data.size(); };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The vlc_data struct
|
||||
*/
|
||||
struct vlc_data
|
||||
: public nzs_data
|
||||
{
|
||||
/**
|
||||
* @brief vlc_data
|
||||
* @param other
|
||||
*/
|
||||
vlc_data(const nzs_data * other = nullptr)
|
||||
: nzs_data(VLC::START_CODE)
|
||||
{ if (other) _from_nzs(other); }
|
||||
|
||||
union {
|
||||
uint8_t _raw = 0;
|
||||
struct {
|
||||
uint8_t padding : 5; //!< reserved
|
||||
bool beacon : 1; //!< the transmitter should continuously repeat transmission of this packet until another is received
|
||||
bool reply : 1; //!< is a reply packet that is in response to the request sent with matching number in the transaction number
|
||||
bool IEEE : 1; //!< data in the payload area shall be interpreted as IEEE VLC data.
|
||||
};
|
||||
} flags; //!< flags for this packet
|
||||
uint16_t transaction = 0; //!< transaction number which allows VLC transactions to be synchronised
|
||||
uint16_t address = 0; //!< The slot number, range 1-512, of the device to which this packet is directed.
|
||||
uint8_t depth = 0; //!< modulation depth expressed as a percentage in the range 1 to 100
|
||||
uint16_t frequency = 0; //!< modulation frequency of the VLC transmitter expressed in Hz.
|
||||
uint16_t modulation = 0; //!< modulation type number that the transmitter should use to transmit VLC.
|
||||
uint16_t language = 0; //!< payload language code
|
||||
uint16_t beacon_frequency; //!< the frequency in Hertz at which the VLC packet should be repeated.
|
||||
std::vector<uint8_t> payload; //!< The actual VLC payload.
|
||||
|
||||
virtual size_t streamSize() const override { return 30 + data.size(); };
|
||||
|
||||
/// The ArtVlc packet is a specially formed ArtNzs packet.
|
||||
/// compile() MUST BE CALLED prior to streaming.
|
||||
void compile();
|
||||
|
||||
private:
|
||||
const static size_t _payload_max_length = 480;
|
||||
uint16_t _checksum() const;
|
||||
bool _from_nzs(const nzs_data *);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The input_data struct
|
||||
*/
|
||||
struct input_data
|
||||
: public packet_data
|
||||
{
|
||||
uint8_t bind_index = 1; //!< the order of bound devices.
|
||||
uint16_t num_ports = 0; //!< the number of input or output ports. Max=4
|
||||
union InputFlags {
|
||||
uint8_t _raw = 0; //!< raw byte
|
||||
struct {
|
||||
bool disabled : 1; //!< Set to disable this input.
|
||||
uint8_t reserved : 7;
|
||||
};
|
||||
}; //!< flags for this packet
|
||||
InputFlags status[4]; //!< input disable status of each port.
|
||||
|
||||
virtual size_t streamSize() const override { return 10; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The firmwaremaster_data struct
|
||||
*/
|
||||
struct firmwaremaster_data
|
||||
: public packet_data
|
||||
{
|
||||
FIRMWARE::MasterType type; //!< Defines the packet contents
|
||||
uint8_t block_id; //!< Counts the consecutive blocks of firmware upload.
|
||||
uint64_t length; //!< the file size (in words) of the file to be uploaded.
|
||||
uint16_t block[256] = {0}; //!< the firmware or UBEA data block.
|
||||
|
||||
virtual size_t streamSize() const override { return 542; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
const size_t _spare_length = 20;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The firmwarereply_data struct
|
||||
*/
|
||||
struct firmwarereply_data
|
||||
: public packet_data
|
||||
{
|
||||
FIRMWARE::ResponseType type; //!< Defines the packet contents
|
||||
|
||||
virtual size_t streamSize() const override { return 26; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
const size_t _spare_length = 21;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The todrequest_data struct
|
||||
*/
|
||||
struct todrequest_data
|
||||
: public packet_data
|
||||
{
|
||||
std::vector<PortAddress> universes; //!< universes that must respond
|
||||
|
||||
virtual size_t streamSize() const override { return 14 + universes.size(); };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
private:
|
||||
const size_t _max_count = 32;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The toddata_data struct
|
||||
*/
|
||||
struct toddata_data
|
||||
: public packet_data
|
||||
{
|
||||
RDM::Version rdm_version = RDM::Standard; //!< supports Draft or Standard RDM
|
||||
uint8_t port = 1; //!< physical port index
|
||||
uint8_t bind_index = 1; //!< sub-device
|
||||
PortAddress universe; //!< responding universe
|
||||
RDM::TodCommandResponse type = RDM::ResponseTodFull; //!< response type
|
||||
uint16_t total_count = 0; //!< total device count
|
||||
uint8_t block_count = 0; //!< index of these devices in total
|
||||
std::vector<std::shared_ptr<::RDM::UID>> devices; //!< block of up to 200 devices
|
||||
|
||||
virtual size_t streamSize() const override { return 18 + devices.size() * 6; }
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The todcontrol_data struct
|
||||
*/
|
||||
struct todcontrol_data
|
||||
: public packet_data
|
||||
{
|
||||
PortAddress universe; //!< unverse that should action command
|
||||
RDM::TodControlCommand command = RDM::AtcNone; //!< control command
|
||||
|
||||
virtual size_t streamSize() const override { return 14; };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The rdm_data struct
|
||||
*/
|
||||
struct rdm_data
|
||||
: public packet_data
|
||||
{
|
||||
RDM::Version rdm_version = RDM::Standard; //!< supports Draft or Standard RDM
|
||||
PortAddress universe; //!< responding universe
|
||||
RDM::RdmCommand command = RDM::ArProcess; //!< response type
|
||||
std::vector<uint8_t> data = {::RDM::SC_RDM}; //!< data array, initialize RDM start
|
||||
|
||||
virtual size_t streamSize() const override { return 13 + data.size(); };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The rdmsub_data struct
|
||||
*/
|
||||
struct rdmsub_data
|
||||
: public packet_data
|
||||
{
|
||||
RDM::Version rdm_version = RDM::Standard; //!< supports Draft or Standard RDM
|
||||
::RDM::UID uid; //!< UID of target RDM device.
|
||||
uint8_t command_class; //!< Get, Set, GetResponse, SetResponse
|
||||
::RDM::PID pid; //!< type of parameter
|
||||
uint16_t subdevice = 0; //!< the first device information contained in packet
|
||||
std::vector<uint16_t> data; //!< packed data array
|
||||
|
||||
virtual size_t streamSize() const override { return 20 + (data.size() * 2); };
|
||||
virtual void iStream(ACN::PDU::Stream) override;
|
||||
virtual void oStream(ACN::PDU::Stream) const override;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ARTNET packet
|
||||
*
|
||||
* All UDP packets accepted by the Node conform to the Art-Net protocol
|
||||
* specification as defined... Any other packets are ignored.
|
||||
*/
|
||||
struct Packet
|
||||
: public ACN::PDU::pdu_stream_object
|
||||
{
|
||||
/**
|
||||
* @brief Packet
|
||||
* @param data
|
||||
*/
|
||||
Packet(std::shared_ptr<packet_data> data = nullptr)
|
||||
: _opcode(OpNull)
|
||||
, _data(data)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief opcode
|
||||
* @return
|
||||
*/
|
||||
OpCode opcode() { return _opcode; }
|
||||
|
||||
/**
|
||||
* @brief data
|
||||
* @return
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> data()
|
||||
{
|
||||
#ifdef RTTI_ENABLED
|
||||
return std::dynamic_pointer_cast<T>(_data);
|
||||
#else
|
||||
return std::static_pointer_cast<T>(_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief createData
|
||||
* @param stream
|
||||
*/
|
||||
template<class T>
|
||||
void createData(ACN::PDU::Stream stream = nullptr)
|
||||
{
|
||||
if (_data)
|
||||
return; // already has a data segment
|
||||
_data = std::make_shared<T>();
|
||||
if (stream && stream->good())
|
||||
_data->iStream(stream);
|
||||
}
|
||||
|
||||
size_t streamSize() const override;
|
||||
void iStream(ACN::PDU::Stream) override;
|
||||
void oStream(ACN::PDU::Stream) const override;
|
||||
|
||||
protected:
|
||||
OpCode _opcode; //!< Op Code
|
||||
std::shared_ptr<packet_data> _data; //!< packet data
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtPoll Packet
|
||||
*/
|
||||
struct ArtPoll
|
||||
: public Packet
|
||||
{
|
||||
ArtPoll()
|
||||
: Packet(std::make_shared<poll_data>())
|
||||
{ _opcode = OpPoll; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtPollReply Packet
|
||||
*/
|
||||
struct ArtPollReply
|
||||
: public Packet
|
||||
{
|
||||
ArtPollReply()
|
||||
: Packet(std::make_shared<pollreply_data>())
|
||||
{ _opcode = OpPollReply; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtIpProg Packet
|
||||
*/
|
||||
struct ArtIpProg
|
||||
: public Packet
|
||||
{
|
||||
ArtIpProg()
|
||||
: Packet(std::make_shared<ipprog_data>())
|
||||
{ _opcode = OpIpProg; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtIpProgReply Packet
|
||||
*/
|
||||
struct ArtIpProgReply
|
||||
: public Packet
|
||||
{
|
||||
ArtIpProgReply()
|
||||
: Packet(std::make_shared<ipprogreply_data>())
|
||||
{ _opcode = OpIpProgReply; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtAddress Packet
|
||||
*/
|
||||
struct ArtAddress
|
||||
: public Packet
|
||||
{
|
||||
ArtAddress()
|
||||
: Packet(std::make_shared<address_data>())
|
||||
{ _opcode = OpAddress; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtDiagData Packet
|
||||
*/
|
||||
struct ArtDiagData
|
||||
: public Packet
|
||||
{
|
||||
ArtDiagData()
|
||||
: Packet(std::make_shared<diagdata_data>())
|
||||
{ _opcode = OpDiagData; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtTimeCode Packet
|
||||
*/
|
||||
struct ArtTimeCode
|
||||
: public Packet
|
||||
{
|
||||
ArtTimeCode()
|
||||
: Packet(std::make_shared<timecode_data>())
|
||||
{ _opcode = OpTimeCode; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtCommand Packet
|
||||
*/
|
||||
struct ArtCommand
|
||||
: public Packet
|
||||
{
|
||||
ArtCommand()
|
||||
: Packet(std::make_shared<command_data>())
|
||||
{ _opcode = OpCommand; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtTrigger Packet
|
||||
*/
|
||||
struct ArtTrigger
|
||||
: public Packet
|
||||
{
|
||||
ArtTrigger()
|
||||
: Packet(std::make_shared<trigger_data>())
|
||||
{ _opcode = OpTrigger; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtDmx Packet
|
||||
*/
|
||||
struct ArtDmx
|
||||
: public Packet
|
||||
{
|
||||
ArtDmx()
|
||||
: Packet(std::make_shared<dmx_data>())
|
||||
{ _opcode = OpDmx; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtSync Packet
|
||||
*/
|
||||
struct ArtSync
|
||||
: public Packet
|
||||
{
|
||||
ArtSync()
|
||||
: Packet(std::make_shared<sync_data>())
|
||||
{ _opcode = OpSync; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtNzs Packet
|
||||
*/
|
||||
struct ArtNzs
|
||||
: public Packet
|
||||
{
|
||||
ArtNzs()
|
||||
: Packet(std::make_shared<nzs_data>())
|
||||
{ _opcode = OpNzs; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtVlc Packet
|
||||
*/
|
||||
struct ArtVlc
|
||||
: public Packet
|
||||
{
|
||||
ArtVlc()
|
||||
: Packet(std::make_shared<vlc_data>())
|
||||
{ _opcode = OpNzs; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtInput Packet
|
||||
*/
|
||||
struct ArtInput
|
||||
: public Packet
|
||||
{
|
||||
ArtInput()
|
||||
: Packet(std::make_shared<input_data>())
|
||||
{ _opcode = OpInput; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtFirmwareMaster Packet
|
||||
*/
|
||||
struct ArtFirmwareMaster
|
||||
: public Packet
|
||||
{
|
||||
ArtFirmwareMaster()
|
||||
: Packet(std::make_shared<firmwaremaster_data>())
|
||||
{ _opcode = OpFirmwareMaster; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtFirmwareReply Packet
|
||||
*/
|
||||
struct ArtFirmwareReply
|
||||
: public Packet
|
||||
{
|
||||
ArtFirmwareReply()
|
||||
: Packet(std::make_shared<firmwarereply_data>())
|
||||
{ _opcode = OpFirmwareReply; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtTodRequest Packet
|
||||
*/
|
||||
struct ArtTodRequest
|
||||
: public Packet
|
||||
{
|
||||
ArtTodRequest()
|
||||
: Packet(std::make_shared<todrequest_data>())
|
||||
{ _opcode = OpTodRequest; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtTodData Packet
|
||||
*/
|
||||
struct ArtTodData
|
||||
: public Packet
|
||||
{
|
||||
ArtTodData()
|
||||
: Packet(std::make_shared<toddata_data>())
|
||||
{ _opcode = OpTodData; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtTodControl Packet
|
||||
*/
|
||||
struct ArtTodControl
|
||||
: public Packet
|
||||
{
|
||||
ArtTodControl()
|
||||
: Packet(std::make_shared<todcontrol_data>())
|
||||
{ _opcode = OpTodControl; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The ArtRdm Packet
|
||||
*/
|
||||
struct ArtRdm
|
||||
: public Packet
|
||||
{
|
||||
ArtRdm()
|
||||
: Packet(std::make_shared<rdm_data>())
|
||||
{ _opcode = OpRdm; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Art Packet
|
||||
*/
|
||||
struct ArtRdmSub
|
||||
: public Packet
|
||||
{
|
||||
ArtRdmSub()
|
||||
: Packet(std::make_shared<rdmsub_data>())
|
||||
{ _opcode = OpRdmSub; }
|
||||
};
|
||||
|
||||
|
||||
} // namespace ARTNET
|
Loading…
Reference in New Issue