diff --git a/app/src/lib/components/icons/index.ts b/app/src/lib/components/icons/index.ts index 91c13a2..3a26707 100644 --- a/app/src/lib/components/icons/index.ts +++ b/app/src/lib/components/icons/index.ts @@ -50,7 +50,7 @@ export { default as Power } from '~icons/tabler/power' export { default as MAC } from '~icons/tabler/dna-2' export { default as Home } from '~icons/tabler/home' export { default as SSID } from '~icons/tabler/router' -export { default as DNS } from '~icons/tabler/address-book' +export { default as DNS } from '~icons/mdi/dns' export { default as Gateway } from '~icons/tabler/torii' export { default as Subnet } from '~icons/tabler/grid-dots' export { default as Channel } from '~icons/tabler/antenna' diff --git a/app/src/lib/components/menu/Menu.svelte b/app/src/lib/components/menu/Menu.svelte index 90dd902..bee952c 100644 --- a/app/src/lib/components/menu/Menu.svelte +++ b/app/src/lib/components/menu/Menu.svelte @@ -19,7 +19,8 @@ Router, AP, Copyright, - Metrics + Metrics, + DNS } from '$lib/components/icons' import appEnv from 'app-env' @@ -103,6 +104,12 @@ icon: AP, href: '/wifi/ap', feature: true + }, + { + title: 'mDNS', + icon: DNS, + href: '/wifi/mdns', + feature: true } ] }, diff --git a/app/src/routes/wifi/mdns/+page.svelte b/app/src/routes/wifi/mdns/+page.svelte new file mode 100644 index 0000000..b0db4a6 --- /dev/null +++ b/app/src/routes/wifi/mdns/+page.svelte @@ -0,0 +1,7 @@ + + +
+ +
diff --git a/app/src/routes/wifi/mdns/MDNS.svelte b/app/src/routes/wifi/mdns/MDNS.svelte new file mode 100644 index 0000000..56f977b --- /dev/null +++ b/app/src/routes/wifi/mdns/MDNS.svelte @@ -0,0 +1,130 @@ + + + + {#snippet icon()} + + {/snippet} + {#snippet title()} + MDNS + {/snippet} + {#snippet right()} + + {/snippet} +
+ {#await getMDNSStatus()} + + {:then nothing} +
+ + + + + + + + + + + + + + + + + {#each services as service} + + + + + + + + {/each} + +
NameIp addressPort
{service.name}{service.ip}{service.port}
+
+ {/await} +
+
diff --git a/app/src/routes/wifi/mdns/MDNSSettings.svelte b/app/src/routes/wifi/mdns/MDNSSettings.svelte new file mode 100644 index 0000000..059facc --- /dev/null +++ b/app/src/routes/wifi/mdns/MDNSSettings.svelte @@ -0,0 +1,99 @@ + + +{#if settings} +
+ +
Configuration
+
+
+ + + +
+ + {#if isEditing} + + {/if} +
+
+
+
+{/if} diff --git a/esp32/lib/ESP32-sveltekit/filesystem.h b/esp32/lib/ESP32-sveltekit/filesystem.h index d7e23e6..3fdbb4f 100644 --- a/esp32/lib/ESP32-sveltekit/filesystem.h +++ b/esp32/lib/ESP32-sveltekit/filesystem.h @@ -12,6 +12,7 @@ #define DEVICE_CONFIG_FILE "/config/peripheral.json" #define WIFI_SETTINGS_FILE "/config/wifiSettings.json" #define SERVO_SETTINGS_FILE "/config/servoSettings.json" +#define MDNS_SETTINGS_FILE "/config/mdnsSettings.json" namespace FileSystem { extern PsychicUploadHandler *uploadHandler; diff --git a/esp32/lib/ESP32-sveltekit/mdns_service.cpp b/esp32/lib/ESP32-sveltekit/mdns_service.cpp new file mode 100644 index 0000000..92367d5 --- /dev/null +++ b/esp32/lib/ESP32-sveltekit/mdns_service.cpp @@ -0,0 +1,101 @@ +#include + +static const char *TAG = "MDNSService"; + +MDNSService::MDNSService() + : endpoint(MDNSSettings::read, MDNSSettings::update, this), + _persistence(MDNSSettings::read, MDNSSettings::update, this, MDNS_SETTINGS_FILE), + _started(false) { + addUpdateHandler([&](const String &originId) { reconfigureMDNS(); }, false); +} + +MDNSService::~MDNSService() { + if (_started) { + stopMDNS(); + } +} + +void MDNSService::begin() { + _persistence.readFromFS(); + startMDNS(); +} + +void MDNSService::reconfigureMDNS() { + if (_started) { + stopMDNS(); + } + startMDNS(); +} + +void MDNSService::startMDNS() { + ESP_LOGV(TAG, "Starting MDNS with hostname: %s", state().hostname.c_str()); + + if (MDNS.begin(state().hostname.c_str())) { + _started = true; + MDNS.setInstanceName(state().instance.c_str()); + + addServices(); + + ESP_LOGI(TAG, "MDNS started successfully with hostname: %s", state().hostname.c_str()); + } else { + _started = false; + ESP_LOGE(TAG, "Failed to start MDNS"); + } +} + +void MDNSService::stopMDNS() { + ESP_LOGV(TAG, "Stopping MDNS"); + MDNS.end(); + _started = false; +} + +void MDNSService::addServices() { + for (const auto &service : state().services) { + MDNS.addService(service.service.c_str(), service.protocol.c_str(), service.port); + + for (const auto &txt : service.txtRecords) { + MDNS.addServiceTxt(service.service.c_str(), service.protocol.c_str(), txt.key.c_str(), txt.value.c_str()); + } + } + + for (const auto &txt : state().globalTxtRecords) { + for (const auto &service : state().services) { + MDNS.addServiceTxt(service.service.c_str(), service.protocol.c_str(), txt.key.c_str(), txt.value.c_str()); + } + } +} + +esp_err_t MDNSService::getStatus(PsychicRequest *request) { + PsychicJsonResponse response = PsychicJsonResponse(request, false); + JsonObject root = response.getRoot(); + getStatus(root); + return response.send(); +} + +void MDNSService::getStatus(JsonObject &root) { + state().read(state(), root); + root["started"] = _started; +} + +esp_err_t MDNSService::queryServices(PsychicRequest *request, JsonVariant &json) { + String service = json["service"].as(); + String proto = json["protocol"].as(); + + PsychicJsonResponse response = PsychicJsonResponse(request, false); + JsonObject root = response.getRoot(); + + ESP_LOGI(TAG, "Querying for service: %s, protocol: %s", service.c_str(), proto.c_str()); + + int n = MDNS.queryService(service.c_str(), proto.c_str()); + ESP_LOGI(TAG, "Found %d services", n); + + JsonArray servicesArray = root["services"].to(); + for (int i = 0; i < n; i++) { + JsonObject serviceObj = servicesArray.add(); + serviceObj["name"] = MDNS.hostname(i); + serviceObj["ip"] = MDNS.IP(i); + serviceObj["port"] = MDNS.port(i); + } + + return response.send(); +} diff --git a/esp32/lib/ESP32-sveltekit/mdns_service.h b/esp32/lib/ESP32-sveltekit/mdns_service.h new file mode 100644 index 0000000..4800853 --- /dev/null +++ b/esp32/lib/ESP32-sveltekit/mdns_service.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include