AirSane icon indicating copy to clipboard operation
AirSane copied to clipboard

umdns instead of avahi on OpenWRT

Open cmangla opened this issue 1 year ago • 19 comments
trafficstars

Avahi is available as a package on OpenWRT, and our current package uses it as a dependency. However, OpenWRT has its own mDNS alternative called umdns, which is light-weight and typically pre-installed. On OpenWRT, umdns does not require any native code integration. It can just be called upon from the init scripts that launch airsaned. Some routers may not have enough space to install avahi.

If airsaned can, after launch, generate output of the form <service> <proto> <port> [<textkey=textvalue> ... ], then this can just be passed on to umdns on OpenWRT. I believe this is all that's required. Example output is "webdav" "tcp" "80" "path=/nextcloud/remote.php/dav/files/YOUR_USER/" "u=YOUR_USER"

Is avahi currently a hard dependency?

Can we add an option to airsaned to just output the text needed by umdns as shown above?

cmangla avatar Sep 07 '24 18:09 cmangla

On macOS, airsaned is using dnssd instead of avahi, so there is some modularization in place already. Certainly, it would not be difficult to write the required output, but note that airsaned will dynamically add or remove entries if scanners are plugged in or removed. It should thus have means to restart/reload the umdns process. Is this possible?

SimulPiscator avatar Sep 07 '24 19:09 SimulPiscator

On macOS, airsaned is using dnssd instead of avahi, so there is some modularization in place already.

Ah, that's good to know.

Certainly, it would not be difficult to write the required output, but note that airsaned will dynamically add or remove entries if scanners are plugged in or removed. It should thus have means to restart/reload the umdns process. Is this possible?

The clean way to do this on OpenWRT (I'm guessing) would be to tell umdns to change the AirSane entries using ubus. The ubus subsystem (with u meaning µ meaning 'micro') is their alternative for the desktop linux daemon dbus. And again, the least hacky way to use ubus would be to use its c-api by linking against libubus.

I am tempted to work around linking against the libubus because our needs are simple. It is also possible to send ubus messages using the ubus binary with the right arguments, and that is how it is used on the commandline. We can just invoke it with system().

I will look into these options when I find some free time.

cmangla avatar Sep 08 '24 08:09 cmangla

Closes cmangla/AirSane-openwrt#32

cmangla avatar Sep 08 '24 13:09 cmangla

You really need to switch to umdns. Avahi really takes up a lot of space and consumes a lot of RAM, I don't know how to reconfigure airsaned to work via umdns. New versions of airsaned are best made based on umdns.

bamboo-master avatar Nov 27 '24 18:11 bamboo-master

I've been searching extensively but could not find any indication that there is a binary API to umdns. All I found are scripting commands to be executed in a service's init script. As airsaned dynamically adds or removes announcements as scanners are plugged in or removed, this is not feasible.

SimulPiscator avatar Nov 28 '24 09:11 SimulPiscator

I've been searching extensively but could not find any indication that there is a binary API to umdns. All I found are scripting commands to be executed in a service's init script.

I agree, the documentation is very limited.

As airsaned dynamically adds or removes announcements as scanners are plugged in or removed, this is not feasible.

In OpenWRT, they have a system-wide software bus for RPC, called ubus, analogous to dbus in desktop linux. And ubus has a binary API. The documentation for umdns says "almost all interaction with the [umdns] daemon is via ubus". So I suspect that for such dynamic service announcements, you'll have to RPC umdns using the C-API ofubus.

See:

https://github.com/openwrt/ubus

https://openwrt.org/docs/guide-developer/ubus

cmangla avatar Nov 28 '24 12:11 cmangla

When playing around with OpenWrt, I noticed there are avahi packages that don't require dbus to work. I don't believe avahi in itself is very resource hungry, so it might make sense to try the avahi-nodbus approach before going to tackle interfacing with umdns.

SimulPiscator avatar Dec 02 '24 22:12 SimulPiscator

The airsane-openwrt package lists libavahi-client as a dependency, which in turn lists avahi-dbus-daemon as a dependency. This is why our openwrt package pulls in dbus. The solution might be to create a libavahi-nobus-client package.

cmangla avatar Dec 03 '24 11:12 cmangla

I may not understand your comment. AFAIK, such a package does already exist: https://github.com/openwrt/packages/blob/master/libs/avahi/Makefile

SimulPiscator avatar Dec 03 '24 12:12 SimulPiscator

I may not understand your comment. AFAIK, such a package does already exist: https://github.com/openwrt/packages/blob/master/libs/avahi/Makefile

Yes, in that file, you will find libavahi-client, but there is no libavahi-nobus-client. Our package pulls in libavahi-client, which in turn pulls in dbus.

I have started an attempt at cmangla/airsane-openwrt#33 . But I am not using openwrt actively these days so I may not be able to take that PR very far.

cmangla avatar Dec 03 '24 12:12 cmangla

Wouldn't it make sense if libavahi-client were able to interface with both dbus and nodbus versions of avahi? Otherwise (i.e., if there were dbus and nodbus versions of libavahi-client), client packages would need to decide for one of those, thus introducing conflicts between packages that depend on either version.

SimulPiscator avatar Dec 03 '24 12:12 SimulPiscator

I believe the way avahi is organized in OpenWRT requires the user to make a system-wide choice between avahi-with-dbus and avahi-without-dbus. This is because there is an avahi-dbus-daemon and an avahi-nodbus-daemon.

But you are right, I should use the VARIANT flag to create a variant of libavahi-client package that does not depend on dbus. Then on a non-dbus system, a user would pick that package variant. Not sure how to do that without modifying the upstream package.

cmangla avatar Dec 03 '24 12:12 cmangla

I see, I was not aware of a number of relevant issues here.

So far, I've tried to build airsaned for OpenWrt but without success. No error message, just no .ipk created. I didn't use the docker image you recommend, though -- this will be the next step.

Then I will have to learn how to debug it remotely.

SimulPiscator avatar Dec 03 '24 12:12 SimulPiscator

So far, I've tried to build airsaned for OpenWrt but without success. No error message, just no .ipk created. I didn't use the docker image you recommend, though -- this will be the next step.

A cheat option is to get Github Actions to compile it as a package for you. In the airsane-openwrt repository, there is a build.yaml workflow. Bit slow and wasteful, but sometimes it is the easy option.

cmangla avatar Dec 03 '24 13:12 cmangla

No error message, just no .ipk created.

I suppose you much have searched for it at bin/packages/**/airsaned_*.ipk ?

cmangla avatar Dec 03 '24 14:12 cmangla

A find bin -iname airsane* did not turn up an ipk file.

SimulPiscator avatar Dec 03 '24 14:12 SimulPiscator

A find bin -iname airsane* did not turn up an ipk file.

Strange. Oh well.

cmangla avatar Dec 03 '24 15:12 cmangla

I have started an attempt at cmangla/AirSane-openwrt#33

I asked the OpenWrt community for help: https://forum.openwrt.org/t/help-fix-package-makefile/217677

cmangla avatar Dec 06 '24 18:12 cmangla

That's nice.

SimulPiscator avatar Dec 07 '24 00:12 SimulPiscator