|
|
- /*
-
- MDNS MODULE
-
- Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com>
-
- */
-
- // -----------------------------------------------------------------------------
- // mDNS Server
- // -----------------------------------------------------------------------------
-
- #include "espurna.h"
-
- #if MDNS_SERVER_SUPPORT
-
- #include "mdns.h"
- #include "telnet.h"
- #include "utils.h"
- #include "web.h"
-
- #include <ESP8266mDNS.h>
-
- // -----------------------------------------------------------------------------
-
- namespace mdns {
- namespace {
-
- void addServices() {
- #if WEB_SUPPORT
- MDNS.addService("http", "tcp", webPort());
- #endif
-
- #if TELNET_SUPPORT
- MDNS.addService("telnet", "tcp", telnetPort());
- #endif
-
- #if OTA_ARDUINOOTA_SUPPORT
- // MDNS implementation has its weird way of accessing strings;
- // can't pass `String`s directly and must use a char pointer
- // to RAM so it could copy it for internal use via `strcpy`
- // Since all we use here is build data exposed with `StringView`s,
- // force everything in RAM first to avoid a runtime exception.
- if (MDNS.enableArduino(OTA_PORT, systemPassword().length() > 0)) {
- const auto app = buildApp();
- MDNS.addServiceTxt("arduino", "tcp",
- "app_name", String(app.name).c_str());
- MDNS.addServiceTxt("arduino", "tcp",
- "app_version", String(app.version).c_str());
- MDNS.addServiceTxt("arduino", "tcp",
- "build_date", String(app.build_time).c_str());
-
- MDNS.addServiceTxt("arduino", "tcp",
- "mac", String(systemChipId()).c_str());
- MDNS.addServiceTxt("arduino", "tcp",
- "target_board", String(systemDevice()).c_str());
-
- MDNS.addServiceTxt("arduino", "tcp", "mem_size",
- String(static_cast<int>(ESP.getFlashChipRealSize() / 1024), 10));
- MDNS.addServiceTxt("arduino", "tcp", "sdk_size",
- String(static_cast<int>(ESP.getFlashChipSize() / 1024), 10));
- MDNS.addServiceTxt("arduino", "tcp", "free_space",
- String(static_cast<int>(ESP.getFreeSketchSpace() / 1024), 10));
- }
- #endif
- }
-
- void start() {
- const auto hostname = systemHostname();
- if (MDNS.begin(hostname)) {
- DEBUG_MSG_P(PSTR("[MDNS] Started with hostname %s\n"), hostname.c_str());
- addServices();
- espurnaRegisterLoop([]() {
- MDNS.update();
- });
- return;
- }
-
- DEBUG_MSG_P(PSTR("[MDNS] ERROR\n"));
- }
-
- } // namespace
- } // namespace mdsn
-
- // As of right now, this needs to be request -> response operation in the same block,
- // so we don't end up using someone else's query results.
- // `queryService()` 3rd arg is timeout, by default it blocks for MDNS_QUERYSERVICES_WAIT_TIME (1000)
-
- // TODO: esp8266 allows async pyzeroconf-like API to have this running independently.
- // In case something other than MQTT needs this, consider extending the API
- // (and notice that RTOS SDK alternative would need to use mdns_query_* ESP-IDF API)
- // TODO: both implementations also have separate queries for A and AAAA records :/
-
- bool mdnsServiceQuery(const String& service, const String& protocol, MdnsServerQueryCallback callback) {
- bool result { false };
-
- auto found = MDNS.queryService(service, protocol);
- for (decltype(found) n = 0; n < found; ++n) {
- if (callback(MDNS.IP(n).toString(), MDNS.port(n))) {
- result = true;
- break;
- }
- }
-
- MDNS.removeQuery();
-
- return result;
- }
-
- bool mdnsRunning() {
- return MDNS.isRunning();
- }
-
- void mdnsServerSetup() {
- // 2.7.x and older require MDNS.begin() when interface is UP
- // issue tracker suggest doing begin() for each mode change, but...
- // this does seem to imply pairing it with end() (aka close()),
- // which will completely reset the MDNS object and require a setup once again.
- // this does not seem to work reliably :/ only support STA for the time being
- // 3.0.0 and newer only need to do MDNS.begin() once at setup()
- // however, note that without begin() call it will immediatly crash b/c
- // there are no sanity checks if it was actually called
- #if defined(ARDUINO_ESP8266_RELEASE_2_7_2) \
- || defined(ARDUINO_ESP8266_RELEASE_2_7_3) \
- || defined(ARDUINO_ESP8266_RELEASE_2_7_4)
-
- wifiRegister([](espurna::wifi::Event event) {
- if ((event == espurna::wifi::Event::StationConnected) && !MDNS.isRunning()) {
- mdns::start();
- }
- });
- #else
- mdns::start();
- #endif
- }
-
- #endif // MDNS_SERVER_SUPPORT
|