Sometimes plugins need to retry various commands send to hardware, either due
to unreliable transfers (e.g. using USB bulk) or from slightly quirky hardware.
Between them they seem to get various things wrong; either the error messages
are repeated and thus difficult to parse, or they just get the memory handling
of `g_propagate_prefixed_error()` wrong.
Providing sane helpers we can reduce the amount of boilerplate. Additionally
we can support a 'reset' function that can try to automatically recover the
hardware for specific error domains and codes.
If we do not ->open() the device (e.g. because it uses a parent device to proxy
writes) then the child never gets a DeviceID which causes all kinds of issues.
If we say that the version format should be the same for the `version_lowest`
and the `version_bootloader` then it does not always make sense to set it at
the same time.
Moving the `version_format` to a standalone first-class property also means it
can be typically be set in the custom device `_init()` function, which means we
don't need to worry about *changing* ther version format as set by the USB and
UDev superclass helpers.
Some hardware does not handle upgrading from version 1.2.2 to 1.2.4 and instead
needs to be upgraded from 1.2.2->1.2.3->1.2.4 so that on-device metadata can be
migrated correctly.
Add a new per-device flag `install-all-releases` which causes the daemon to not
skip directly to the newest release. This is designed to be set from a quirk
file.
This can obviously only be used for devices that can apply firmware "live" and
thus do not need a reboot or system shutdown to actually apply the firmware.
This also needs the cabinet archive to ship multiple versions of the firmware,
and for the metainfo.xml file to refer to multiple release objects.