mDNS Service - ESP32 - — ESP-Protocols latest documentation (original) (raw)

[中文]

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. On Linux, mDNS is provided by avahi and is usually installed by default.

mDNS Properties

Example method to start mDNS for the STA interface and set hostname and default_instance:

void start_mdns_service() { //initialize mDNS service esp_err_t err = mdns_init(); if (err) { printf("MDNS Init failed: %d\n", err); return; }

//set hostname
mdns_hostname_set("my-esp32");
//set default instance
mdns_instance_name_set("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.

Please note:

  1. Self-querying names is not supported in Espressif’s mDNS library, a deliberate design choice to simplify implementation, preventing local network pollution and addressing WiFi multicast behavior)
  2. Setting your own hostname is a prerequisite(mandatory) for advertising services or delegating other names.

Example method to add a few services and different properties:

void add_mdns_services() { //add our services mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0); mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0); mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);

//NOTE: services must be added before their properties can be set
//use custom instance for the web server
mdns_service_instance_name_set("_http", "_tcp", "Jhon's ESP32 Web Server");

mdns_txt_item_t serviceTxtData[3] = {
    {"board","{esp32}"},
    {"u","user"},
    {"p","password"}
};
//set txt data for service (will free and replace current data)
mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);

//change service port
mdns_service_port_set("_myservice", "_udp", 4321);

}

mDNS Query

mDNS provides methods for browsing for services and resolving host’s IP/IPv6 addresses.

Results for services are returned as a linked list of mdns_result_t objects.

Example method to resolve host IPs:

void resolve_mdns_host(const char * host_name) { printf("Query A: %s.local", host_name);

struct ip4_addr addr;
addr.addr = 0;

esp_err_t err = mdns_query_a(host_name, 2000,  &addr);
if(err){
    if(err == ESP_ERR_NOT_FOUND){
        printf("Host was not found!");
        return;
    }
    printf("Query Failed");
    return;
}

printf(IPSTR, IP2STR(&addr));

}

Example method to resolve local services:

static const char * if_str[] = {"STA", "AP", "ETH", "MAX"}; static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};

void mdns_print_results(mdns_result_t * results){ mdns_result_t * r = results; mdns_ip_addr_t * a = NULL; int i = 1, t; while(r){ printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]); if(r->instance_name){ printf(" PTR : %s\n", r->instance_name); } if(r->hostname){ printf(" SRV : %s.local:%u\n", r->hostname, r->port); } if(r->txt_count){ printf(" TXT : [%u] ", r->txt_count); for(t=0; ttxt_count; t++){ printf("%s=%s; ", r->txt[t].key, r->txt[t].value); } printf("\n"); } a = r->addr; while(a){ if(a->addr.type == IPADDR_TYPE_V6){ printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6)); } else { printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4))); } a = a->next; } r = r->next; }

}

void find_mdns_service(const char * service_name, const char * proto) { ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);

mdns_result_t * results = NULL;
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20,  &results);
if(err){
    ESP_LOGE(TAG, "Query Failed");
    return;
}
if(!results){
    ESP_LOGW(TAG, "No results found!");
    return;
}

mdns_print_results(results);
mdns_query_results_free(results);

}

Example of using the methods above:

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");

}

Performance Optimization

Execution Speed

Please check Maximizing Execution Speed for more details.

Minimizing RAM Usage

Please check Minimizing RAM Usage for more details.

Application Example

mDNS server/scanner example

API Reference

Functions

esp_err_t mdns_init(void)

Initialize mDNS on given interface.

Returns:

void mdns_free(void)

Stop and free mDNS server.

esp_err_t mdns_hostname_set(const char *hostname)

Set the hostname for mDNS server required if you want to advertise services.

Parameters:

hostname – Hostname to set

Returns:

esp_err_t mdns_hostname_get(char *hostname)

Get the hostname for mDNS server.

Parameters:

hostname – pointer to the hostname, it should be allocated and hold at least MDNS_NAME_BUF_LEN chars

Returns:

esp_err_t mdns_delegate_hostname_add(const char *hostname, const mdns_ip_addr_t *address_list)

Adds a hostname and address to be delegated A/AAAA queries will be replied for the hostname and services can be added to this host.

Parameters:

Returns:

esp_err_t mdns_delegate_hostname_set_address(const char *hostname, const mdns_ip_addr_t *address_list)

Set the address to a delegated hostname.

Parameters:

Returns:

esp_err_t mdns_delegate_hostname_remove(const char *hostname)

Remove a delegated hostname All the services added to this host will also be removed.

Parameters:

hostname – Hostname to remove

Returns:

bool mdns_hostname_exists(const char *hostname)

Query whether a hostname has been added.

Parameters:

hostname – Hostname to query

Returns:

esp_err_t mdns_instance_name_set(const char *instance_name)

Set the default instance name for mDNS server.

Parameters:

instance_name – Instance name to set

Returns:

esp_err_t mdns_service_add(const char *instance_name, const char *service_type, const char *proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items)

Add service to mDNS server.

Note

The value length of txt items will be automatically decided by strlen

Parameters:

Returns:

esp_err_t mdns_service_add_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items)

