2017-01-04 16:54:07 +00:00
mDNS Service
============
Overview
--------
mDNS is a multicast UDP service that is used to provide local network service and host discovery.
mDNS is installed by default on most operating systems or is available as separate package. On `` Mac OS `` it is installed by default and is called `` Bonjour `` . Apple releases an installer for `` Windows `` that can be found `on Apple's support page <https://support.apple.com/downloads/bonjour%2520for%2520windows> `_ . On `` Linux `` , mDNS is provided by `avahi <https://github.com/lathiat/avahi> `_ and is usually installed by default.
mDNS Properties
^^^^^^^^^^^^^^^
* `` hostname `` : the hostname that the device will respond to. If not set, the `` hostname `` will be read from the interface. Example: `` my-esp32 `` will resolve to `` my-esp32.local ``
* `` default_instance `` : friendly name for your device, like `` Jhon's ESP32 Thing `` . If not set, `` hostname `` will be used.
Example method to start mDNS for the STA interface and set `` hostname `` and `` default_instance `` :
2017-05-02 08:36:01 +00:00
.. highlight :: c
::
2017-01-04 16:54:07 +00:00
mdns_server_t * mdns = NULL;
void start_mdns_service()
{
//initialize mDNS service on STA interface
esp_err_t err = mdns_init(TCPIP_ADAPTER_IF_STA, &mdns);
if (err) {
printf("MDNS Init failed: %d\n", err);
return;
}
//set hostname
mdns_set_hostname(mdns, "my-esp32");
//set default instance
mdns_set_instance(mdns, "Jhon's ESP32 Thing");
}
mDNS Services
^^^^^^^^^^^^^
mDNS can advertise information about network services that your device offers. Each service is defined by a few properties.
* `` service `` : (required) service type, prepended with underscore. Some common types can be found `here <http://www.dns-sd.org/serviceTypes.html> `_ .
* `` proto `` : (required) protocol that the service runs on, prepended with underscore. Example: `` _tcp `` or `` _udp ``
* `` port `` : (required) network port that the service runs on
* `` instance `` : friendly name for your service, like `` Jhon's ESP32 Web Server `` . If not defined, `` default_instance `` will be used.
* `` txt `` : `` var=val `` array of strings, used to define properties for your service
2017-05-02 08:36:01 +00:00
Example method to add a few services and different properties::
2017-01-04 16:54:07 +00:00
void add_mdns_services()
{
//add our services
mdns_service_add(mdns, "_http", "_tcp", 80);
mdns_service_add(mdns, "_arduino", "_tcp", 3232);
mdns_service_add(mdns, "_myservice", "_udp", 1234);
//NOTE: services must be added before their properties can be set
//use custom instance for the web server
mdns_service_instance_set(mdns, "_http", "_tcp", "Jhon's ESP32 Web Server");
const char * arduTxtData[4] = {
"board=esp32",
"tcp_check=no",
"ssh_upload=no",
"auth_upload=no"
};
//set txt data for service (will free and replace current data)
mdns_service_txt_set(mdns, "_arduino", "_tcp", 4, arduTxtData);
//change service port
mdns_service_port_set(mdns, "_myservice", "_udp", 4321);
}
mDNS Query
^^^^^^^^^^
mDNS provides methods for browsing for services and resolving host's IP/IPv6 addresses.
2017-05-02 08:36:01 +00:00
Results are returned as a linked list of `` mdns_result_t `` objects. If the result is from host query, it will contain only `` addr `` and `` addrv6 `` if found. Service queries will populate all fields in a result that were found.
2017-01-04 16:54:07 +00:00
2017-05-02 08:36:01 +00:00
Example method to resolve host IPs::
2017-01-04 16:54:07 +00:00
void resolve_mdns_host(const char * hostname)
{
printf("mDNS Host Lookup: %s.local\n", hostname);
//run search for 1000 ms
if (mdns_query(mdns, hostname, NULL, 1000)) {
//results were found
const mdns_result_t * results = mdns_result_get(mdns, 0);
//itterate through all results
size_t i = 1;
while(results) {
//print result information
printf(" %u: IP:" IPSTR ", IPv6:" IPV6STR "\n", i++
IP2STR(&results->addr), IPV62STR(results->addrv6));
//load next result. Will be NULL if this was the last one
results = results->next;
}
//free the results from memory
mdns_result_free(mdns);
} else {
//host was not found
printf(" Host Not Found\n");
}
}
2017-05-02 08:36:01 +00:00
Example method to resolve local services::
2017-01-04 16:54:07 +00:00
void find_mdns_service(const char * service, const char * proto)
{
printf("mDNS Service Lookup: %s.%s\n", service, proto);
//run search for 1000 ms
if (mdns_query(mdns, service, proto, 1000)) {
//results were found
const mdns_result_t * results = mdns_result_get(mdns, 0);
//itterate through all results
size_t i = 1;
while(results) {
//print result information
printf(" %u: hostname:%s, instance:\"%s\", IP:" IPSTR ", IPv6:" IPV6STR ", port:%u, txt:%s\n", i++,
(results->host)?results->host:"NULL", (results->instance)?results->instance:"NULL",
IP2STR(&results->addr), IPV62STR(results->addrv6),
results->port, (results->txt)?results->txt:"\r");
//load next result. Will be NULL if this was the last one
results = results->next;
}
//free the results from memory
mdns_result_free(mdns);
} else {
//service was not found
printf(" Service Not Found\n");
}
}
2017-05-02 08:36:01 +00:00
Example of using the methods above::
2017-01-04 16:54:07 +00:00
void my_app_some_method(){
//search for esp32-mdns.local
resolve_mdns_host("esp32-mdns");
//search for HTTP servers
find_mdns_service("_http", "_tcp");
//or file servers
find_mdns_service("_smb", "_tcp"); //windows sharing
find_mdns_service("_afpovertcp", "_tcp"); //apple sharing
find_mdns_service("_nfs", "_tcp"); //NFS server
find_mdns_service("_ftp", "_tcp"); //FTP server
//or networked printer
find_mdns_service("_printer", "_tcp");
find_mdns_service("_ipp", "_tcp");
}
Application Example
-------------------
2017-01-19 08:16:06 +00:00
mDNS server/scanner example: :example: `protocols/mdns` .
2017-01-04 16:54:07 +00:00
API Reference
-------------
2017-05-02 08:36:01 +00:00
.. include :: /_build/inc/mdns.inc
2017-01-04 16:54:07 +00:00