SimulPiscator / AirSane

Publish SANE scanners to MacOS, Android, and Windows via Apple AirScan.
GNU General Public License v3.0
258 stars 26 forks source link

Android Mopria Scan cannot find scanner #98

Open cmangla opened 1 year ago

cmangla commented 1 year ago

I have AirSane installed on a Raspberry Pi Zero running on OpenWrt 22.03.2. The AirSane package was built using the linked (newer) OpenWrt package source. The scanner works perfectly well with macOS and Windows: both are able to detect it automatically and are able to scan. Both are also connected to the local network over WiFi only. When I check on macOS, I can see the mDNS entry for the scanner under _uscan._tcp.local.

Mopria Scan on my Android phone, on the other hand, cannot detect the scanner. I am able to reach the scanner's HTML ui by navigating to http://pizero.local:8090, so clearly the host is reachable even from the '.local' domain. Furthermore, using the "Service Browser" app from the play store, I can see the same _uscan._tcp.local that I see on macOS, with all the same entries.

Mopria Scan version 1.8.6, Android 11, AirSane 806e57d (5 commits after Janitor release).

SimulPiscator commented 1 year ago

Using Mopria Scan 1.8.6, I can see my scanner in the local network (the server is an older Intel NUC running Debian 11). In the past, I have had issues with scanners not being recognized or not able to connect to which had to do with IPv6 being enabled on the NUC but not on individual devices in the network. Just recently, an update to my FritzBox router broke scanning from some devices, required enabling of IPv6 on a MacBook, and a reboot of the NUC.

cmangla commented 1 year ago

@SimulPiscator Thanks for checking. I will try to dig down into the issue with my setup at some point. I did a quick check of IPv6 in my network and the devices; can't spot any particular issue.

cmangla commented 1 year ago

I ran wireshark on the Pi running AirSane and ran Mopria Scan on my phone. The Pi sees the mDNS queries and it seems AirSane responds:

image

@SimulPiscator Is there anything obvious that you can spot in this screenshot? If not, how can I debug this further? What information would be useful?

SimulPiscator commented 1 year ago

In the screenshot I see that the address of the AirSane machine seems to be "pzwh". Can you get a connection to http://pzwh:8090 from a browser on your phone? If not, does it work with http://pzwh.local:8090 ?

cmangla commented 1 year ago

In the screenshot I see that the address of the AirSane machine seems to be "pzwh". Can you get a connection to http://pzwh:8090

I can get a connection to http://pzwh:8090 just fine from my phone browser. I get to the web interface of AirSane. I am able to scan using the web UI.

from a browser on your phone? If not, does it work with http://pzwh.local:8090 ?

Conecting to http://pzwh.local:8090 from my phone browsers does not work. It is not able to resolve the DNS. However, I think this this expected on Android and may be solved in upcoming releases, I think.

SimulPiscator commented 1 year ago

Same here, yes. As a last resort, can you uninstall the Mopria Scanner App completely (removing its preferences) and reinstall it?

cmangla commented 1 year ago

I first cleared Mopria Scanner App's data and cache, then I uninstalled it. Then I installed it again from the Play Store. It's still exactly the same unfortunately.

cmangla commented 1 year ago

I have an app called "BonjourBrowser" on my phone which is able to find local http servers using mDNS, so that means my phone is at least able to receive mDNS broadcast messages.

SimulPiscator commented 1 year ago

In your screenshot, I can see that your scanner does not have rs=/eSCL. By default, AirSane uses this for compatibility reasons. Can you post your /etc/default/airsaned? What will happen if you enter your raspberry pi's IPv4 address instead of the * in the first line in /etc/default/airsaned?

cmangla commented 1 year ago

On my OpenWrt build of Airsane, it uses /etc/config/airsaned for configuration, which is in the distro's own standardized format. It then translates this config into command-line options when airsaned is launched. Here is that config:

