OTA broken LeaMDNS #2678

Closed
opened 2024-12-12 02:45:09 +03:00 by traxanos · 11 comments
traxanos commented 2024-12-12 02:45:09 +03:00 (Migrated from github.com)

Hello everyone,

I have a problem. I use LeaMDNS and OTA and that doesn't work anymore. The device hangs because you switched to SimpleMDNS in the OTA. Unfortunately SimpleMDNS can't do anything, so I can no longer maintain txt records with

MDNS.addServiceTxt()

Are there plans to extend SimpleMDNS in this respect or do I now have to choose between OTA or a proper MDNS?

Hello everyone, I have a problem. I use LeaMDNS and OTA and that doesn't work anymore. The device hangs because you switched to SimpleMDNS in the OTA. Unfortunately SimpleMDNS can't do anything, so I can no longer maintain txt records with ``` MDNS.addServiceTxt() ``` Are there plans to extend SimpleMDNS in this respect or do I now have to choose between OTA or a proper MDNS?
earlephilhower commented 2024-12-12 06:58:58 +03:00 (Migrated from github.com)

Is there some small complete function for setting up the MDNS that you're trying to do, to see if it can be done SimpleMDNS uses the basic LWIP implementation to avoid memory allocation and minimize overhead, but it does have some pretty big restrictions.

Alternatively, I suppose I'm not against reverting to LEAMDNS for ArduinoOTA. It was really my test case for the basic "get some MDNS working in FreeRTOS" and just sort of stuck because I didn't think anyone still using Arduino's OTA (vs. the web updaters) would be doing much real Bonjour stuff.

Or, if you can think of a way to select at compile-time between the two? If you're doing Platform.IO this might be the best and let advanced users pull in LEA + OTA while leaving the average user with the smaller footprint.

Is there some small complete function for setting up the MDNS that you're trying to do, to see if it can be done `SimpleMDNS` uses the basic LWIP implementation to avoid memory allocation and minimize overhead, but it does have some pretty big restrictions. Alternatively, I suppose I'm not against reverting to LEAMDNS for `ArduinoOTA`. It was really my test case for the basic "get some MDNS working in FreeRTOS" and just sort of stuck because I didn't think anyone still using Arduino's OTA (vs. the web updaters) would be doing much real Bonjour stuff. Or, if you can think of a way to select at compile-time between the two? If you're doing Platform.IO this might be the best and let advanced users pull in LEA + OTA while leaving the average user with the smaller footprint.
traxanos commented 2024-12-12 10:47:26 +03:00 (Migrated from github.com)

Hi, we are using PIO, so it would be conceivable to work with defines. The question is whether it wouldn’t make sense to extend SimpleMDNS. For example, enableArduino already creates TXT records. To avoid memory allocations, you could also work with callbacks, similar to how it is done internally. However, this would make it incompatible with the ESP, and I would have to provide two different implementations.

On the other hand, you would receive string/char pointers, so the memory overhead wouldn’t be that significant either.

But if I understood you correctly, the switch was made due to issues with FreeRTOS?

Hi, we are using PIO, so it would be conceivable to work with defines. The question is whether it wouldn’t make sense to extend SimpleMDNS. For example, enableArduino already creates TXT records. To avoid memory allocations, you could also work with callbacks, similar to how it is done internally. However, this would make it incompatible with the ESP, and I would have to provide two different implementations. On the other hand, you would receive string/char pointers, so the memory overhead wouldn’t be that significant either. But if I understood you correctly, the switch was made due to issues with FreeRTOS?
earlephilhower commented 2024-12-12 21:11:24 +03:00 (Migrated from github.com)

Please give #2679 a look. It implements basic MDNS TXT record addition without execution allocations. I don't really use MDNS, but the following sequence does seem to compile and run fine here and LeaMDNS

....
  ArduinoOTA.begin();

  MDNS.addService("satan", "tcp", 666);
  MDNS.addServiceTxt("satan", "light", "True");
  MDNS.addServiceTxt("satan", "number", (uint32_t)666);
  MDNS.addServiceTxt("satan", "floor", (int32_t)-9999);

