diff --git a/wled00/data/common.js b/wled00/data/common.js index d2d69179..eb51eb93 100644 --- a/wled00/data/common.js +++ b/wled00/data/common.js @@ -187,7 +187,7 @@ function sendDDP(ws, start, len, colors) { pkt[0] = 0x02; // DDP protocol indicator for WLED websocket. Note: below DDP protocol bytes are offset by 1 pkt[1] = 0x40; // flags: 0x40 = no push, 0x41 = push (i.e. render), note: this is DDP protocol byte 0 pkt[2] = 0x00; // reserved - pkt[3] = 0x01; // 1 = RGB (currently only supported mode) + pkt[3] = 0x0B; // RGB, 8bit per channel pkt[4] = 0x01; // destination id (not used but 0x01 is default output) pkt[5] = (off >> 24) & 255; // DDP protocol 4-7 is offset pkt[6] = (off >> 16) & 255; diff --git a/wled00/e131.cpp b/wled00/e131.cpp index bec17d47..bf37fa4e 100644 --- a/wled00/e131.cpp +++ b/wled00/e131.cpp @@ -15,6 +15,14 @@ void handleDDPPacket(e131_packet_t* p) { static bool ddpSeenPush = false; // have we seen a push yet? [[maybe_unused]] int lastPushSeq = e131LastSequenceNumber[0]; + // reject unsupported color data types (only RGB and RGBW are supported) + // WLEDMM allow legacy "undefined" datatype, and legacy (but wrong) datatype=0x01 + if ( p->dataType != 0 && p->dataType != 0x01 && + p->dataType != DDP_TYPE_RGB24 && p->dataType != DDP_TYPE_RGBW32) return; + + // reject status and config packets (not implemented) + if (p->destination == DDP_ID_STATUS || p->destination == DDP_ID_CONFIG) return; + //reject late packets belonging to previous frame (assuming 4 packets max. before push) #if 0 // WLEDMM fixme - we definitely have more than 5-10 packets per frame !!! if (e131SkipOutOfSequence && lastPushSeq) { @@ -41,8 +49,8 @@ void handleDDPPacket(e131_packet_t* p) { uint16_t dataLen = htons(p->dataLen); unsigned stop = start + dataLen / ddpChannelsPerLed; uint8_t* data = p->data; - uint16_t c = 0; - if (p->flags & DDP_TIMECODE_FLAG) c = 4; //packet has timecode flag, we do not support it, but data starts 4 bytes later + unsigned c = 0; + if (p->flags & DDP_FLAGS_TIME) c = 4; //packet has timecode flag, we do not support it, but data starts 4 bytes later unsigned numLeds = stop - start; // stop >= start is guaranteed unsigned maxDataIndex = c + numLeds * ddpChannelsPerLed; // validate bounds before accessing data array @@ -67,7 +75,7 @@ void handleDDPPacket(e131_packet_t* p) { } } - bool push = p->flags & DDP_PUSH_FLAG; + bool push = p->flags & DDP_FLAGS_PUSH; ddpSeenPush |= push; if (!ddpSeenPush || push) { // if we've never seen a push, or this is one, render display #ifdef WLED_DEBUG diff --git a/wled00/src/dependencies/e131/ESPAsyncE131.h b/wled00/src/dependencies/e131/ESPAsyncE131.h index 40d7154e..e0ddccfd 100644 --- a/wled00/src/dependencies/e131/ESPAsyncE131.h +++ b/wled00/src/dependencies/e131/ESPAsyncE131.h @@ -49,13 +49,26 @@ typedef struct ip_addr ip4_addr_t; #define E131_DEFAULT_PORT 5568 #define ARTNET_DEFAULT_PORT 6454 #define DDP_DEFAULT_PORT 4048 +#define DDP_HEADER_LEN 10 +#define DDP_SYNCPACKET_LEN 10 -#define DDP_PUSH_FLAG 0x01 -#define DDP_TIMECODE_FLAG 0x10 +#define DDP_FLAGS_VER 0xc0 // version mask +#define DDP_FLAGS_VER1 0x40 // version=1 +#define DDP_FLAGS_PUSH 0x01 +#define DDP_FLAGS_QUERY 0x02 +#define DDP_FLAGS_REPLY 0x04 +#define DDP_FLAGS_STORAGE 0x08 +#define DDP_FLAGS_TIME 0x10 + +#define DDP_CHANNELS_PER_PACKET 1440 // 480 leds #define DDP_TYPE_RGB24 0x0B // 00 001 011 (RGB , 8 bits per channel, 3 channels) #define DDP_TYPE_RGBW32 0x1B // 00 011 011 (RGBW, 8 bits per channel, 4 channels) +#define DDP_ID_DISPLAY 1 +#define DDP_ID_CONFIG 250 +#define DDP_ID_STATUS 251 + #define ARTNET_OPCODE_OPDMX 0x5000 #define ARTNET_OPCODE_OPPOLL 0x2000 #define ARTNET_OPCODE_OPPOLLREPLY 0x2100 diff --git a/wled00/udp.cpp b/wled00/udp.cpp index bd2c37b1..614262e6 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -799,24 +799,6 @@ void sendSysInfoUDP() * Art-Net, DDP, E131 output - work in progress \*********************************************************************************************/ -#define DDP_HEADER_LEN 10 -#define DDP_SYNCPACKET_LEN 10 - -#define DDP_FLAGS1_VER 0xc0 // version mask -#define DDP_FLAGS1_VER1 0x40 // version=1 -#define DDP_FLAGS1_PUSH 0x01 -#define DDP_FLAGS1_QUERY 0x02 -#define DDP_FLAGS1_REPLY 0x04 -#define DDP_FLAGS1_STORAGE 0x08 -#define DDP_FLAGS1_TIME 0x10 - -#define DDP_ID_DISPLAY 1 -#define DDP_ID_CONFIG 250 -#define DDP_ID_STATUS 251 - -// 1440 channels per packet -#define DDP_CHANNELS_PER_PACKET 1440 // 480 leds - // // Send real time UDP updates to the specified client // @@ -885,11 +867,11 @@ uint8_t IRAM_ATTR_YN realtimeBroadcast(uint8_t type, IPAddress client, uint16_t // the amount of data is AFTER the header in the current packet size_t packetSize = DDP_CHANNELS_PER_PACKET; - uint8_t flags = DDP_FLAGS1_VER1; + uint8_t flags = DDP_FLAGS_VER1; if (currentPacket == (packetCount - 1U)) { // last packet, set the push flag // TODO: determine if we want to send an empty push packet to each destination after sending the pixel data - flags = DDP_FLAGS1_VER1 | DDP_FLAGS1_PUSH; + flags = DDP_FLAGS_VER1 | DDP_FLAGS_PUSH; if (channelCount % DDP_CHANNELS_PER_PACKET) { packetSize = channelCount % DDP_CHANNELS_PER_PACKET; } diff --git a/wled00/ws.cpp b/wled00/ws.cpp index 308a90c1..c4c837d8 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -100,7 +100,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp if (len < unsigned(10 + offset)) return; // DDP header is 10 bytes (+1 protocol byte) size_t ddpDataLen = (data[8+offset] << 8) | data[9+offset]; // data length in bytes from DDP header uint8_t flags = data[0+offset]; - if ((flags & DDP_TIMECODE_FLAG) ) ddpDataLen += 4; // timecode flag adds 4 bytes to data length + if ((flags & DDP_FLAGS_TIME) ) ddpDataLen += 4; // timecode flag adds 4 bytes to data length if (len < (10 + offset + ddpDataLen)) return; // not enough data, prevent out of bounds read // could be a valid DDP packet, forward to handler handleE131Packet((e131_packet_t*)&data[offset], client->remoteIP(), P_DDP);