Closed rickbassham closed 1 year ago
You are mixing unicast with broadcast and multicast. You are not just sending and receiving UDP, please change your subject. For examples on using multicast on an OS, see https://mongoose.ws/documentation/tutorials/udp-ssdp-search/ Then, you are mixing some OS networking stack with Mongoose built-in TCP/IP stack. Currently that stack does not support multicast (and probably neither broadcast). To do something like that, currently, you should choose a platform where lwIP works in socket mode (lwIP + FreeRTOS), in order to be able to replicate what you did in your OS; though this hasn't been tested either and YMMV. The current RP2040 + W5500 example does send and receive UDP (syncs time via SNTP, which runs on UDP), it just does not use broadcast nor multicast. Please do not post all the code, only relevant portions. What does not work ? Do you receive ? Can't you send ? Did you sniff your network ? Etc, Currently we are not planning to add support for broadcast nor multicast in Mongoose built-in stack, but if it is something simple we might consider adding it. What is your use case ?
I guess I was just trying to provide as much info as needed to show the issue. When using the OS stack, running on my Mac, my example code above works. When using the same relevant code, but using the Mongoose TCP/IP stack, I can receive the broadcast packet, but sending the response results in nothing going over the wire, verified with wireshark.
I'm likely just doing something wrong here, since the broadcast packet is received just fine, and just looking for some help getting this going. I like mongoose since it seems to be much more reliable and performant than a lot of other options out there, but if I can't get the discovery protocol working, I'll need to use something else.
My use case is implementing the ASCOM Alpaca discovery protocol, which sends a specific broadcast packet to the network and expects devices to respond if they implement the Alpaca protocol.
The broadcast is sent on port 32227 with alpacadiscovery1
as the packet contents. The expected return packet should contain a json string:
{"AlpacaPort":80}
Here is a link to a working example on an Arduino not using the Mongoose framework.
Currently that stack does not support multicast (and probably neither broadcast).
The Pico SDK works with lwIP, and we have an example on using the Pico W with FreeRTOS. You can still run Mongoose over lwIP over FreeRTOS, though we haven't tested UDP broadcast nor multicast in that architecture
Currently we are not planning to add support for broadcast nor multicast in Mongoose built-in stack, but if it is something simple we might consider adding it.
I would've expected the broadcast packet to go out but with the wrong destination MAC, can you check for that ? Our ARP algorithm is pretty simple and is probably trying to resolve the broadcast address. I would bet it is sending to the default gateway, can you check that ? The fix would be to add a corner case and just use a broadcast MAC for broadcast destinations. These from the top of my head, I haven't worked on the stack for some time now.
It seems to resolve the remote IP and port correctly when I log those here:
MG_INFO(("Alpaca %M %u", mg_print_ip_port, &(c->rem), c->is_udp));
mg_send(c, ALPACA_RESPONSE, 17);
Also, I'm not trying to send a broadcast via mongoose, I'm trying to reply to a broadcast packet I received. Not sure if I made that clear above
One more thing I've tried is establishing a new "connection" to send the udp packet response:
if (strncmp(c->recv.buf, "alpacadiscovery1", 16) == 0)
{
MG_INFO(("Alpaca %M %u", mg_print_ip_port, &(c->rem), c->is_udp));
char url[100];
memset(url, 0, sizeof(url));
mg_snprintf(url, sizeof(url), "udp://%M", mg_print_ip_port, &(c->rem));
mg_connect(c->mgr, url, alpaca_discover_send, NULL);
// mg_send(c, ALPACA_RESPONSE, 17);
}
static void alpaca_discover_send(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
MG_DEBUG(("Alpaca discover send %d", ev));
if (ev == MG_EV_RESOLVE)
{
mg_send(c, ALPACA_RESPONSE, 17);
c->is_draining = 1;
}
}
But this doesn't have anything sent either.
Also, I'm not trying to send a broadcast via mongoose, I'm trying to reply to a broadcast packet I received. Not sure if I made that clear above
No, I didn't get it, sorry about that.
You should be able to reply to a broadcast packet.
mg_connect()
should definitely send something
Did you try a working example for your hardware ? If so, and it worked, please post a network capture file, filter on your device MAC and broadcast MAC so we can try to see if something goes out. Do you know of any simulator or easy setup that we can try to quickly reproduce this ?
Here's an example working on the same hardware, using the Arduino framework and platformio.
https://gist.github.com/rickbassham/2912a558ec9cc8e0f86aa776503eb25c
I mean something using that protocol that can run on a computer
For the thing that sends the broadcast? if so, in python:
pip install alpyca
from alpaca.discovery import search_ipv4
found = search_ipv4()
print(found)
Relevant code for the search_ipv4
function is here.
If you look at your Wireshark captures, you should see the UDP response going out, though destination MAC is all zeroes. This shouldn't be so, we'll check
Just tested and this fix works. Thank you!
You're welcome! (I tested before submitting)
WRT MG_EV_RESOLVE: It is fired when resolving, that means you have to mg_connect to get that event, that is why you didn't get called.
Now you can also send local broadcasts and multicasts. Receiving multicast is not supported (yet?).
My goal is: To receive a UDP packet broadcast on the network, and respond if the UDP packet matches a filter.
My actions were:
Modified the captive-dns-server example to test locally. Worked. Updated the example to use the RP2040 and W5500. Doesn't work.
My expectation was: A UDP packet is sent properly across the network.
The result I saw:
Non-working log
Working log:
Working Code:
Non-working code:
Environment