Skip to content

Commit

Permalink
Fix websocket crash
Browse files Browse the repository at this point in the history
  • Loading branch information
eandersson committed Sep 4, 2024
1 parent 74f78fe commit 1d4d71d
Showing 1 changed file with 47 additions and 18 deletions.
65 changes: 47 additions & 18 deletions main/http_server/http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static const char * TAG = "http_server";

static GlobalState * GLOBAL_STATE;
static httpd_handle_t server = NULL;
QueueHandle_t log_queue = NULL;

static int fd = -1;

Expand All @@ -48,6 +49,7 @@ static int fd = -1;

#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
#define SCRATCH_BUFSIZE (10240)
#define MESSAGE_QUEUE_SIZE (128)

typedef struct rest_server_context
{
Expand Down Expand Up @@ -534,12 +536,8 @@ esp_err_t POST_OTA_update(httpd_req_t * req)
return ESP_OK;
}

static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;

void log_to_websocket(const char * format, va_list args)
void log_to_queue(const char * format, va_list args)
{
pthread_mutex_lock(&log_mutex);

va_list args_copy;
va_copy(args_copy, args);

Expand All @@ -550,7 +548,6 @@ void log_to_websocket(const char * format, va_list args)
// Allocate the buffer dynamically
char * log_buffer = (char *) calloc(needed_size + 2, sizeof(char)); // +2 for potential \n and \0
if (log_buffer == NULL) {
pthread_mutex_unlock(&log_mutex);
return;
}

Expand All @@ -567,16 +564,25 @@ void log_to_websocket(const char * format, va_list args)
len++;
}

// Print to standard output
printf("%s", log_buffer);

if (xQueueSendToBack(log_queue, (void*)&log_buffer, (TickType_t) 0) != pdPASS) {
if (log_buffer != NULL) {
free((void*)log_buffer);
}
}
}

void send_log_to_websocket(char *message)
{
// Prepare the WebSocket frame
httpd_ws_frame_t ws_pkt;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.payload = (uint8_t *) log_buffer;
ws_pkt.len = len;
ws_pkt.payload = (uint8_t *)message;
ws_pkt.len = strlen(message);
ws_pkt.type = HTTPD_WS_TYPE_TEXT;

// Print to standard output
printf("%s", log_buffer);

// Ensure server and fd are valid
if (server != NULL && fd >= 0) {
// Send the WebSocket frame asynchronously
Expand All @@ -586,9 +592,7 @@ void log_to_websocket(const char * format, va_list args)
}

// Free the allocated buffer
free(log_buffer);

pthread_mutex_unlock(&log_mutex);
free((void*)message);
}

/*
Expand All @@ -597,14 +601,12 @@ void log_to_websocket(const char * format, va_list args)
*/
esp_err_t echo_handler(httpd_req_t * req)
{

if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Handshake done, the new connection was opened");
fd = httpd_req_to_sockfd(req);
esp_log_set_vprintf(log_to_websocket);
esp_log_set_vprintf(log_to_queue);
return ESP_OK;
}

return ESP_OK;
}

Expand All @@ -622,6 +624,29 @@ esp_err_t http_404_error_handler(httpd_req_t * req, httpd_err_code_t err)
return ESP_OK;
}

void websocket_log_handler()
{
while (true)
{
char *message;
if (xQueueReceive(log_queue, &message, (TickType_t) portMAX_DELAY) != pdPASS) {
if (message != NULL) {
free((void*)message);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
continue;
}

if (fd == -1) {
free((void*)message);
vTaskDelay(100 / portTICK_PERIOD_MS);
continue;
}

send_log_to_websocket(message);
}
}

esp_err_t start_rest_server(void * pvParameters)
{
GLOBAL_STATE = (GlobalState *) pvParameters;
Expand All @@ -639,6 +664,8 @@ esp_err_t start_rest_server(void * pvParameters)
REST_CHECK(rest_context, "No memory for rest context", err);
strlcpy(rest_context->base_path, base_path, sizeof(rest_context->base_path));

log_queue = xQueueCreate(MESSAGE_QUEUE_SIZE, sizeof(char*));

httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.uri_match_fn = httpd_uri_match_wildcard;
config.max_uri_handlers = 20;
Expand Down Expand Up @@ -711,8 +738,10 @@ esp_err_t start_rest_server(void * pvParameters)

httpd_register_err_handler(server, HTTPD_404_NOT_FOUND, http_404_error_handler);

// Start the DNS server that will redirect all queries to the softAP IP
// Start websocket log handler thread
xTaskCreate(&websocket_log_handler, "websocket_log_handler", 4096, NULL, 2, NULL);

// Start the DNS server that will redirect all queries to the softAP IP
dns_server_config_t dns_config = DNS_SERVER_CONFIG_SINGLE("*" /* all A queries */, "WIFI_AP_DEF" /* softAP netif ID */);
start_dns_server(&dns_config);

Expand Down

0 comments on commit 1d4d71d

Please sign in to comment.