But if I understood you correctly, the switch was made due to issues with FreeRTOS?

Yes, LWIP runs at IRQ time and calls back the main app when UDP packets come in. That's how we have no OS but still don't need an event pump in the main loop(). malloc in Newlib needs a recursive lock which is pedantically checked for in the FreeRTOS IRQ context. (In general you don't want to allow that kind of lock in an IRQ because the owner can be unclear. But in this instance, malloc is IRQ protected and it's not possible to have a real confusion in this core.)

Please give #2679 a look. It implements basic MDNS TXT record addition without execution allocations. I don't really use MDNS, but the following sequence does seem to compile and run fine here and LeaMDNS ```` .... ArduinoOTA.begin(); MDNS.addService("satan", "tcp", 666); MDNS.addServiceTxt("satan", "light", "True"); MDNS.addServiceTxt("satan", "number", (uint32_t)666); MDNS.addServiceTxt("satan", "floor", (int32_t)-9999); ```` > But if I understood you correctly, the switch was made due to issues with FreeRTOS? Yes, LWIP runs at IRQ time and calls back the main app when UDP packets come in. That's how we have no OS but still don't need an event pump in the main loop(). `malloc` in Newlib needs a recursive lock which is pedantically checked for in the FreeRTOS IRQ context. (In general you don't want to allow that kind of lock in an IRQ because the owner can be unclear. But in this instance, malloc is IRQ protected and it's not possible to have a real confusion in this core.)
traxanos commented 2024-12-12 21:27:45 +03:00 (Migrated from github.com)

i understand. pio is currently downloading. non releases versions took many time :D i will give you feedback if alle works

i understand. pio is currently downloading. non releases versions took many time :D i will give you feedback if alle works
traxanos commented 2024-12-12 21:38:46 +03:00 (Migrated from github.com)

this is roughly our structure and how it works. thanks

MDNS.begin(_hostName)
MDNS.addService("openknx", "tcp", -1);
MDNS.addServiceTxt("openknx", "tcp", "serial", openknx.info.humanSerialNumber().c_str());
MDNS.addServiceTxt("openknx", "tcp", "version", openknx.info.humanFirmwareVersion().c_str());
MDNS.addServiceTxt("openknx", "tcp", "firmware", openknx.info.humanFirmwareNumber().c_str());
MDNS.addServiceTxt("openknx", "tcp", "pa", openknx.info.humanIndividualAddress().c_str());
MDNS.enableArduino(2040 /* default port for ota */, false /* AUTH true / false */);
ArduinoOTA.setPort(2040);
ArduinoOTA.setRebootOnSuccess(false);
ArduinoOTA.onStart...
ArduinoOTA.onEnd...
ArduinoOTA.onProgress...
ArduinoOTA.onError...
ArduinoOTA.begin(false);

// loop
MDNS.update();
ArduinoOTA.handle();

ArduinoOTA.end();

we have separated mdns and arduinoota because we only activate & deactivate the ota when necessary-

PS: Do you know a tool with which I can do the OTA via UDP port 2040 (i.e. without http)? with the esp it is espota. or is it only possible via ardunio ide (which we do not use)?

this is roughly our structure and how it works. thanks ``` MDNS.begin(_hostName) MDNS.addService("openknx", "tcp", -1); MDNS.addServiceTxt("openknx", "tcp", "serial", openknx.info.humanSerialNumber().c_str()); MDNS.addServiceTxt("openknx", "tcp", "version", openknx.info.humanFirmwareVersion().c_str()); MDNS.addServiceTxt("openknx", "tcp", "firmware", openknx.info.humanFirmwareNumber().c_str()); MDNS.addServiceTxt("openknx", "tcp", "pa", openknx.info.humanIndividualAddress().c_str()); MDNS.enableArduino(2040 /* default port for ota */, false /* AUTH true / false */); ArduinoOTA.setPort(2040); ArduinoOTA.setRebootOnSuccess(false); ArduinoOTA.onStart... ArduinoOTA.onEnd... ArduinoOTA.onProgress... ArduinoOTA.onError... ArduinoOTA.begin(false); // loop MDNS.update(); ArduinoOTA.handle(); ArduinoOTA.end(); ``` we have separated mdns and arduinoota because we only activate & deactivate the ota when necessary- PS: Do you know a tool with which I can do the OTA via UDP port 2040 (i.e. without http)? with the esp it is espota. or is it only possible via ardunio ide (which we do not use)?
earlephilhower commented 2024-12-12 22:05:12 +03:00 (Migrated from github.com)