Add service to mDNS server with a delegated hostname.

Note

The value length of txt items will be automatically decided by strlen

Parameters:

Returns:

bool mdns_service_exists(const char *service_type, const char *proto, const char *hostname)

Check whether a service has been added.

Parameters:

Returns:

bool mdns_service_exists_with_instance(const char *instance, const char *service_type, const char *proto, const char *hostname)

Check whether a service has been added.

Parameters:

Returns:

esp_err_t mdns_service_remove(const char *service_type, const char *proto)

Remove service from mDNS server.

Parameters:

Returns:

esp_err_t mdns_service_remove_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname)

Remove service from mDNS server with hostname.

Parameters:

Returns:

esp_err_t mdns_service_instance_name_set(const char *service_type, const char *proto, const char *instance_name)

Set instance name for service.

Parameters:

Returns:

esp_err_t mdns_service_instance_name_set_for_host(const char *instance_old, const char *service_type, const char *proto, const char *hostname, const char *instance_name)

Set instance name for service with hostname.

Parameters:

Returns:

esp_err_t mdns_service_port_set(const char *service_type, const char *proto, uint16_t port)

Set service port.

Parameters:

Returns:

esp_err_t mdns_service_port_set_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname, uint16_t port)

Set service port with hostname.

Parameters:

Returns:

esp_err_t mdns_service_txt_set(const char *service_type, const char *proto, mdns_txt_item_t txt[], uint8_t num_items)

Replace all TXT items for service.

Note

The value length of txt items will be automatically decided by strlen

Parameters:

Returns:

esp_err_t mdns_service_txt_set_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname, mdns_txt_item_t txt[], uint8_t num_items)

Replace all TXT items for service with hostname.

Note

The value length of txt items will be automatically decided by strlen

Parameters:

Returns:

esp_err_t mdns_service_txt_item_set(const char *service_type, const char *proto, const char *key, const char *value)

Set/Add TXT item for service TXT record.

Note

The value length will be automatically decided by strlen

Parameters:

Returns:

esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service_type, const char *proto, const char *key, const char *value, uint8_t value_len)

Set/Add TXT item for service TXT record.

Parameters:

Returns:

esp_err_t mdns_service_txt_item_set_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname, const char *key, const char *value)

Set/Add TXT item for service TXT record with hostname.

Note

The value length will be automatically decided by strlen

Parameters:

Returns:

esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *instance, const char *service_type, const char *proto, const char *hostname, const char *key, const char *value, uint8_t value_len)

Set/Add TXT item for service TXT record with hostname and txt value length.

Parameters:

Returns:

esp_err_t mdns_service_txt_item_remove(const char *service_type, const char *proto, const char *key)

Remove TXT item for service TXT record.

Parameters:

Returns:

esp_err_t mdns_service_txt_item_remove_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname, const char *key)

Remove TXT item for service TXT record with hostname.

Parameters:

Returns:

esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype)

Add a subtype for service.

Parameters:

Returns:

esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, const char *subtype)

Remove a subtype for service.

Parameters:

Returns:

esp_err_t mdns_service_subtype_add_multiple_items_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items)

Add multiple subtypes for service at once.

Parameters:

Returns:

esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instance_name, const char *service_type, const char *proto, const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items)

Update subtype for service.

Note

If num_items is 0, then remove all subtypes.

Parameters:

Returns:

esp_err_t mdns_service_remove_all(void)

Remove and free all services from mDNS server.

Returns:

esp_err_t mdns_query_async_delete(mdns_search_once_t *search)

Deletes the finished query. Call this only after the search has ended!

Parameters:

search – pointer to search object

Returns:

bool mdns_query_async_get_results(mdns_search_once_t *search, uint32_t timeout, mdns_result_t **results, uint8_t *num_results)

Get results from search pointer. Results available as a pointer to the output parameter. Pointer to search object has to be deleted via mdns_query_async_delete once the query has finished. The results although have to be freed manually.

Parameters:

Returns:

True if search has finished before or at timeout False if search timeout is over

mdns_search_once_t *mdns_query_async_new(const char *name, const char *service_type, const char *proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_query_notify_t notifier)

Query mDNS for host or service asynchronousely. Search has to be tested for progress and deleted manually!

Parameters:

Returns:

mdns_search_once_s pointer to new search object if query initiated successfully. NULL otherwise.

esp_err_t mdns_query_generic(const char *name, const char *service_type, const char *proto, uint16_t type, mdns_query_transmission_type_t transmission_type, uint32_t timeout, size_t max_results, mdns_result_t **results)

Generic mDNS query All following query methods are derived from this one.

Parameters:

Returns:

esp_err_t mdns_query(const char *name, const char *service_type, const char *proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t **results)

Query mDNS for host or service.

Note that querying PTR types sends Multicast query, all other types send Unicast queries

Parameters:

Returns:

void mdns_query_results_free(mdns_result_t *results)

Free query results.

Parameters:

results – linked list of results to be freed

esp_err_t mdns_query_ptr(const char *service_type, const char *proto, uint32_t timeout, size_t max_results, mdns_result_t **results)

Query mDNS for service.

Parameters:

Returns:

