mDNS Integration
struct np_mdns_functions
The Nabto Edge platform uses mDNS for discovery on the local network. That is, if a client needs to find a local device on the local network.
Some systems come with their own mDNS service, on these systems we recommend to use the system provided mDNS service. If a system does not provide an mDNS service, we have a generic service which is located in the src/modules/mdns
folder.
The jobs of the mDNS discovery are:
- Inform a client about local devices with Nabto Edge.
- Tell the client at which ip and port the Nabto Edge service is running on the device.
Requirements for Nabto Edge devices to be discovered via mDNS
- Provide discovable Service Type Identifier of :
_nabto._udp
- Provide Text record with two key/values pairs:
productid=<productId>
deviceid=<deviceId>
The mDNS Instance Name of the device is not important since it basically is used to identify the device on the local network. Once a Nabto Edge connection has been established the client will lookup the device and product id and forwardly use those to locate and connect to the device.
mDNS service discovery is built into the Nabto Edge platform through the np_mdns
interface. This interface have one function.
void (*publish_service)(struct np_mdns* obj, uint16_t port, const char* productId, const char* deviceId);
This function is called a bit after the device has been started, since the device needs to have opened its local socket first and acquired the local port number of the local socket.
When this function is called, the mDNS implementation should register the service _nabto._udp
as having the port
port number on the device. Further, two key value pairs should be registered for the service productid=<productId>
and deviceid=<deviceId>
.
Testing
Several mDNS clients exist which can be used to test that an mDNS implementation works. On Windows and Mac, it is recommended to use the dns-sd tool which comes from bonjour.
On Windows this sdk can be downloaded from https://developer.apple.com/bonjour/.
On Mac, the dns-sd tool is installed by default.
On Linux the avahi-tools package can be used, it comes with the avahi-browse command (avahi-browse -a -r
).
Example scan for all nabto edge devices on the local network:
C:\>dns-sd -B _nabto._udp
Browsing for _nabto._udp
Timestamp A/R Flags if Domain Service Type Instance Name
4:22:42.514 Add 2 4 local. _nabto._udp. de-nhbpwxcx
The example shows information about a specific device, the important information is the txt records and the port number.
C:\>dns-sd -L de-nhbpwxcx _nabto._udp
Lookup de-nhbpwxcx._nabto._udp.local
4:23:48.795 de-nhbpwxcx._nabto._udp.local. can be reached at de-nhbpwxcx.local.:49654 (interface 4)
deviceId=de-nhbpwxcx productId=pr-bqyh43fb
Example: Get the ips for a device using dns-sd:
C:\>dns-sd -G v4v6 de-nhbpwxcx.local.
Timestamp A/R Flags if Hostname Address TTL
4:33:27.514 Add 3 4 de-nhbpwxcx.local. 192.168.123.117 120
4:33:27.514 Add 2 4 de-nhbpwxcx.local. 2001:DB8:1234:0003:8D41:1F5C:3C08:2D3F%<0> 120
Using this information we know that the device with the product id pr-bqyh43fb
and the device id de-nhbpwxcx
can be reached on the ips 192.168.123.117
and 2001:DB8:1234:0003:8D41:1F5C:3C08:2D3F
on UDP port 49654
mDNS example implementation
The ESP32 comes with an mDNS server, https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/mdns.html.
Assuming the mDNS server is started acording to the documentation, then the mDNS integration is as follows.
static struct np_mdns_functions vtable = {
.publish_service = &publish_service
};
struct np_mdns esp32_mdns_get_impl()
{
struct np_mdns obj;
obj.vptr = &vtable;
obj.data = NULL;
return obj;
}
void publish_service(struct np_mdns* obj, uint16_t port, const char* productId, const char* deviceId)
{
mdns_txt_item_t serviceTxtData[2] = {
{"productid",productId},
{"deviceid",deviceId}
};
mdns_service_add(NULL, "_nabto", "_udp", port, serviceTxtData, 2);
}