I believe your structure should work but because there is no "remove service" capability in the LWIP MDNS you may end up with multiple services of the same name and things going weird at that point (because enableArduino is called by OTA itself as part of ArduinoOTA::begin). That's easily protected against in the SimpleMDNS class. I'll put in a flag check and repush.

We use espota.py too because that's what I worked with on the ESP8266 Arduino core. It's installed in the source tree under tools/espota.py. Basically the same args as the 8266 one:

tools.uf2conv.upload.network_pattern="{network_cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin"
I believe your structure should work but because there is no "remove service" capability in the LWIP MDNS you may end up with multiple services of the same name and things going weird at that point (because enableArduino is called by OTA itself as part of ArduinoOTA::begin). That's easily protected against in the SimpleMDNS class. I'll put in a flag check and repush. We use `espota.py` too because that's what I worked with on the ESP8266 Arduino core. It's installed in the source tree under `tools/espota.py`. Basically the same args as the 8266 one: ```` tools.uf2conv.upload.network_pattern="{network_cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin" ````
earlephilhower commented 2024-12-12 22:11:59 +03:00 (Migrated from github.com)

Latest push should allow multiple starts of ArduinoOTA, please use that in testing.

Latest push should allow multiple starts of ArduinoOTA, please use that in testing.
traxanos commented 2024-12-12 22:17:32 +03:00 (Migrated from github.com)

no, i say that ardunioota is not allowed to make mdns by calling MDNS.begin(false). therefore _useMDNS == false.

i never understood why some classes think they have to implement something like that themselves. arduinoota should only do MDNS.enableArduino. but unfortunately esp does that too. that's why i switched off mdns in pico and esp and call MDNS.enableArduino myself.

no, i say that ardunioota is not allowed to make mdns by calling MDNS.begin(false). therefore _useMDNS == false. i never understood why some classes think they have to implement something like that themselves. arduinoota should only do MDNS.enableArduino. but unfortunately esp does that too. that's why i switched off mdns in pico and esp and call MDNS.enableArduino myself.
earlephilhower commented 2024-12-12 22:28:41 +03:00 (Migrated from github.com)

Gotcha. I didn't notice the begin(false) bit. In any case it doesn't hurt for the library to sanity check, so those will stay in. Do report any results when you get some, please.

Gotcha. I didn't notice the `begin(false)` bit. In any case it doesn't hurt for the library to sanity check, so those will stay in. Do report any results when you get some, please.
traxanos commented 2024-12-12 22:39:48 +03:00 (Migrated from github.com)

so my friend. everything works. mdns (enabledArduno + customs) and ota (by espota). perfect! now i just hope for a quick release :D thank you very much

so my friend. everything works. mdns (enabledArduno + customs) and ota (by espota). perfect! now i just hope for a quick release :D thank you very much
traxanos commented 2024-12-13 12:28:59 +03:00 (Migrated from github.com)

but again a small addendum. you are aware that your variant is not compatible with esp32, right? i thought that your way of writing would also work with esp32. unfortunately this is not the case.

i can make a case distinction. but if external libs want to set something like that, you unfortunately lose the game.

you must know this, but I wanted to mention it again to be on the safe side.

but again a small addendum. you are aware that your variant is not compatible with esp32, right? i thought that your way of writing would also work with esp32. unfortunately this is not the case. i can make a case distinction. but if external libs want to set something like that, you unfortunately lose the game. you must know this, but I wanted to mention it again to be on the safe side.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Max/earlephilhower_arduino-pico#2678