esp_err_t mdns_query_srv(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result)

Query mDNS for SRV record.

Parameters:

Returns:

esp_err_t mdns_query_txt(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result)

Query mDNS for TXT record.

Parameters:

Returns:

esp_err_t mdns_lookup_delegated_service(const char *instance, const char *service_type, const char *proto, size_t max_results, mdns_result_t **result)

Look up delegated services.

Parameters:

Returns:

esp_err_t mdns_lookup_selfhosted_service(const char *instance, const char *service_type, const char *proto, size_t max_results, mdns_result_t **result)

Look up self hosted services.

Parameters:

Returns:

esp_err_t mdns_query_a(const char *host_name, uint32_t timeout, esp_ip4_addr_t *addr)

Query mDNS for A record.

Parameters:

Returns:

esp_err_t mdns_register_netif(esp_netif_t *esp_netif)

Register custom esp_netif with mDNS functionality mDNS service runs by default on preconfigured interfaces (STA, AP, ETH). This API enables running the service on any customized interface, either using standard WiFi or Ethernet driver or any kind of user defined driver.

Parameters:

esp_netif – Pointer to esp-netif interface

Returns:

esp_err_t mdns_unregister_netif(esp_netif_t *esp_netif)

Unregister esp-netif already registered in mDNS service.

Parameters:

esp_netif – Pointer to esp-netif interface

Returns:

esp_err_t mdns_netif_action(esp_netif_t *esp_netif, mdns_event_actions_t event_action)

Set esp_netif to a desired state, or perform a desired action, such as enable/disable this interface or send announcement packets to this netif.

Parameters:

Returns:

mdns_browse_t *mdns_browse_new(const char *service, const char *proto, mdns_browse_notify_t notifier)

Browse mDNS for a service _service._proto.

Parameters:

Returns:

mdns_browse_t pointer to new browse object if initiated successfully. NULL otherwise.

esp_err_t mdns_browse_delete(const char *service, const char *proto)

Stop the _service._proto browse.

Parameters:

Returns:

Structures

struct mdns_txt_item_t

mDNS basic text item structure Used in mdns_service_add()

Public Members

const char *key

item key name

const char *value

item value string

struct mdns_subtype_item_t

mDNS basic subtype item structure Used in mdns_service_subtype_xxx() APIs

Public Members

const char *subtype

subtype name

struct mdns_ip_addr_s

mDNS query linked list IP item

Public Members

esp_ip_addr_t addr

IP address

struct mdns_ip_addr_s *next

next IP, or NULL for the last IP in the list

struct mdns_result_s

mDNS query result structure

Public Members

struct mdns_result_s *next

next result, or NULL for the last result in the list

esp_netif_t *esp_netif

ptr to corresponding esp-netif

uint32_t ttl

time to live

mdns_ip_protocol_t ip_protocol

ip_protocol type of the interface (v4/v6)

char *instance_name

instance name

char *service_type

service type

char *proto

srevice protocol

char *hostname

hostname

uint16_t port

service port

mdns_txt_item_t *txt

txt record

uint8_t *txt_value_len

array of txt value len of each record

size_t txt_count

number of txt items

mdns_ip_addr_t *addr

linked list of IP addresses found

Macros

MDNS_TYPE_A

MDNS_TYPE_PTR

MDNS_TYPE_TXT

MDNS_TYPE_AAAA

MDNS_TYPE_SRV

MDNS_TYPE_OPT

MDNS_TYPE_NSEC

MDNS_TYPE_ANY

MDNS_NAME_MAX_LEN

MDNS_NAME_BUF_LEN

Type Definitions

typedef struct mdns_search_once_s mdns_search_once_t

Asynchronous query handle.

typedef struct mdns_browse_s mdns_browse_t

Daemon query handle.

typedef struct mdns_ip_addr_s mdns_ip_addr_t

mDNS query linked list IP item

typedef struct mdns_result_s mdns_result_t

mDNS query result structure

typedef void (*mdns_query_notify_t)(mdns_search_once_t *search)

typedef void (*mdns_browse_notify_t)(mdns_result_t *result)

Enumerations

enum mdns_event_actions_t

Values:

enumerator MDNS_EVENT_ENABLE_IP4

enumerator MDNS_EVENT_ENABLE_IP6

enumerator MDNS_EVENT_ANNOUNCE_IP4

enumerator MDNS_EVENT_ANNOUNCE_IP6

enumerator MDNS_EVENT_DISABLE_IP4

enumerator MDNS_EVENT_DISABLE_IP6

enumerator MDNS_EVENT_IP4_REVERSE_LOOKUP

enumerator MDNS_EVENT_IP6_REVERSE_LOOKUP

enum mdns_ip_protocol_t

mDNS enum to specify the ip_protocol type

Values:

enumerator MDNS_IP_PROTOCOL_V4

enumerator MDNS_IP_PROTOCOL_V6

enumerator MDNS_IP_PROTOCOL_MAX

enum mdns_query_transmission_type_t

mDNS query type to be explicitly set to either Unicast or Multicast

Values:

enumerator MDNS_QUERY_UNICAST

enumerator MDNS_QUERY_MULTICAST