/* SPDX-License-Identifier: GPL-3.0-only */ #include #include #include #include #include #include #include typedef int esp_err_t; enum { ESP_OK = 0, ESP_FAIL = -1 }; typedef struct { int fd; bool invalid; } esp_tls_t; typedef struct { unsigned user_cb_state; esp_tls_t *tls; } esp_https_server_user_cb_arg_t; enum { HTTPD_SSL_USER_CB_SESS_CREATE, HTTPD_SSL_USER_CB_SESS_CLOSE }; typedef struct { void *handle; int fd; const char *uri, *headers, *body; } httpd_req_t; enum { HTTPD_WS_CLIENT_HTTP, HTTPD_WS_CLIENT_WEBSOCKET }; #define MALLOC_CAP_INTERNAL 1U #define MALLOC_CAP_8BIT 2U #define MALLOC_CAP_DMA 4U #define MALLOC_CAP_SPIRAM 8U #define portMUX_TYPE int #define portMUX_INITIALIZER_UNLOCKED 0 static bool locked, upgraded; static unsigned scans, calls, ws_queries; static int64_t clock_us = 1000; static void (*during_scan)(void), (*during_handler)(void), (*during_print)(void); static void lock(int *m) { (void)m; assert(!locked); locked = true; } static void unlock(int *m) { (void)m; assert(locked); locked = false; } #define portENTER_CRITICAL(m) lock(m) #define portEXIT_CRITICAL(m) unlock(m) static int64_t esp_timer_get_time(void) { assert(!locked); return clock_us; } static uint32_t heap_caps_get_free_size(uint32_t caps) { assert(!locked); ++scans; if (during_scan) { void (*hook)(void) = during_scan; during_scan = NULL; hook(); } return 10000 + caps; } static uint32_t heap_caps_get_largest_free_block(uint32_t caps) { assert(!locked); return 5000 + caps; } static uint32_t uxTaskGetStackHighWaterMark(void *task) { assert(!locked && !task); return 1234; } static esp_err_t esp_tls_get_conn_sockfd(esp_tls_t *tls, int *fd) { assert(!locked); *fd = tls->fd; return tls->invalid ? ESP_FAIL : ESP_OK; } static int httpd_req_to_sockfd(httpd_req_t *r) { assert(!locked); return r->fd; } static int httpd_ws_get_fd_info(void *handle, int fd) { assert(!locked && handle && fd >= 0); ++ws_queries; return upgraded ? HTTPD_WS_CLIENT_WEBSOCKET : HTTPD_WS_CLIENT_HTTP; } static esp_err_t handler_result; static esp_err_t handler(httpd_req_t *r) { assert(!locked && r->handle); ++calls; clock_us += 75; if (during_handler) { void (*hook)(void) = during_handler; during_handler = NULL; hook(); } return handler_result; } static esp_err_t ticket_handler(httpd_req_t *r) { return handler(r); } static esp_err_t websocket_handler(httpd_req_t *r) { return handler(r); } static esp_err_t web_admin_transport_ticket_handler(httpd_req_t *r) { return handler(r); } static esp_err_t web_admin_transport_upgrade_handler(httpd_req_t *r) { return handler(r); } static char output[65536]; static size_t output_size; static int capture_printf(const char *fmt, ...) { assert(!locked); va_list ap; va_start(ap, fmt); int count = vsnprintf(output + output_size, sizeof(output) - output_size, fmt, ap); va_end(ap); assert(count >= 0 && (size_t)count < sizeof(output) - output_size); output_size += count; if (during_print) { void (*hook)(void) = during_print; during_print = NULL; hook(); } return count; } #define printf capture_printf