I want My ESP32 to send it's log messages over Wi-Fi. For this I register a uri handler that starts an async response. In principle, this works fine but it crashes at a random moment. Sometimes instantly when I connect, sometimes after several minutes. The core dump message is different. Most of the time is says LoadProhibited, but sometimes also LoadStoreAlignment or the ESP32 just freezes. Looks like something is really messed up.
Logging to UART with the same framework works fine and as long as I don't connect to api/log http is also stable.
/** Handler that will be registered on the httpd. */
esp_err_t uri_handler(httpd_req_t *r) {
addResponseHeaders(r);
DEBUG << "Sending log stream";
auto out = std::make_shared<httpd_req_t*>(nullptr);
const auto err = httpd_req_async_handler_begin(r, out.get());
if (err != ESP_OK || *out == nullptr) {
ERROR << "Failed to start async handler: " << esp_err_to_name(err);
return err;
}
auto receiverId = std::make_shared<int>(0);
/* Handler that will be registeres on the logging framework */
auto logReceiver = [out, receiverId] (Log::Level level, const char* tag, const char* file, int line, const std::string_view& message) {
if (*out) {
using namespace std;
string json = format(
R"({{"uptime":{},"level":{},"tag":"{}","file":"{}","line":{},"message":"{}"}})",
xTaskGetTickCount(), Log::levelName(level),
tag, file, line, message
);
if (httpd_resp_send_chunk(*out, json.data(), json.size()) != ESP_OK) {
Log::unregisterLogReceiver(*receiverId);
if (*out) {
httpd_req_async_handler_complete(*out);
}
*out = nullptr;
DEBUG << "Log stream closed";
}
} else {
Log::unregisterLogReceiver(*receiverId);
DEBUG << "Log stream closed unexpectedly";
}
};
*receiverId = Log::registerLogReceiver(logReceiver);
return ESP_OK;
}
/** Will be called at program start. */
void registerLogHandler() {
httpd_uri_t httpd_uri = {
.uri = "/api/log",
.method = HTTP_GET,
.handler = &uri_handler,
.user_ctx = nullptr,
.is_websocket = false};
auto result = httpd_register_uri_handler(HttpServer::handle, &httpd_uri);
}
I have seen the espressif example but don't see any difference except that the whole application architecture is different.
using namespace std;andstd::make_shared<httpd_req_t*>(nullptr);mixed in the function work? If you are using ESP32-Arduino (which is in C++), then look into ESPAsyncWebServer and tag your question asarduino-esp32instead ofesp-idf.