2022-06-08 16:05:06 -04:00
|
|
|
|
/*
|
|
|
|
|
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)
|
2022-06-09 16:51:14 -04:00
|
|
|
|
, oem(MY_ARTNET_MANUFACTUER_ID)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
, 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
|