diff options
| author | Luke Hoersten <[email protected]> | 2026-06-13 22:08:02 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-06-13 22:08:02 -0500 |
| commit | 4756daedaefd18919e96fadaabc7f1a00b383b4c (patch) | |
| tree | b2eeefb22f53673ac9437920d7447442a205fc8b /main/mdns_service.c | |
| parent | e2ac22e58901e18b0b567b85d93a8f68335180bc (diff) | |
M2: HTTP server + mDNS service discovery + shared state
- viewport_state.{h,c}: shared state struct (config, run-state, counters,
orientation, timestamps) behind a FreeRTOS mutex. Modules update it
under viewport_state_lock(); GET /state serializes a snapshot.
- http_api.{h,c}: starts esp_http_server on :80, registers GET /state.
Returns the full JSON shape from the spec (name, version, configured,
state, uptime_ms, last_frame_ms_ago, frames_received, decode_errors,
state_post_failures, resolution, ip, free_heap, free_psram).
- mdns_service.{h,c}: mdns_init + advertise _scrypted-viewport._tcp.local
on :80 with version/resolution/orientation/name TXT records.
mdns_service_refresh() reapplies hostname + TXT after /config writes
(called from M4 onward).
- main/CMakeLists.txt: add esp_http_server, esp_timer, json, mdns to
REQUIRES. espressif/mdns added as managed component via
main/idf_component.yml.
app_main calls viewport_state_init early so any module can read defaults
before /config arrives.
Also adds TESTING.md tracking per-milestone verification status and an
integration test plan to run after M9 (races, failure modes, longevity,
power cycles, negative protocol, multi-viewport).
M1 promoted to "🟡 builds clean" in TESTING.md; combined HW verification
of M1+M2 will be one flash session. Build verified against ESP-IDF 5.4
for target esp32p4 (binary ~550 KB).
Diffstat (limited to 'main/mdns_service.c')
| -rw-r--r-- | main/mdns_service.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/main/mdns_service.c b/main/mdns_service.c new file mode 100644 index 0000000..761ade5 --- /dev/null +++ b/main/mdns_service.c @@ -0,0 +1,65 @@ +#include "mdns_service.h" + +#include <stdio.h> +#include <string.h> + +#include "esp_check.h" +#include "esp_log.h" +#include "mdns.h" + +#include "viewport_state.h" + +static const char *TAG = "mdns"; +static const char *SERVICE = "_scrypted-viewport"; +static const char *PROTO = "_tcp"; +static const uint16_t PORT = 80; + +static esp_err_t apply_records(void) +{ + viewport_state_lock(); + viewport_state_t *st = viewport_state_get(); + + char hostname[80]; + if (st->viewport_name[0]) { + snprintf(hostname, sizeof(hostname), "viewport-%s", st->viewport_name); + } else { + snprintf(hostname, sizeof(hostname), "viewport"); + } + + const char *resolution = viewport_state_resolution_str(); + const char *orientation = (st->orientation == VIEWPORT_ORIENTATION_PORTRAIT) + ? "portrait" : "landscape"; + const char *name_value = st->viewport_name[0] ? st->viewport_name : ""; + + viewport_state_unlock(); + + mdns_txt_item_t txt[] = { + { "version", VIEWPORT_VERSION }, + { "resolution", resolution }, + { "orientation", orientation }, + { "name", name_value }, + }; + const size_t txt_count = sizeof(txt) / sizeof(txt[0]); + + ESP_RETURN_ON_ERROR(mdns_hostname_set(hostname), TAG, "hostname_set"); + ESP_RETURN_ON_ERROR(mdns_service_txt_set(SERVICE, PROTO, txt, txt_count), + TAG, "txt_set"); + + ESP_LOGI(TAG, "advertising %s.local on %s.%s.local:%u", + hostname, SERVICE, PROTO, PORT); + return ESP_OK; +} + +esp_err_t mdns_service_start(void) +{ + ESP_RETURN_ON_ERROR(mdns_init(), TAG, "mdns_init"); + ESP_RETURN_ON_ERROR( + mdns_service_add(NULL, SERVICE, PROTO, PORT, NULL, 0), + TAG, "service_add"); + return apply_records(); +} + +esp_err_t mdns_service_refresh(void) +{ + return apply_records(); +} |
