forked from forkineye/ESPixelStick
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ESPAsyncDDP.cpp
101 lines (87 loc) · 2.63 KB
/
ESPAsyncDDP.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* ESPAsyncDDP.cpp
*
* Project: ESPAsyncDDP - Asynchronous DDP library for Arduino ESP8266 and ESP32
* Copyright (c) 2019 Daniel Kulp
*
* This program is provided free for you to use in any way that you wish,
* subject to the laws and regulations where you are using it. Due diligence
* is strongly suggested before using this code. Please give credit where due.
*
* The Author makes no warranty of any kind, express or implied, with regard
* to this program or the documentation contained in this document. The
* Author shall not be liable in any event for incidental or consequential
* damages in connection with, or arising out of, the furnishing, performance
* or use of these programs.
*
*/
#include "ESPAsyncDDP.h"
#include <string.h>
// Constructor
ESPAsyncDDP::ESPAsyncDDP(uint8_t buffers) {
pbuff = RingBuf_new(sizeof(DDP_packet_t), buffers);
lastSequenceSeen = 0;
stats.packetsReceived = 0;
stats.bytesReceived = 0;
stats.errors = 0;
stats.ddpMinChannel = 9999999;
stats.ddpMaxChannel = 0;
}
/////////////////////////////////////////////////////////
//
// Public begin() members
//
/////////////////////////////////////////////////////////
bool ESPAsyncDDP::begin(IPAddress ourIP) {
return initUDP(ourIP);
}
/////////////////////////////////////////////////////////
//
// Private init() members
//
/////////////////////////////////////////////////////////
bool ESPAsyncDDP::initUDP(IPAddress ourIP) {
bool success = false;
delay(100);
if (udp.listen(DDP_PORT)) {
udp.onPacket(std::bind(&ESPAsyncDDP::parsePacket, this,
std::placeholders::_1));
success = true;
}
return success;
}
/////////////////////////////////////////////////////////
//
// Packet parsing - Private
//
/////////////////////////////////////////////////////////
void ESPAsyncDDP::parsePacket(AsyncUDPPacket _packet) {
sbuff = reinterpret_cast<DDP_packet_t *>(_packet.data());
pbuff->add(pbuff, sbuff);
stats.packetsReceived++;
stats.bytesReceived += _packet.length();
int sn = sbuff->header.sequenceNum & 0xF;
if (sn) {
bool isErr = false;
if (lastSequenceSeen) {
if (sn == 1) {
if (lastSequenceSeen != 15) {
isErr = true;
}
} else if ((sn - 1) != lastSequenceSeen) {
isErr = true;
}
}
if (isErr) {
stats.errors++;
}
lastSequenceSeen = sn;
}
if (stats.ddpMinChannel > htonl(sbuff->header.channelOffset)) {
stats.ddpMinChannel = htonl(sbuff->header.channelOffset);
}
int mc = htonl(sbuff->header.channelOffset) + htons(sbuff->header.dataLen);
if (mc > stats.ddpMaxChannel) {
stats.ddpMaxChannel = mc;
}
}