Quando navighiamo su Internet, il servizio DNS (Domain Name System) si occupa di “tradurre” (risolvere) i nomi nei corrispettivi indirizzi IP.
Se ad esempio digitiamo www.google.com nel nostro browser, il nostro computer interroga il server DNS – normalmente quello messo a disposizione dal nostro provider – e ottiene da questo l’indirizzo IP del server che ospita il sito di Google:
Una rete locale casalinga spesso non dispone di un server DNS, quindi per poter comunicare con un dispositivo è necessario conoscere il suo indirizzo IP. Sapere quale indirizzo IP ha un dispositivo è semplice se tale indirizzo viene assegnato in maniera statica oppure se il dispositivo stesso ha un display dove lo visualizza:
Al contrario, se l’indirizzo IP viene assegnato in maniera dinamica (ad esempio dal server DHCP del nostro router) e il dispositivo non lo visualizza, può essere complicato recuperarlo. Ci può venire in aiuto il protocollo Multicast DNS (mDNS), vediamo come utilizzarlo con il chip esp32.
mDNS
mDNS è un protocollo di rete, definito nella RFC6762, che consente la risoluzione di nomi in indirizzi IP senza la necessità della presenza di un server DNS all’interno della rete.
Il suo funzionamento è molto semplice. Quando un dispositivo ha la necessità di conoscere l’indirizzo IP di un altro dispositivo in rete invia un pacchetto UDP multicast con la richiesta; il pacchetto, essendo multicast, raggiunge tutti i dispositivi connessi. La risposta viene inviata sempre in multicast in modo che tutti la ricevano:
Di default, mDNS risolve nomi che terminano con il suffisso .local.
ESP32
Il framework esp-idf include un componente che implementa il protocollo mDNS; in questo tutorial vi mostrerò come utilizzarlo per rispondere a richieste mDNS. L’esempio completo è disponibile nel mio repository Github; vediamone gli elementi principali.
Per prima cosa, via menuconfig è possibile configurare due parametri:
MDNS_HOSTNAME è il nome al quale risponderà il nostro chip esp32 (ad esempio “esp32“) mentre MDNS_INSTANCE è una descrizione del dispositivo (es. “ESP32 Demo Board“).
L’utilizzo del server mDNS che risponde alle queries è molto semplice. Una volta effettuata la connessione alla rete wifi (il programma riprende un mio esempio precedente) è sufficiente creare una nuova istanza del server e configurarlo con i parametri sopra definiti:
// mDNS server instance mdns_server_t* mDNS = NULL; [...] // create and configure the mDNS server ESP_ERROR_CHECK(mdns_init(TCPIP_ADAPTER_IF_STA, &mDNS)); ESP_ERROR_CHECK(mdns_set_hostname(mDNS, CONFIG_MDNS_HOSTNAME)); ESP_ERROR_CHECK(mdns_set_instance(mDNS, CONFIG_MDNS_INSTANCE)); |
Non dimentichiamoci di includere l’header del componente all’inizio del nostro programma:
#include "mdns.h" |
Tutto qui! Una volta eseguito il programma, il server mDNS rimarrà in ascolto e, alla ricezione di richieste per il nome MDNS_HOSTNAME.local, risponderà con l’indirizzo IP della scheda esp32.
mDNS per Windows e Linux
Per poter effettuare un test, il nostro PC deve essere in grado di “parlare” il protocollo mDNS.
Se stiamo utilizzando Windows, possiamo installare l’applicativo Bonjour Print Services di Apple. Sebbene pensato per effettuare discovery e configurazioni di stampanti (da qui il nome), in realtà tale servizio supporta in generale il protocollo mDNS ed è quindi la soluzione migliore in ambiente Microsoft.
Per Linux esiste il daemon Avahi, spesso già installato nelle distribuzioni più diffuse.
Una volta predisposto il nostro PC, possiamo provare il funzionamento del programma con un semplice ping esp32.local (sostituendo il nome che avete configurato):
Conclusioni
L’utilizzo del componente mDNS consente di realizzare dispositivi, basati sul chip esp32, facilmente identificabili via rete, senza necessità di dotarli di un display o di un collegamento seriale. Inoltre, è sicuramente più semplice – soprattutto per utenti non esperti – utilizzare un nome ben noto (“esp32.local”) invece che dover andare alla ricerca di uno “strano numero” (l’indirizzo IP) che può addirittura cambiare nel tempo.
In questo tutorial abbiamo visto solo come rispondere a query mDNS: questo è sicuramente l’utilizzo più comune ma non è il solo: il componente del framework consente infatti di inviare richieste o di pubblicare diversi servizi… Espressif ha reso disponibile un programma di esempio che esplora alcune di queste features.
Hi Luca.
I try to compile this example (09_mdns) direct download from your GIT, but I don’t be able to do the “make”.
“uknown type ‘mdns_server_t'”.
In you GIT example, where is locate the “mdns.h”?
Thanks a lot.
Hi Sergi, unfortunately ESP changed the way they handle the mDNS component, I have to change my code accordingly
Hi Luca,
For resolve the problem you need to make the following:
// mdns_server_t* mDNS = NULL;
// ESP_ERROR_CHECK(mdns_init(TCPIP_ADAPTER_IF_STA, &mDNS));
// ESP_ERROR_CHECK(mdns_set_hostname(mDNS, “esp32”));
// ESP_ERROR_CHECK(mdns_set_instance(mDNS, “Basic HTTP Server”));
ESP_ERROR_CHECK(mdns_init());
ESP_ERROR_CHECK(mdns_hostname_set(“esp32”));
ESP_ERROR_CHECK(mdns_instance_name_set(“Basic HTTP Server”));
This is actual for 3 your samples.
thanks! I’ll update my examples accordingly
Ciao Luca,
sto lavorando su VirtualBox – Ubuntu e ho questo errore: “ping: esp32.local: Name or service not known”
Può essere dovuto al fatto che sono su macchina virtuale o sbaglio altro?
ciao Angelo, non so se Ubuntu ha incluso Avahi… ti serve per poter gestire mDNS