Auto node discovery.

This commit is contained in:
Blaz Kristan
2021-01-22 16:17:18 +01:00
parent 0266370218
commit dd433d8af0
9 changed files with 601 additions and 393 deletions

View File

@@ -163,8 +163,32 @@ void handleNotifications()
if (!isSupp && notifierUdp.remoteIP() == Network.localIP()) return; //don't process broadcasts we send ourselves
uint8_t udpIn[packetSize +1];
if (isSupp) notifier2Udp.read(udpIn, packetSize);
else notifierUdp.read(udpIn, packetSize);
uint16_t len;
if (isSupp) len = notifier2Udp.read(udpIn, packetSize);
else len = notifierUdp.read(udpIn, packetSize);
// WLED nodes info notifications
if (isSupp && udpIn[0] == 255 && udpIn[1] == 1 && len >= 40) {
// IPAddress remoteIP = notifier2Udp.remoteIP();
uint8_t unit = udpIn[39];
Nodes[unit].age = 0; // Create a new element when not present
NodesMap::iterator it = Nodes.find(unit);
if (it != Nodes.end()) {
for (byte x = 0; x < 4; x++) {
it->second.ip[x] = udpIn[x + 2];
}
it->second.age = 0; // reset 'age counter'
char tmpNodeName[33] = { 0 };
memcpy(&tmpNodeName[0], reinterpret_cast<byte *>(&udpIn[6]), 32);
tmpNodeName[32] = 0;
it->second.nodeName = tmpNodeName;
it->second.nodeName.trim();
it->second.nodeType = udpIn[38];
}
return;
}
//wled notifier, ignore if realtime packets active
if (udpIn[0] == 0 && !realtimeMode && receiveNotifications)
@@ -349,3 +373,99 @@ void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
}
}
}
/*********************************************************************************************\
Refresh aging for remote units, drop if too old...
\*********************************************************************************************/
void refreshNodeList()
{
for (NodesMap::iterator it = Nodes.begin(); it != Nodes.end();) {
bool mustRemove = true;
if (it->second.ip[0] != 0) {
if (it->second.age < 10) {
it->second.age++;
mustRemove = false;
++it;
}
}
if (mustRemove) {
it = Nodes.erase(it);
}
}
}
/*********************************************************************************************\
Broadcast system info to other nodes. (to update node lists)
\*********************************************************************************************/
void sendSysInfoUDP(uint8_t repeats)
{
if (!udpConnected || !repeats) {
return;
}
IPAddress ip = WiFi.localIP();
// TODO: make a nice struct of it and clean up
// 0: 1 byte 'binary token 255'
// 1: 1 byte id '1'
// 2: 4 byte ip
// 6: 32 char name
// 38: 1 byte node type id
// 39: 1 byte node id
// 40 bytes total
// send my info to the world...
for (;repeats--;)
{
/*
escapedMac // mac address
*/
uint8_t data[40] = {0};
data[0] = 255;
data[1] = 1;
for (byte x = 0; x < 4; x++) {
data[x + 2] = ip[x];
}
memcpy((byte *)data + 6, serverDescription, 32);
#ifdef ESP8266
data[38] = NODE_TYPE_ID_ESP8266;
#elif defined(ARDUINO_ARCH_ESP32)
data[38] = NODE_TYPE_ID_ESP32;
#else
data[38] = NODE_TYPE_ID_UNDEFINED;
#endif
data[39] = ip[3]; // unit ID == last IP number
IPAddress broadcastIP(255, 255, 255, 255);
notifier2Udp.beginPacket(broadcastIP, udpPort2);
notifier2Udp.write(data, 40);
notifier2Udp.endPacket();
if (repeats) delay(500);
}
Nodes[ip[3]].age = 0; // Create new node when not already present.
// store my own info also in the list
NodesMap::iterator it = Nodes.find(ip[3]);
if (it != Nodes.end())
{
for (byte x = 0; x < 4; x++) {
it->second.ip[x] = ip[x];
}
it->second.age = 0;
it->second.nodeName = serverDescription;
#ifdef ESP8266
it->second.nodeType = NODE_TYPE_ID_ESP8266;
#elif defined(ARDUINO_ARCH_ESP32)
it->second.nodeType = NODE_TYPE_ID_ESP32;
#else
it->second.nodeType = NODE_TYPE_ID_UNDEFINED;
#endif
it->second.unit = ip[3];
}
}