Hardware-associated snaps - Snap Store search by hardware signature

Unfortunately, many (or most) hardware devices need device-model-specific code or data, known as driver and ideally provided by the hardware manufacturer. Drivers in RPM or DEB packages need to be individually cretaed for each Linux distribtion, where as Snaps are independent of the Linux distribution where they get installed. Snao is therefore a nice format for manufacturer being able to provide hardware drivers at a low effort and low cost.
To make it easy (or even fully automatic) to find and install the correct drivers, the driver Snaps need to get associated to the hardware models they support, by having an appropriate data set in each Snap. The Snap Store would need to take the hardware signature of each Snap which it carries and so be able to answer a search for the driver for a given hardware model (= all Snaps which are associated with this model).
A client then could either trigger a hardware-model-based Snap Store Search (and Snap installaion in case of success) if it detects a new hardware device, or in the Snap Store client app (or in GNOME Control Center) there can be a list of detected/discovered hardware with “Search for driver” buttons.
This should at least work for all-userspace-drivers, like for printers and scanners for example.
What is needed is:

  • Each Snap containing drivers or other hardware-model-specific code needs to provide a (text) file containing the hardware signatures for each supported device, ideally generated by a script during build of the Snap. Note that one Snap can support thousands of devices, like Gutenprint for example.
  • If a Snap is uploaded into the Snap Store, the Snap Store server has to check whether it contains a hardware table and if yes, add the entries to a database (and naturally remove the entries of a Snap which gets removed or replaced)
  • The Snap Store server’s API for clients should support a search by hardware signature: The client calls the appropriate function with a hardware signature and gets back a list of the Snaps which provide that signature according to the database.

For the design of the hardware table in the Snaps and the database on the Snap Store server one must take into account that different types of hardware can have different types of signatures.
Printers have for example device IDs, containing Make, Model, Page Description Languages, usually on USB, but also sometimes on SNMP and IPP, Make/Model always identifies them well enough, but USB Vendor and Product IDs can be the same for several different models.
USB (dumb) scanners can be identified by USB Vendor and Product IDs, for example.
It can also make sense to wildcards or regexps in the hardware table of a snap, so a manufacturer could easily cover all their devices or a certain series of their devices.



Device signatures of printers

This is a typical device ID for a printer:

MDL:HP OfficeJet Pro 8710;

It is a standard which came with parallel port printers but it is also used on all USB printers and also on many network printers. It comes out as a single line, not containing newline characters. I have split it into several lines for easier readability here in the forum.
The ID is a dictionary, consisting of several key-value pairs. One has a key, colon, then the value and after that a semicolon, which separates from the next keys. The semicolon after the last value, at the very end of the ID is missing sometimes. This also implies that key cannot contain a colon and values cannot contain a semicolon.
For identifying a printer model one usually uses the MFG and MDL fields, manufacturer and model. The SN field is the serial number and is not important for us, selecting the driver, but very useful if you have several printers of the same model and keep them connected always to the same print queue. The CMD field lists the Page Description Languages (PDLs) which the printer understands, this helps associating generic drivers or discovering the presence of a PostScript add-on module. Note also that sometimes the fields are named MANUFACTURER, and MODEL.
The example is from the HP OfficeJet Pro 8710, a multi-function printer made by HP.
You can see the device ID of your printer, depending on how it is connected, try one of these commands:

sudo /usr/lib/cups/backend/usb

If your printer advertises itself via DNS-SD in the network, you can find its DNS-SD record with the diagnostic tools of Avahi: avahi-discover and avahi-browse. There are fields named usb_MFG, usb_MDL, and usb_CMD showing the appropriate fields of the device ID, but there are also several other fields showing manufacturer, model, and PDLs.
If you run

sudo /usr/lib/cups/backend/dnssd

