Bonjour/mDNSResponder on mbed

18 Jun 2010 . Edited: 18 Jun 2010

Having played around with rolling my own UDP broadcast service which periodically fires out a UDP packet containing info about the mbed application to make discovery a little easier, I realised I was part way to re-inventing the wheel.  Bonjour/Zeroconf/mDNSResponder does a better job of doing the same thing, with the added bonus of client APIs and browsers already having been written for most platforms.

So I'm going to attempt to port Apple's open source mDNSResponder to run on top of Donatien's lwip stack.  Expect to see lots of idiotic questions appearing on here as I stumble through the darkness trying to figure this out.

My first stumbling block has been trying to get the NetServicesSource code to compile so I can enable lwIPs AutoIP functionality to start with.  However, having simply imported this program's files into my newly created program (Bonjour), complilation fails with:

"This declaration may not have extern "C" linkage (E800)" in file "/Bonjour/lib/mbed/Base.h"

This same error is listed for Base.h lines 150, 157, 167, 177, 187, 197; FunctionPointer.h lines 35, 55, 70; Serial.h line 148; Ticker.h lines 70, 95; InterruptIn.h lines 75, 95.  All listed as being within /lib/mbed/ which does not appear in the compiler's editing environment for me to investigate further.

Not a very illustrious start, falling at the first fence.  If anyone can point me in the right direction I'd be immensely grateful.

Thanks all.

Darran

18 Jun 2010

Hi Darran,

I have just published a new version of the source, so it might be a good idea to update it.

Looking at your program, it seems that you haven't configured the netCfg.h file properly. If you want to use Ethernet, it should look like this:

#ifndef NET_CFG_H
#define NET_TELIT_STACK 0
#define NET_GPRS 0
#define NET_PPP 0
#define NET_ZG2100 0
#define NET_ETH 1
#define NET_USB_SERIAL 0
#define NET_TELIT 0
#define NET_CFG_H 1
#define NET_USB 0
#define NET_LWIP_STACK 1
#endif
Also, feel free to delete the components you're not using to speed up the compilation times.

Good luck with this project, it could be a great component for the stack:).

Donatien

 

 

18 Jun 2010

Thanks Donatien, I was sure it would be something simple.  I did look to check that NET_ETH and NET_LWIP_STACK were set to 1.  Didn't think to check that the other components were set to 0. :/

Thanks again.  Now to learn a *lot* about C trying to get the mDNSResponse ported!

18 Jun 2010

AutoIP is now working.  Only the difficult bit to go, now!

The diff for anyone interested (this is the diff to NetServicesSource 1.02).  Not hugely complicated, just defines a couple of preprocessor constants to get lwip to compile in the AutoIP support and adds another timer to EthernetNetIf to call autoip_tmr() every AUTOIP_TMR_INTERVAL (100) ms.

$ diff -r NetServicesSource Bonjour
diff -r NetServicesSource/if/eth/EthernetNetIf.cpp Bonjour/if/eth/EthernetNetIf.
cpp
27a28
> #include "ipv4/lwip/autoip.h"
37c38
< EthernetNetIf::EthernetNetIf() : LwipNetIf(), m_ethArpTimer(), m_dhcpCoarseTimer(), m_dhcpFineTimer(), m_pNetIf(NULL),
---
> EthernetNetIf::EthernetNetIf() : LwipNetIf(), m_ethArpTimer(), m_dhcpCoarseTimer(), m_dhcpFineTimer(), m_autoIpTimer(), m_pNetIf(NULL),
45c46
< EthernetNetIf::EthernetNetIf(IpAddr ip, IpAddr netmask, IpAddr gateway, IpAddr dns) : LwipNetIf(), m_ethArpTimer(), m_dhcpCoarseTimer(), m_dhcpFineTimer(), m_pNetIf(NULL), m_hostname(NULL) //W/o DHCP
---
> EthernetNetIf::EthernetNetIf(IpAddr ip, IpAddr netmask, IpAddr gateway, IpAddr dns) : LwipNetIf(), m_ethArpTimer(), m_dhcpCoarseTimer(), m_dhcpFineTimer(), m_autoIpTimer(), m_pNetIf(NULL), m_hostname(NULL) //W/o DHCP
77a79
>     m_autoIpTimer.start();
117a120,124
>       if(m_autoIpTimer.read_ms()>=AUTOIP_TMR_INTERVAL)
>       {
>         m_autoIpTimer.reset();
>         autoip_tmr();
>       }
diff -r NetServicesSource/if/eth/EthernetNetIf.h Bonjour/if/eth/EthernetNetIf.h
55a56
>   Timer m_autoIpTimer;
diff -r NetServicesSource/lwip/lwipopts.h Bonjour/lwip/lwipopts.h
334c334,336
< #define LWIP_AUTOIP             0
---
> #define LWIP_AUTOIP             (LWIP_DHCP)
> #define LWIP_DHCP_AUTOIP_COOP   (LWIP_AUTOIP)
> #define LWIP_DHCP_AUTOIP_COOP_TRIES 3
diff -r NetServicesSource/netCfg.h Bonjour/netCfg.h
3,4c3,4
< #define NET_GPRS 1
< #define NET_PPP 1
---
> #define NET_GPRS 0
> #define NET_PPP 0
8,10c8,10
< #define NET_TELIT 1
< #define NET_CFG_H 1
< #define NET_USB 1
---
> #define NET_TELIT 0
> #define NET_CFG_H 0
> #define NET_USB 0

The default LWIP_DHCP_AUTOIP_COOP_TRIES is 9, but anything over 3 results in the default 15 second timeout hitting before the AutoIP steps in. Apparently, if a DHCP response is received after AutoIP assigns a 169.254.0.0/16 address, the DHCP assigned address will take over. I've yet to test this aspect.

24 May 2011

Good day,

I am curious if you have gotten any further on the implementation of Bonjour on the mbed. I too am looking at using the Bonjour functionality to have the services on the mbed auto-magically discovered from other nodes.

Thanks, Tyler

24 May 2011

I'm afraid I didn't get much further other than buying a copy of this book: http://oreilly.com/catalog/9780596101008 then things got in the way.

One day...