Merge pull request #4859 from Liliputech/udp_name_sync_rework
new usermod hooks "onUdpPacket"
This commit is contained in:
5
usermods/udp_name_sync/library.json
Normal file
5
usermods/udp_name_sync/library.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "udp_name_sync",
|
||||
"build": { "libArchive": false },
|
||||
"dependencies": {}
|
||||
}
|
||||
85
usermods/udp_name_sync/udp_name_sync.cpp
Normal file
85
usermods/udp_name_sync/udp_name_sync.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "wled.h"
|
||||
|
||||
class UdpNameSync : public Usermod {
|
||||
|
||||
private:
|
||||
|
||||
bool enabled = false;
|
||||
char segmentName[WLED_MAX_SEGNAME_LEN] = {0};
|
||||
static constexpr uint8_t kPacketType = 200; // custom usermod packet type
|
||||
static const char _name[];
|
||||
static const char _enabled[];
|
||||
|
||||
public:
|
||||
/**
|
||||
* Enable/Disable the usermod
|
||||
*/
|
||||
inline void enable(bool value) { enabled = value; }
|
||||
|
||||
/**
|
||||
* Get usermod enabled/disabled state
|
||||
*/
|
||||
inline bool isEnabled() const { return enabled; }
|
||||
|
||||
void setup() override {
|
||||
// Enabled when this usermod is compiled, set to false if you prefer runtime opt-in
|
||||
enable(true);
|
||||
}
|
||||
|
||||
void loop() override {
|
||||
if (!enabled) return;
|
||||
if (!WLED_CONNECTED) return;
|
||||
if (!udpConnected) return;
|
||||
Segment& mainseg = strip.getMainSegment();
|
||||
if (segmentName[0] == '\0' && !mainseg.name) return; //name was never set, do nothing
|
||||
|
||||
const char* curName = mainseg.name ? mainseg.name : "";
|
||||
if (strncmp(curName, segmentName, sizeof(segmentName)) == 0) return; // same name, do nothing
|
||||
|
||||
IPAddress broadcastIp = uint32_t(Network.localIP()) | ~uint32_t(Network.subnetMask());
|
||||
byte udpOut[WLED_MAX_SEGNAME_LEN + 2];
|
||||
udpOut[0] = kPacketType; // custom usermod packet type (avoid 0..5 used by core protocols)
|
||||
|
||||
if (segmentName[0] != '\0' && !mainseg.name) { // name cleared
|
||||
notifierUdp.beginPacket(broadcastIp, udpPort);
|
||||
segmentName[0] = '\0';
|
||||
DEBUG_PRINTLN(F("UdpNameSync: sending empty name"));
|
||||
udpOut[1] = 0; // explicit empty string
|
||||
notifierUdp.write(udpOut, 2);
|
||||
notifierUdp.endPacket();
|
||||
return;
|
||||
}
|
||||
|
||||
notifierUdp.beginPacket(broadcastIp, udpPort);
|
||||
DEBUG_PRINT(F("UdpNameSync: saving segment name "));
|
||||
DEBUG_PRINTLN(curName);
|
||||
strlcpy(segmentName, curName, sizeof(segmentName));
|
||||
strlcpy((char *)&udpOut[1], segmentName, sizeof(udpOut) - 1); // leave room for header byte
|
||||
size_t nameLen = strnlen((char *)&udpOut[1], sizeof(udpOut) - 1);
|
||||
notifierUdp.write(udpOut, 2 + nameLen);
|
||||
notifierUdp.endPacket();
|
||||
DEBUG_PRINT(F("UdpNameSync: Sent segment name : "));
|
||||
DEBUG_PRINTLN(segmentName);
|
||||
return;
|
||||
}
|
||||
|
||||
bool onUdpPacket(uint8_t * payload, size_t len) override {
|
||||
DEBUG_PRINT(F("UdpNameSync: Received packet"));
|
||||
if (!enabled) return false;
|
||||
if (receiveDirect) return false;
|
||||
if (len < 2) return false; // need type + at least 1 byte for name (can be 0)
|
||||
if (payload[0] != kPacketType) return false;
|
||||
Segment& mainseg = strip.getMainSegment();
|
||||
char tmp[WLED_MAX_SEGNAME_LEN] = {0};
|
||||
size_t copyLen = len - 1;
|
||||
if (copyLen > sizeof(tmp) - 1) copyLen = sizeof(tmp) - 1;
|
||||
memcpy(tmp, &payload[1], copyLen);
|
||||
tmp[copyLen] = '\0';
|
||||
mainseg.setName(tmp);
|
||||
DEBUG_PRINT(F("UdpNameSync: set segment name"));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static UdpNameSync udp_name_sync;
|
||||
REGISTER_USERMOD(udp_name_sync);
|
||||
Reference in New Issue
Block a user