Skip to content

Commit 27b27af

Browse files
committed
Fix nRF52 AsyncUDP multicast TX/RX race condition causing garbled packets
socketSendUDP() calls yield() while waiting for SEND_OK, allowing the cooperative scheduler to run AsyncUDP::runOnce(). When runOnce() calls parsePacket() on the same socket during an active send, the multicast loopback packet arriving from the switch produces a garbled 8-byte RX header (wrong source IP, wrong payload length), leading to protobuf decode errors in UdpMulticastHandler. Add a volatile isSending flag that writeTo() sets around the send operation. runOnce() checks this flag and skips parsePacket() while a send is in progress. Loopback packets stay buffered in the W5100S RX buffer and are read cleanly on the next poll cycle. Made-with: Cursor
1 parent 3a74e04 commit 27b27af

2 files changed

Lines changed: 9 additions & 3 deletions

File tree

src/platform/nrf52/AsyncUDP.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ void AsyncUDP::onPacket(const std::function<void(AsyncUDPPacket)> &callback)
3030

3131
bool AsyncUDP::writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port)
3232
{
33-
if (!udp.beginPacket(ip, port))
33+
isSending = true;
34+
if (!udp.beginPacket(ip, port)) {
35+
isSending = false;
3436
return false;
37+
}
3538
udp.write(data, len);
36-
return udp.endPacket();
39+
bool ok = udp.endPacket();
40+
isSending = false;
41+
return ok;
3742
}
3843

3944
void AsyncUDP::close()
@@ -70,7 +75,7 @@ const uint8_t *AsyncUDPPacket::data()
7075

7176
int32_t AsyncUDP::runOnce()
7277
{
73-
if (_onPacket && udp.parsePacket() > 0) {
78+
if (_onPacket && !isSending && udp.parsePacket() > 0) {
7479
AsyncUDPPacket packet(udp);
7580
_onPacket(packet);
7681
}

src/platform/nrf52/AsyncUDP.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class AsyncUDP : public Print, private concurrency::OSThread
3131
private:
3232
EthernetUDP udp;
3333
uint16_t localPort;
34+
volatile bool isSending = false;
3435
std::function<void(AsyncUDPPacket)> _onPacket;
3536
virtual int32_t runOnce() override;
3637
};

0 commit comments

Comments
 (0)