config airsaned 'global'
    option interface        ''
    option port         '8090'
    option access_log       '-'
    option hotplug          'true'
    option mdns_announce        'true'
    option local_scanners_only  'true'
    option debug            'false'

and the resulting command-line is:

/usr/bin/airsaned --listen-port=8090 --access-log=- --hotplug=true --mdns-announce=true --local-scanners-only=true --debug=false

So you can see, when the interface in the config is blank, it is omitted from the command-line of airsaned. I ran a test by changing it to *, so then I got:

/usr/bin/airsaned --interface=* --listen-port=8090 --access-log=- --hotplug=true --mdns-announce=true --local-scanners-only=true --debug=false

and airsaned was indeed listening on all IP addresses:

# netstat -l -n -p | grep -i airsane
tcp        0      0 192.168.1.120:8090      0.0.0.0:*               LISTEN      1940/airsaned
tcp        0      0 127.0.0.1:8090          0.0.0.0:*               LISTEN      1940/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      1940/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      1940/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      1940/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      1940/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      1940/airsaned
tcp        0      0 ::1:8090                :::*                    LISTEN      1940/airsaned

But Moria Scan didn't find it still.

When I try to start airsaned with my ip address in the interface, it crashes with like so:

# /usr/bin/airsaned --interface=192.168.1.120 --listen-port=8090 --access-log=- --hotplug=true --mdns-announce=true --local-scanners-only=true --debug=true
git commit: N/A (branch N/A, rev N/A+)
build date: 2022-10-14T22:44:41Z
start time is 500052
no device options at '/etc/airsane/options.conf'
enumerating local devices...
sane_init(nullptr, nullptr)
sane_get_devices() ...
... sane_get_devices() -> SANE_Status Success
sane_exit()
found: hpaio:/usb/Photosmart_C4200_series?serial=MY85FQP16804VP (Hewlett-Packard Photosmart_C4200_series)
stable unique name: hpaio:Hewlett-Packard Photosmart_C4200_series:1
uuid: 83e18d98-1fce-5380-9e93-0a9690a50292
sane_init(nullptr, nullptr)
sane_open(hpaio:/usb/Photosmart_C4200_series?serial=MY85FQP16804VP) -> 0xb6cc9280
[source] := "Flatbed"
sane_close(0xb6cc9280)
sane_exit()
published as 'Hewlett-Packard Photosmart_C4200_series #2'
end time is 500054
startup took 2.3125 secconds
server finished with error status -1, last error was 6: No such device or address

So I change it to start with --interface=wlan0, which gave me:

# netstat -l -n -p | grep -i airsane
tcp        0      0 192.168.1.120:8090      0.0.0.0:*               LISTEN      3423/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      3423/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      3423/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      3423/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      3423/airsaned
tcp        0      0 [omitted:IPv6]:8090 :::*                    LISTEN      3423/airsaned

In summary, I tried --interface=wlan0 and --interface=*, neither helped with Mopria Scan, and --interface=192.168.1.120 doesn't seem to work on OpenWrt.

cmangla commented 1 year ago

While doing the above exercises, I did enable debug and noticed:

airsaned[3694]: no device options at '/etc/airsane/options.conf'

Not sure if that indicates anything.

SimulPiscator commented 1 year ago

--interface=192.168.1.120 doesn't seem to work on OpenWrt.

Right, it wants interface device names, sorry.

airsaned[3694]: no device options at '/etc/airsane/options.conf'

That's not an issue, it just means there are no per-scanner options present in that file, or the file does not exist.

What might be interesting is that on my network, scanners are announced as _uscan._tcp whereas on your network they are announced as _uscan._tcp.local. Could that make a difference?

cmangla commented 1 year ago

What might be interesting is that on my network, scanners are announced as _uscan._tcp whereas on your network they are announced as _uscan._tcp.local. Could that make a difference?

Could be. Is it avahi that decides how that announcement happens?

SimulPiscator commented 1 year ago