You get information extracted from the DNS-SD record, especially the device ID is an artificial composition of information gathered from the DNS-SD record.
Here you see that manufacturer and model can be extracted from printers in different ways, sometimes the output differs a little bit, for example upper vs. lower case, HP vs. Hewlett-Packard, … So do all comparisons after “normalising” the strings, replacing each sequence of non alphanumeric characters by a single space, put a space into each letter/number transition, make all letters lower case, replace Hewlett-Packard by HP, cut manufacturer name from model field. This will not cause mis-recognitions, as no manufacturer would release two products where the name differs only by upper/lower case or non-alphanumeric characters. The hardware signature list of the snap could already contain normalised names.
Do not try to identify printers by their numeric USB Vendor and Product IDs, there was already a big bunch of Epson printers which had all the same pair of Vendor and Product ID.

Device signatures of scanners
SANE associates USB scanners with their drivers (SANE backends) via the numeric USB Vendor and Product IDs (the ones which I do not recommend to use for printers) and this seems to have worked well all the times. I do not have a scan-only scanner (the ones which do not have a test page generation unit under the scanner mechanics) at hand, as these are the so-called “dumb” USB scanners which are typically handled this way by SANE.
For multi-function devices the SANE backends often identify the device by its printing part (methods above), network and IPP-over-USB devices via DNS-SD.
You can see SANE’s device signatures by running

scanimage -L

You get one output line for each found valid scanner/SANE-backend pair. The lines are SANE URIs and usually contain the hardware ID infor with which the scanner got associated, like USB Vendor/Product ID, IPP or HTTP URI, …
The backends for “dumb” scanners usually identify with USB Vendor/Product, HPLIP uses Manufacturer and Model as it only supports printer/scanner multi-function devices, AirPrint (eSCL) scanners are identified by a HTTP URI resource part “/eSCL” and also by DNS-SD record fields.
For manufacturer and model names in device tables the same as for printers is valid. USB Vendor/Product IDs are simply numeric and should be listed in the commonly used hex format.

How would other applications use these snapped drivers?

I might be missing some context on how userspace drivers normally work. Do they provide shared libraries for other applications to use or do they create new devices?

I can at least speak for printers and scanners. A snapped printer driver starts a daemon which emulates an IPP (Internet Printing Protocol) printer with driverless printing capabilities (the Printer Application). Jobs sent to this emulated printer are converted to the physical printers’s native language and sent on to the physical printer, which usually is not an IPP printer by itself, it can be on USB or accessed through the network with LPD or AppSocket communication methods.
The emulated IPP printer advertises itself via DNS-SD on localhost and CUPS (and/or cups-browsed) automatically picks up this printer and makes it available to the applications. CUPS/cups-browsed automatically creates the PPD file for the local print queue by querying the emulated IPP printer via IPP.
For a scanner we have a similar concept, here we have a Scanner Application which emulates an IPP scanner which forwards scanning requests to the physical scanner, converting them into the scanner’s language and returns the scanned images. Also thes Scanner Applications advertise themselves via DNS-SD on localhost.
Client application will use SANE with a backend doing IPP scanning. The backend polls the capabilities of the emulated scanner via IPP so that the application can display user-settable options.
For multi-function printers (printer and scanner in one) we have an emulated IPP multi-function device.

1 Like

All list entries should have manufacturer and model
Even if the hardware signature does not contain the manufacturer and model name of the device, as for example with USB scanners, the device table of the snap should contain manufacturer and model in addition to whatever is needed to identify the device by its signature, as user could search for a hardware device manually, by entering manufacturer and model into the search line of the Snap Store, for example when deciding which hardware to buy.

Note that hardware-associated snaps could not only be drivers for a certain piece of hardware but also applications specific for a certain class of devices, like a video player for Raspberry Pi, a firmware, updater, configuration tool, … A search for a device should show all snaps which a specific to the device/device class.

Another possible class of drivers are graphics card drivers, but, unfortunately, I do not know how to obtain signatures and how to snap such drivers.

There’s this related proposal regarding GPU drivers: GPU Support Proposal