154 lines
5.9 KiB
C++
154 lines
5.9 KiB
C++
/*
|
|
sacn.h
|
|
|
|
Copyright (c) 2020 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 "../acn/sdt/sdt.h"
|
|
|
|
#include <cstdint>
|
|
|
|
/**
|
|
* @brief \cite sACN E1.31 Lightweight streaming protocol for transport of
|
|
* DMX512 \cite DMX using ACN \cite ACN.
|
|
*
|
|
* # 1 Introduction
|
|
*
|
|
* ## 1.1 Scope
|
|
*
|
|
* > This standard describes a mechanism to transfer DMX512-A [DMX] packets
|
|
* > over an IP network using a subset of the ACN protocol suite. It covers
|
|
* > data format, data protocol, data addressing, and network management. It
|
|
* > also outlines a synchronization method to help ensure that multiple
|
|
* > receivers can process this data concurrently when supervised by the same
|
|
* > source. Sources transporting either data or synchronization packets must
|
|
* > also advertise, via the Universe Discovery mechanism, what universes they
|
|
* > are actively transmitting on.
|
|
*
|
|
* ## 1.2 Overview and Architecture
|
|
*
|
|
* > This standard can be used to transfer DMX512-A \cite DMX packets of all
|
|
* > START Codes via an ANSI E1.17 \cite ACN supported network. It also
|
|
* > defines a method by which this \cite DMX data may be synchronized across
|
|
* > multiple receivers. A simple packet wrapper approach is used whereby the
|
|
* > data is encapsulated in a wrapper following the ACN packet structure.
|
|
* > For the use of this standard, the ACN wrapper is carried in UDP
|
|
* > \cite udp packets.
|
|
* >
|
|
* > The wrapper is structured such that it is both compatible and meaningful
|
|
* > to the ANSI E1.17 \cite ACN standard. Readers are referred to the ANSI
|
|
* > E1.17 \cite ACN standard, particularly the “ACN Architecture” \cite ACN
|
|
* > and “Device Management Protocol” \cite DMP documents for more information.
|
|
* > The “Root Layer Protocol” used in this standard is described in the “ACN
|
|
* > Architecture” document.
|
|
* >
|
|
* > This standard uses multicast addressing to provide a mechanism to
|
|
* > partition traffic for distinct universes of DMX512-A \cite DMX and
|
|
* > synchronization data. Direct unicast of DMX512-A \cite DMX data is also
|
|
* > supported.
|
|
*/
|
|
namespace sACN {
|
|
|
|
/// @brief \cite sACN 3.1 Octet: An eight-bit byte within a data packet.
|
|
using octet = uint8_t;
|
|
|
|
/// @brief \cite sACN 3.3 Universe Number: Each E1.31 Data Packet contains a universe
|
|
/// number identifying the universe it carries.
|
|
///
|
|
/// > From an ACN perspective, a receiving device has some number of properties
|
|
/// > whose value is addressed by the combination of a universe number and a
|
|
/// > data slot number. From an historical perspective, a receiving device
|
|
/// > consumes some number of DMX512-A \cite DMX data slots.
|
|
using universe_number = uint16_t;
|
|
|
|
|
|
// Appendix A: Defined Parameters (Normative)
|
|
static const uint32_t VECTOR_ROOT_E131_DATA = 0x00000004;
|
|
static const uint32_t VECTOR_ROOT_E131_EXTENDED = 0x00000008;
|
|
|
|
static const uint8_t VECTOR_DMP_SET_PROPERTY = 0x02;
|
|
|
|
static const uint32_t VECTOR_E131_DATA_PACKET = 0x00000002;
|
|
|
|
static const uint32_t VECTOR_E131_EXTENDED_SYNCHRONIZATION = 0x00000001;
|
|
static const uint32_t VECTOR_E131_EXTENDED_DISCOVERY = 0x00000002;
|
|
|
|
static const uint32_t VECTOR_UNIVERSE_DISCOVERY_UNIVERSE_LIST = 0x00000001;
|
|
|
|
static const uint16_t E131_UNIVERSE_DISCOVER_INTERVAL = 10000; // ms
|
|
static const uint16_t E131_NETWORK_DATA_LOSS_TIMEOUT = 2500; // ms
|
|
static const uint16_t E131_DISCOVERY_UNIVERSE = 64214;
|
|
|
|
static const uint16_t ACN_SDT_MULTICAST_PORT = 5568;
|
|
|
|
|
|
/// @brief borrow Ip address struct from ACN::SDT::UDP
|
|
///
|
|
/// > \cite sACN 9 Operation of E1.31 in IPv4 and IPv6 Networks
|
|
/// >
|
|
/// > This standard has the ability to operate over both IPv4 and IPv6
|
|
/// > transports.
|
|
using ipAddress = ACN::SDT::UDP::ipAddress;
|
|
|
|
/// @brief borrow Ip address types from ACN::SDT
|
|
///
|
|
/// > \cite sACN 9 Operation of E1.31 in IPv4 and IPv6 Networks
|
|
/// >
|
|
/// > Components complying with this standard shall indicate,
|
|
/// > through labelling, manufacturer documentation, or other means, which IP
|
|
/// > transports they support.
|
|
using ip_addr_spec = ACN::SDT::ip_addr_spec;
|
|
|
|
|
|
/**
|
|
* @brief \cite sACN 9.3.1 Allocation of IPv4 Multicast Addresses
|
|
*
|
|
* > Multicast addresses are from the IPv4 Local Scope and will be managed by
|
|
* > routers in conformance with RFC 2365 \cite ASIPM.
|
|
*/
|
|
static inline const ipAddress IPv4MulticastAddress(universe_number universe) {
|
|
ipAddress addr;
|
|
addr.type = ACN::SDT::SDT_ADDR_IPV4;
|
|
addr.address.ipv4.bytes[3] = 239;
|
|
addr.address.ipv4.bytes[2] = 255;
|
|
addr.address.ipv4.bytes[1] = universe >> 8;
|
|
addr.address.ipv4.bytes[0] = universe & 0xff;
|
|
return addr;
|
|
};
|
|
|
|
|
|
/**
|
|
* @brief \cite sACN 9.3.2 Allocation of IPv6 Multicast Addresses
|
|
* @param universe
|
|
* @return
|
|
*/
|
|
static inline const ipAddress IPv6MulticastAddress(universe_number universe) {
|
|
ipAddress addr;
|
|
addr.type = ACN::SDT::SDT_ADDR_IPV6;
|
|
addr.address.ipv6.group[3] = 131;
|
|
addr.address.ipv6.group[1] = universe >> 8;
|
|
addr.address.ipv6.group[0] = universe & 0xff;
|
|
return addr;
|
|
}
|
|
|
|
} // SACN
|