Yes, it's avahi that decides. But maybe it's just your client software that displays the domain in addition to the service name? I did not find any avahi option (in /etc/avahi/avahi-daemon.conf, nor in the API) that would refer to anything like appending .localto the service name. (On Android, I'm using an app called "ServiceBrowser", on macOS, I'm using an app called "Discovery" to view network services.)

cmangla commented 1 year ago

Here is a screenshot of Service Browser on my Android phone (where Mopria Scan doesn't work): unnamed

SimulPiscator commented 1 year ago

Thanks for the screen shots. What strikes me is the large number of IPv6 addresses in the record, as visible on macOS. What if the Mopria Scan App picks one that doesn't work for some reason? It's not necessarily the one displayed by the ServiceBrowser app.

cmangla commented 1 year ago

That is a good point. Service Browser (Android) seems to pick only one ipv6 address, and it matches one of those shown in Discovery (macOS). I navigated to that one ipv6 address from my android phone browser and it got to the webpage of AirSane, so at least that connection is fine.

cmangla commented 1 year ago

Now I checked all four of the ipv6 addresses listed in macOS discovery, and I can get to all of them from my browser in my android phone.

cmangla commented 1 year ago

Mopria Scan also has an option to add a scanner manually. When I try to add http://pzwh:8090 it just says 'Error adding scanner'. But airsaned has some interesting log output:

Warning: Error 404 when requesting "/eSCL/ScannerCapabilities"
[2a02:8010:6807:10:f45d:edde:8e13:cbf] - - [30/Jan/2023:12:06:18 +0000] "GET /eSCL/ScannerCapabilities" 404 386 "" "okhttp/4.9.1"

Interesting?

SimulPiscator commented 1 year ago

In your case, the path to the scanner does not begin with /eSCL, so Mopria Scan cannot add it manually. You could enable the COMPATIBLE_PATH option to locate the first scanner at /eSCL.

cmangla commented 1 year ago

What is the path to my scanner?

I also tried the scanner address http://pzwh:8090/83e18d98-1fce-5380-9e93-0a9690a50292 but I got this in airsaned logs:

Warning: Error 404 when requesting "/83e18d98-1fce-5380-9e93-0a9690a50292/eSCL/ScannerCapabilities"
[2a02:8010:6807:10:f45d:edde:8e13:cbf] - - [30/Jan/2023:12:09:50 +0000] "GET /83e18d98-1fce-5380-9e93-0a9690a50292/eSCL/ScannerCapabilities" 404 423 "" "okhttp/4.9.1"
SimulPiscator commented 1 year ago

The path to your ScannerCapabilities would be /83e18d98-1fce-5380-9e93-0a9690a50292/ScannerCapabilities but Mopria Scan will always add an /eSCL after the address you type. If you use COMPATIBLE_PATH, you can just enter http://pzwh:8090.

cmangla commented 1 year ago

I updated the Airsaned-Openwrt package to accept the compatible-paths option, and added a bunch of missing options with defaults taken from your systemd config. Now, in Mopria Scan, I am able to add the scanner manually. So at least that works. But still Moria cannot find the scanner automatically.

cmangla commented 1 year ago

For reference and records, --compatible-paths option was exposed in the config in the OpenWrt package in https://github.com/cmangla/AirSane-openwrt/pull/7

cyanfish commented 11 months ago

I've been working on my own ESCL server and had a similar issue where I could add the scanner manually in Mopria Scan but it wasn't found automatically. Turns out Mopria has a check where it requires the UUID in the mDNS TXT record to exactly match the UUID in the ScannerCapabilities XML. I'm not sure if that's the issue here but I thought I'd mention it in case it's helpful.

SimulPiscator commented 11 months ago

Thanks for your comment. AirSane uses the same string variable to write both the mDNS TXT record, and the ScannerCapabilities XML UUID, so I don't think that's the issue.

SimulPiscator commented 11 months ago

I should add that I have not experienced any issues with recent versions of MopriaScan for Andoid.