It’s been a week since the last blog post about mDNS and the nodeMCU.
I’ve promised further updates and well here they are.
The bonjour user module can now question other mDNS / bonjour devices for their IP and other info.
A lot has changed in the API, and some more changes will come, but i hope to have covered the major things now. As it is now:
-
requests, responses = bonjour:parse(frame)
will now return request and responses. Some responses are completely parsed (Type A, CNAME and SRV) more types are to come
-
bonjour:create_request({request1, request2, ..})now generates a mDNS frame containing the requests. A request itself is a table with name, type and class fields. I.e.
request1 = { name="domain-name.local", type=bonjour.TYPE.A, class=bonjour.CLASS.IN } -
bonjour:create_response({response1, response2, ..})now generates a mDNS frame containing the requests. A request itself is a table with name, type, class, and ttl filled. I.e.
response1 = { name="esp-8266.local", type=bonjour.TYPE.A, class=bonjour.CLASS.IN, ttl=64, ip=wifi.sta.getip() } - to fill the fields,
bonjour.TYPE
and
bonjour.CLASS
contain the required constants. Named as in RF1035. I.e. bonjour.TYPE.A
- the field
bonjour.VERSION
contains a version id (16bit, high byte = mahor, low byte = minor version)
Depending on the type, also (A): ip, (CNAME): cname, (SRV): host, port, priority and weight must be present.
So what?
Querries! 🙂
Want to find other nodeMCU devices running the mDNS responder or your Fruit-Branded Smartphone? Just ask them for their IP now.
![]()
The source file of the bonjour module can be found here.
I have added an extended version of the same mDNS responder lua file for the latest Demo Firmware I had provided with the last demo:
if ((bonjour ~= nil) and (bonjour.VERSION >= 0x0002)) then
bonjourRequestIP = {}
if (wifi.sta.getip() == nil) then
print("mDNS requires an ip address. Please connect to a station.")
else
srv = net.createServer(net.UDP)
conn = net.createConnection(net.UDP, 0)
conn:connect(5353, "224.0.0.251")
srv:on("receive",
function (s, c)
-- get requests from frame
requests, responses = bonjour:parse(c)
if (requests ~= nil) then
for index, request in pairs(requests) do
tmr.wdclr() ;
print("Request mDNS["..index.."]: "..request.name.."(Type: "..request.type..")")
if ((request.name:lower() == "esp-8266.local") and (request.type == bonjour.TYPE.A)) then
conn:send (
bonjour:create_response({{name = request.name, type=bonjour.TYPE.A, class=1, ttl=64, ip=wifi.sta.getip()}})
)
end
end
end
if (responses ~= nil) then
for index, response in pairs(responses) do
tmr.wdclr() ;
if (response.type == bonjour.TYPE.A) then
if (bonjourRequestIP.Name ~= nil) then
if (bonjourRequestIP.Name:lower() == response.name:lower()) then
bonjourRequestIP.IP = response.ip
bonjourRequestIP.Callback(response.ip)
bonjourRequestIP.Name = nil ;
else
print("Response mDNS["..index.."]: "..response.name.."(A: ip="..response.ip..")")
end
else
print("Response mDNS["..index.."]: "..response.name.."(A: ip="..response.ip..")")
end
elseif (response.type == bonjour.TYPE.CNAME) then
print("Response mDNS["..index.."]: "..response.name.."(CNAME: cname="..response.cname..")")
else
print("Response mDNS["..index.."]: "..response.name.."(Type: "..response.type..")")
end
end
end
end
)
srv:listen(5353)
net.multicastJoin(wifi.sta.getip(), "224.0.0.251")
end
function RequestBonjourIP(localname, callback)
bonjourRequestIP.Name = localname
bonjourRequestIP.Callback = callback
bonjourRequestIP.IP = ""
bonjourRequestIP.Retry = 0
bonjourRequestIP.Done = 0
conn:send(bonjour:create_request({{name = bonjourRequestIP.Name, type = bonjour.TYPE.A, class=bonjour.CLASS.IN}}))
tmr.alarm(0,300, 1,
function()
if (bonjourRequestIP.IP == "") then
if (bonjourRequestIP.Retry > 8) then
bonjourRequestIP.Done = 1
bonjourRequestIP.Callback(nil)
tmr.stop(0)
end
conn:send(bonjour:create_request({{name = bonjourRequestIP.Name, type = bonjour.TYPE.A, class=.CLASS.IN}}))
bonjourRequestIP.Retry = bonjourRequestIP.Retry + 1 ;
else
bonjourRequestIP.Done = 1
end
end
)
end
else
print("mDNS Server requires user module Bonjour v0.02 or higher.") ;
end
A lot of error checking was added and more will be done.
There might be crashes with huge mDNS requests (i.e. a 1010 byte request a local device sends sometimes here seems to trigger a reset) but further investigation is required to rule out that this is simply the watchdog for taking too long or if the request is using up too much memory.
Several mDNS response formats need to be parsed. right now they will be sent and received ignoring their actual payload.
This leaves me to say:
Have fun!