133 lines
3.7 KiB
C++
133 lines
3.7 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.
|
|
*/
|
|
|
|
#ifndef SACN_H_
|
|
#define SACN_H_
|
|
|
|
#include <AsyncUDP.h>
|
|
#include <unordered_map>
|
|
#include "dmx_universe.h"
|
|
|
|
// Appendix A: Defined Parameters (Normative)
|
|
#define VECTOR_ROOT_E131_DATA 0x00000004
|
|
#define VECTOR_ROOT_E131_EXTENDED 0x00000008
|
|
|
|
#define VECTOR_DMP_SET_PROPERTY 0x02 // informative
|
|
|
|
#define VECTOR_E131_DATA_PACKET 0x00000002
|
|
|
|
#define VECTOR_E131_EXTENDED_SYNCHRONIZATION 0x00000001
|
|
#define VECTOR_E131_EXTENDED_DISCOVERY 0x00000002
|
|
|
|
#define E131_E131_UNIVERSE_DISCOVER_INTERVAL 10000 // ms
|
|
#define E131_NETWORK_DATA_LOSS_TIMEOUT 2500 // ms
|
|
#define E131_DISCOVERY_UNIVERSE 64214
|
|
|
|
#define ACN_SDT_MULTICAST_PORT 5568
|
|
|
|
// A S C - E 1 . 1 7
|
|
static constexpr uint8_t ACN_PACKET_IDENTIFIER[] = { 0x41, 0x53, 0x43, 0x2d, 0x45, 0x31, 0x2e, 0x31, 0x37, 0x00, 0x00, 0x00 };
|
|
|
|
|
|
// Table 5-1: ACN Root Layer
|
|
typedef union {
|
|
struct {
|
|
uint16_t preamble_size;
|
|
uint16_t postamble_size;
|
|
uint8_t acn_id[12];
|
|
uint16_t flength;
|
|
uint32_t vector;
|
|
uint8_t cid[16];
|
|
} __attribute__((packed));
|
|
uint8_t raw[37];
|
|
} e131_rlp_t;
|
|
|
|
|
|
// Table 6-1: E1.31 Data Packet Framing Layer
|
|
typedef union {
|
|
struct {
|
|
uint16_t flength;
|
|
uint32_t vector;
|
|
uint8_t source_name[64];
|
|
uint8_t priority;
|
|
uint16_t reserved;
|
|
uint8_t sequence_number;
|
|
uint8_t options;
|
|
uint16_t universe;
|
|
} __attribute__((packed));
|
|
uint8_t raw[77];
|
|
} e131_frame_t;
|
|
|
|
|
|
// Table 7-1: E131 Data Packet DMP Layer
|
|
typedef union {
|
|
struct {
|
|
uint16_t flength;
|
|
uint8_t vector;
|
|
uint8_t type;
|
|
uint16_t first_address;
|
|
uint16_t address_increment;
|
|
uint16_t property_value_count;
|
|
uint8_t property_values[513];
|
|
} __attribute__((packed));
|
|
uint8_t raw[523];
|
|
} e131_dmp_t;
|
|
|
|
|
|
// Table 4-1: E1.31 Data Packet
|
|
typedef union {
|
|
struct {
|
|
e131_rlp_t rlp;
|
|
e131_frame_t frame;
|
|
e131_dmp_t dmp;
|
|
} __attribute__((packed));
|
|
uint8_t raw[638];
|
|
} e131_packet_t;
|
|
|
|
|
|
typedef std::function<void(e131_packet_t *packet)> E131PacketHandlerFunction;
|
|
|
|
|
|
class ESPsACN {
|
|
public:
|
|
ESPsACN();
|
|
|
|
bool subscribe(uint16_t universe = 1);
|
|
static IPAddress E131MulticastAddress(uint16_t universe);
|
|
Universe * universe(uint16_t num) {
|
|
return universes_.at(num);
|
|
}
|
|
|
|
private:
|
|
e131_packet_t *buff_; // Pointer to scratch packet buffer
|
|
AsyncUDP udp; // AsyncUDP
|
|
|
|
// UDP packet parser callback
|
|
void parsePacket(AsyncUDPPacket);
|
|
|
|
std::unordered_map <uint16_t, Universe*> universes_;
|
|
};
|
|
|
|
#endif // SACN_H_
|