Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mongoose on ESP32 and mg_broadcast support #782

Closed
nkolban opened this issue Feb 7, 2017 · 12 comments
Closed

Mongoose on ESP32 and mg_broadcast support #782

nkolban opened this issue Feb 7, 2017 · 12 comments

Comments

@nkolban
Copy link

nkolban commented Feb 7, 2017

Howdy folks, ... in a project I need to publish on a WebSocket when an event in my ESP32 occurs. I understand that I am not allowed to simply call mg_send_websocket_frame() in a separate task/thread and that makes sense. I am also of the understanding that the correct way to achieve my goal is to invoke mg_broadcast in my originating thread which will cause an event to be generated in my event handling loop where I can then perform the web socket send.

With this background ... I seem to find that mg_broadcast is disabled by default. I then changed my build process to define MG_ENABLE_BROADCAST and the mg_broadcast() function became present. However, I have not been able to get it to work. When I invoke mg_broadcast, no event is generated.

Is the mg_broadcast functionality working in the ESP32 port of the Mongoose networking library?

@cpq
Copy link
Member

cpq commented Feb 7, 2017

mg_broadcast() is using socketpair. A thread that sends a brodcasts writes to the one end of a socketpair, that wakes up and IO thread that reads from another end, and receives a message.

A socketpair is created using loopback, 127.0.0.1.

I have a suspicion that on ESP32, just like on ESP8266, the loopback is not enabled in LWIP. @rojer @alashkin do you have any more state on that?

@nkolban
Copy link
Author

nkolban commented Feb 7, 2017

When I tried to port Mongoose networking myself back in 2016 I found that 127.0.0.1 wasn't working ... see the following issue ... espressif/esp-idf#114

A poster to that thread claims that 0.0.0.0 works as does the local IP address.

In the ESP-IDF world, there are also other synchronization mechanisms including queues and semaphores at the FreeRTOS level.

If using a 127.0.0.1 socket pair isn't going to work easily on the ESP32, might we consider some ESP32/RTOS alternative mechanism defined at build time?

@nkolban
Copy link
Author

nkolban commented Jun 9, 2017

Was this issue ever resolved? Is "mg_broadcast" a supported function in ESP32 Mongoose networking?

What I have is a situation where, when I receive an incoming MG_EV_WEBSOCKET_FRAME event, I need to send back a response. I am under the belief that I can't invoke mg_send_websocket_frame() in the event handler that receives the MG_EV_WEBSOCKET_FRAME and hence am looking for a good design to achieve my goal.

@klapligehesten
Copy link

Hi Neil. Inspired by the book you wrote on the esp32, i've written a small project where i have worked my way around the above problem by using FreeRTOS queues.
see: https://github.com/klapligehesten/esp32_mg_web

@Eloquence4
Copy link

I can confirm that mg_broadcast works on ESP-IDF commit e7dc749e2f953a976325964b5ac49b53c8bafc42

@avanbremen
Copy link

avanbremen commented Feb 9, 2018

@cpq @Eloquence4 @nkolban Could you please share with me how you got mg_broadcast working? I believe the API is pretty straightforward, however I can't get mg_broadcast to work.

I am running a websocket server just fine and I am able to receive data without any issues. To test mg_broadcast (and make sure no other tasks were interfering), I simply created a second task in FreeRTOS which runs every 10 seconds (using vTaskDelay). For testing purposes I created a local (static) struct mg_mgr mgr; in the .c file, so that both tasks can access the Mongoose manager.

I noticed that the task is actually locking up. By adding several debug (ESP_LOGD / LOGI) statements, I was able to identify that mg_broadcast never returns. Within function mg_broadcast (mongoose.c), every function call returns up until the last one: dummy = MG_RECV_FUNC(mgr->ctl[0], (char *) &len, 1, 0);

The callback function that gets passed into mg_broadcast is even called, so we know that mg_mgr_poll wakes up and the callback function is called from within the mg_mgr_poll thread/task. However, MG_RECV_FUNC never returns. I did not make any changes to Mongoose (besides adding #define MG_ENABLE_BROADCAST 1 to enable mg_broadcast functionality), so MG_RECV_FUNC is simply mapped to recv (default).

I validated that LwIP loopback support is enabled, based on the issue @nkolban raised here. Since I did not make any changes to the default project config, loopback support is enabled.

It almost looks like it has something to do with the socketpair struct mg_mgr::ctl that's used to enable inter-process communication via mg_broadcast. But I can't figure out what's causing the function to block and thus lockup the entire task.

I am running Mongoose 6.11 and the latest version of ESP-IDF (I just pulled it from GitHub). I also tested with ESP-IDF v3.0-rc1, older versions of Mongoose, older versions of ESP-IDF and a combination of those.

@nkolban on a side note, I placed Mongoose in its own component folder. I tried defining MG_ENABLE_BROADCAST in the component makefile, using CFLAGS += -DMG_ENABLE_BROADCAST=1. Unfortunately that did not have any effect. When I place this into the project Makefile, it does work. I saw you ran into something similar, did you find a solution?

Thanks!

@Eloquence4
Copy link

Eloquence4 commented Feb 15, 2018

This is the example code i used to test mg_broadcast with: https://pastebin.com/tgV8ZcgL
I can't really test if the task deletes itself right now, i will comment back when i can.

@avanbremen
Copy link

@Eloquence4 thanks for your reply. I am currently working on a small example project that will demonstrate the issue. Perhaps you can spot an issue in the code. I will post asap.

@avanbremen
Copy link

avanbremen commented Feb 15, 2018

@cpq @Eloquence4 I just created a test project that demonstrates the issue, you can find it here. I assume the mg_broadcast callback is called 1 + N times, where N is the number of user sockets. I assume it's called for the loopback socket as well, hence the +1. Can you confirm?

I can also create a new issue, as this issue post dates back to 7 Feb 2017 and my issue is perhaps due to a newer version of Mongoose and/or ESP-IDF.

@avanbremen
Copy link

avanbremen commented Feb 17, 2018

Created a new issue here for clarity's sake.

Update 19-02-2018: The issue has been resolved.

@snahmad
Copy link

snahmad commented Aug 17, 2018

Not building for me linker error on esp32.

undefined reference to `mg_broadcast'

I have defined

#define MG_ENABLE_SYNC_RESOLVER 1
#define MG_ENABLE_BROADCAST 1
extern "C" {
#include "mongoose.h"
}

Any idea?

@cpq
Copy link
Member

cpq commented Dec 13, 2020

Closing this.

The latest code has diverted from the mg_broadcast concept. Instead, it provides a socketpair API for the inter-task comms. See an example at https://github.com/cesanta/mongoose/tree/master/examples/multi-threaded

@cpq cpq closed this as completed Dec 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants