MDNS mdns_query_ptr don't give results

maurizio.scian
Posts: 26
Joined: Mon Jun 26, 2023 8:09 am

MDNS mdns_query_ptr don't give results

Postby maurizio.scian » Fri Jan 03, 2025 6:27 pm

I have a network, with 2 or more devices. Each device has an unique hostname and devices needs to get other devices hostname.
Resolving the mdns host with the "mdns_query_a" method works if I enter the names precisely, but the devices do not know the names of the other hosts: they have to infer this from the services that are exposed.
Simplifying the code, these are the sources of the initializations:

Device1:

Code: Select all

mdns_init();
mdns_hostname_set("Device1");
mdns_instance_name_set("Device1");
mdns_service_add("Dev1Service", "ServiceA", "_tcp", 60667, NULL, 0);
Device2:

Code: Select all

mdns_init();
mdns_hostname_set("Device2");
mdns_instance_name_set("Device2");
mdns_service_add("Dev2Service", "ServiceB", "_tcp", 60668, NULL, 0);
Well, after the connection, each devices need to get the others connected devices hostnames.

Device1:

Code: Select all

mdns_result_t *results = NULL;
mdns_query_ptr("ServiceB", "_tcp", 60668, 100, &results);
Device2:

Code: Select all

mdns_result_t *results = NULL;
mdns_query_ptr("ServiceA", "_tcp", 60667, 100, &results);
Both the devices can print the query results:

Code: Select all

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) {
		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; t<r->txt_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("  IPV6: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
			}
			else {
				printf("  IPV4   : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
			}
			a = a->next;
		}
		r = r->next;
	}
}
Each devices get a result with many record (even if only one other device is on the same network), but the instance_name, and the hostname are ever empty string (not null, only empty) and addr is ever 0.
In menuconfig in each device those settings are enabled: Enable responding to IPv4 reverse queries, multiple instances under the same device, and Use predefined interface for Ethernet.

Where am I going wrong?

maurizio.scian
Posts: 26
Joined: Mon Jun 26, 2023 8:09 am

Re: MDNS mdns_query_ptr don't give results

Postby maurizio.scian » Mon Feb 03, 2025 2:50 pm

I'll try to explain better:
MDNS works well if I resolve a name punctually, but if I request a service, it responds but doesn't give information about the host.

nopnop2002
Posts: 347
Joined: Thu Oct 03, 2019 10:52 pm
Contact:

Re: MDNS mdns_query_ptr don't give results

Postby nopnop2002 » Tue Feb 04, 2025 12:25 pm

>mdns_query_ptr("ServiceB", "_tcp", 60668, 100, &results);

The first argument of mdns_query_ptr is the service type.
The service type will have a name like this.
_service_60668
_http_8080

The third argument is time in milliseconds to wait for answer.


Service name is service type + protocol.
_service_60668._tcp
_http_8080._tcp

This will help.

https://github.com/nopnop2002/esp-idf-mdns

maurizio.scian
Posts: 26
Joined: Mon Jun 26, 2023 8:09 am

Re: MDNS mdns_query_ptr don't give results

Postby maurizio.scian » Wed Feb 19, 2025 9:30 pm

>mdns_query_ptr("ServiceB", "_tcp", 60668, 100, &results);

The first argument of mdns_query_ptr is the service type.
The service type will have a name like this.
_service_60668
_http_8080

The third argument is time in milliseconds to wait for answer.


Service name is service type + protocol.
_service_60668._tcp
_http_8080._tcp

This will help.

https://github.com/nopnop2002/esp-idf-mdns
Thank you @nopnop2002, it's the solution!

Device1 initialization:

Code: Select all

mdns_init();
mdns_hostname_set("Device1");
mdns_instance_name_set("Device1");
mdns_service_add(NULL, "_ServiceA_60667", "_udp", 60667, NULL, 0);
Device2 initialization:

Code: Select all

mdns_init();
mdns_hostname_set("Device1");
mdns_instance_name_set("Device1");
mdns_service_add(NULL, "_ServiceB_60668", "_udp", 60668, NULL, 0);
Device1 query:

Code: Select all

mdns_result_t *results = NULL;
mdns_query_ptr("_ServiceB_60668", "_udp", 100, 60668, &results);
Device2 query:

Code: Select all

mdns_result_t *results = NULL;
mdns_query_ptr("_ServiceA_60667", "_udp", 100, 60667, &results);
Using this method for display the results:

Code: Select all

#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
/* these strings match tcpip_adapter_if_t enumeration */
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
#endif

/* these strings match mdns_ip_protocol_t enumeration */
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};

static void mdns_print_results(mdns_result_t *results, char * hostname, char * ip, uint16_t *port)
{
	mdns_result_t *r = results;
	mdns_ip_addr_t *a = NULL;
	int i = 1, t;
	while (r) {
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
		esp_netif_get_desc(r->esp_netif);
		printf("%d: Interface: %s, Type: %s, TTL: %"PRIu32"\n",
			i++, esp_netif_get_desc(r->esp_netif), ip_protocol_str[r->ip_protocol], r->ttl);

#else
		printf("%d: Interface: %s, Type: %s, TTL: %u\n", 
			i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol], r->ttl);
#endif
		if (r->instance_name) {
			printf("  PTR : %s.%s.%s\n", r->instance_name, r->service_type, r->proto);
		}
		if (r->hostname) {
			printf("  SRV : %s.local:%u\n", r->hostname, r->port);
			strcpy(hostname, r->hostname);
			*port = r->port;
		}
		if (r->txt_count) {
			printf("  TXT : [%zu] ", r->txt_count);
			for (t = 0; t < r->txt_count; t++) {
				printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value ? r->txt[t].value : "NULL", r->txt_value_len[t]);
			}
			printf("\n");
		}
		a = r->addr;
		while (a) {
			if (a->addr.type == ESP_IPADDR_TYPE_V6) {
				printf("  AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
			} else {
				printf("  A   : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
				sprintf(ip, IPSTR, IP2STR(&(a->addr.u_addr.ip4)));
			}
			a = a->next;
		}
		r = r->next;
	}
}
Display a result like:

Code: Select all

1: Interface: eth, Type: V4, TTL: 120
  PTR : OIDA-HPAA77777
  SRV : OIDA-HPAA77777.local:60668
  IPV4   : 192.168.0.43
Last edited by maurizio.scian on Thu Feb 20, 2025 11:56 am, edited 1 time in total.

nopnop2002
Posts: 347
Joined: Thu Oct 03, 2019 10:52 pm
Contact:

Re: MDNS mdns_query_ptr don't give results

Postby nopnop2002 » Wed Feb 19, 2025 10:50 pm

>mdns_query_ptr("_ServiceA_60667", "_udp", 60667, 100, &results);
>mdns_query_ptr("_ServiceB_60668", "_udp", 60668, 100, &results);

The third argument is time in milliseconds to wait for answer, not the port number.
You can check the details of this function here.
https://docs.espressif.com/projects/esp ... /mdns.html

maurizio.scian
Posts: 26
Joined: Mon Jun 26, 2023 8:09 am

Re: MDNS mdns_query_ptr don't give results

Postby maurizio.scian » Thu Feb 20, 2025 11:39 am

>mdns_query_ptr("_ServiceA_60667", "_udp", 60667, 100, &results);
>mdns_query_ptr("_ServiceB_60668", "_udp", 60668, 100, &results);

The third argument is time in milliseconds to wait for answer, not the port number.
You can check the details of this function here.
https://docs.espressif.com/projects/esp ... /mdns.html
This explains the slowness! ;)

Thank you my hero!

Who is online

Users browsing this forum: Applebot, Baidu [Spider], Bing [Bot], ChatGPT-User, Qwantbot and 4 guests