Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Understanding Avahi

stonier edited this page Nov 5, 2011 · 4 revisions

C++ Implementation

Entry Groups

When publish a service, you may wish to publish across more than one service name/type. For example printers may be publishing a unix printer service, pdl printer service, scanner service etc. For such services it is important for their publication to be commited atomically as a group so that no other service publication can interrupt and destroy the commonality of the service name.

This is what the entry group is for - add your service group to the object and they'll all get published together.

Note that this means for most services (one-offs), you'll be using an entry group per publication.

Do not try and re-use the entry group - avahi will go into a bad state!

Resolvers

When discovering, you'll need to set up a resolver for each discovery. This resolver should be kept open, so that you can be informed of when the connection goes up and down. Connections going up and down don't remove the discovery, just its resolvability. Things of course get complicated when you drop off, and someone else steals your name.

MultiThreading

Avahi will expect all interactions from inside its own thread.

If you want to manipulate services run-time, you'll need to lock and reopen the threaded poll lock if you're working from your program's main thread. Note that many of the callbacks (discovery, resolver) will actually run inside the threaded_poll loop, so don't need locking (you'll get deadlocks if you try).

The above works for the c++ implementation. If using python or qt or another custom implementation, it may need some thinking/custom loop implementations.

Ros Constraints

Rather than implement absolutely everything capable by the avahi api, some constraints were implemented for ros architectures to keep things simple. This can easily be modified on an as needed basis. The constraints:

  • one service type per advertised service name

c.f. a printer which will usually advertise one name, but usually 3 types of printer services. Refer to the section below on entry groups for a more detailed discussion on atomicized entries.

  • protocol is ipv4

We could put this as a further variable in the zeroconf_comms formats and c++ api, but seems like unnecessary complication for now. Might have to upgrade to unspecified (i.e. both ipv4, ipv6 at some time though.

  • interface is unspecified

Same issues as the previous constraint, but for hardware interfaces (e.g. eth0, wlan1).

Non C++ Implementations

  • python : have only done a bit of testing, not worked out how to do runtime configuration though (event loop problem).
  • embedded : avahi comes with libavahi-core which can remove the dependency on dbus.

Bugs & Workarounds

There are some bugs with avahi's resolver that pop up when wireless connections drop out (or go out of range) and get overridden by new connections with the same service name from elsewhere. This will happen alot for wireless robots all running off the same robot name.

  1. After wireless drops out and just before the resolver times out it will sometimes associate an ipv4 connection with an ipv6 address. This is just plain ignored in the code for now.

  2. If wireless drops out and another robot with different ip tries to connect on the same service name, it resolves to the old ip address. Something wrong in avahi here, it calls the callback before it has a chance to set all the variables properly. Simply waiting for 500ms in the callback fixes this.