[vdr] [ANNOUNCE] another more or less useless plugin: avahi4vdr

Lars Hanisch dvb at flensrocker.de
Thu Jan 10 00:05:52 CET 2013


Homepage: https://github.com/flensrocker/vdr-plugin-avahi4vdr

What is it:
It's a helper, so you can easily announce network services of your vdr and its plugins to your LAN via avahi (a Zeroconf
implementation) or retrieve information about other network services (not limited to vdr such as nfs mounts etc.).
Please read the README at
https://github.com/flensrocker/vdr-plugin-avahi4vdr/blob/master/README

I'm trying very hard to keep my README up-to-date. If there are questions please let me know.
Please get familiar with Avahi, the avahi-tools like avahi-browse, avahi-publish and their manpages.

How does it work:
The "static way" is using a file "services.conf" in the plugin's config directory. For an example please look at
 https://github.com/flensrocker/vdr-plugin-avahi4vdr/blob/master/examples/services.conf

 Please forgive my long post... :)

Server-Example: How to announce streamdev-server
 (aka announcing a static network service with fixed port)
# line in services.conf, for syntax and escaping see README
name=vdr-streamdev-server on %h,type=_http._tcp,port=3000,subtype=_vdr_streamdev_server._sub._http._tcp

name: is something to display to the user (%h will be replaced with the hostname)
type: is the service type, there are standards, look at http://www.dns-sd.org/ServiceTypes.html
port: the port the service is listening on (handy for dynamic ports, since you can update the service on the fly and
reannounce a new port, but sadly not in this static example, you have to use the plugin's SVDRPCommand "CreateService"
for more control)
subtype: you can specify details of the service, streamdev is on the lowest level a webserver, hence the type
_http._tcp, but will publish special services with another "protocol", I suggest "_vdr_<plugin's name>.sub.<service
type>" if it's for a vdr plugin. You can specify as many subtypes as you want.
txt: you can add as many txt records to a service with service specific data (not used in this example, if you know
avahi, you'll understand).

On vdr startup, avahi4vdr connects to the avahi-daemon and will announce the streamdev-server. What for? Read next. :)

Example: How to find streamdev-server
 (suggestion as extension to streamdev-client, feel free to implement)
I will create a patch as soon as I can find time and really do need this fetaure at streamdev...

You can call avahi4vdr's SVDRPCommand directly for registering a browser for services:

  int replyCode = 0;
  cString browserId; // remember this!
  cPlugin *avahi4vdr = cPluginManager::GetPlugin("avahi4vdr");
  ...
  if (avahi4vdr != NULL)
     browserId = avahi4vdr->SVDRPCommand("CreateBrowser",
"caller=streamdev-client,protocol=IPv4,type=_vdr_streamdev_server._sub._http._tcp", replyCode);
  ...

If you don't need the browser anymore you can delete it anytime (will be done automatically on vdr-exit).
  ...
  if (avahi4vdr != NULL)
     avahi4vdr->SVDRPCommand("DeleteBrowser", *browserId, replyCode);
  ...

Your plugin's Service function will be called if the browser raises an event:
  bool cPluginDbus2vdr::Service(const char *Id, void *Data)
  {
    if (strcmp(Id, "avahi4vdr-event") == 0) {
       cAvahiHelper options(Data);
       const char *event = options.Get("event");
       const char *browser_id = options.Get("id");
       if (strcmp(event, "browser-service-resolved") == 0) {
          const char *name = options.Get("name");
          const char *host = options.Get("host");
          const char *protocol = options.Get("protocol");
          const char *address = options.Get("address");
          const char *port = options.Get("port");
          const char *local = options.Get("local");
          const char *txt = NULL;
          int txt_nr = 0;
          while (true) {
                txt = options.Get("txt", txt_nr);
                if (txt == NULL)
                   break;
                ...
                txt_nr++;
                }
          ...
          }
       else if (strcmp(event, "browser-service-removed") == 0) {
          const char *name = options.Get("name");
          const char *protocol = options.Get("protocol");
          const char *local = options.Get("local");
          ...
          }
       return true;
       }
    return false;
  }

cAvahiHelper is located at https://github.com/flensrocker/vdr-plugin-avahi4vdr/blob/master/avahi-helper.h
It's a helper class for parsing parameters, only header is needed, so just copy it to your plugin.

caller: (at CreateBrowser) the name of the plugin which should be called. You needn't to take your plugin's name. It's
possible to create browsers for other plugins. It's not a bug, it's a feature. :)

Whenever the browser detects a new service, an event "browser-service-resolved" is emitted. streamdev-client should
instantiate a new device for each detected server (or reuse an unconnected device, multi-device support should be added
first to streamdev-client) and if a server shuts down (event "browser-service-removed") the corresponding device can be
"deactivated" (e.g. set to -none-).

No more editing ips or ports in config files... :)


For now there is just one "user" of the feature "dynamic publishing of services": dbus2vdr
It starts a dbus-daemon listening on a dynamic tcp port and publishes it as subtype "_vdr_dbus2vdr._sub._dbus._tcp". On
this separate dbus-daemon dbus2vdr just offers some read-only objects and methods like listing the timers or recordings.
Listing channels will be added soon.
I want to use these "dbus2vdr"-daemons to collect all timers from the stations on the LAN. I will add some simple logic
(will be announced next month or so) and then all vdrs will record every thing they want. Timer conflict check is not
yet planned, first incarnation will be "record everything I find important". Each vdr will decide on its own if it wants
to record the timer of the remote vdr. Please be patient, project is at planning/documentation state, I have nothing
coded yet.


 What would you like to do with avahi4vdr? Please let me know...


 Have fun!

Lars.



More information about the vdr mailing list