Before this change calling FuUsbDevice->open() opened the device, and
also unconditionally added various GUIDs and InstanceIDs which we
normally do in setup.
Then fu_device_setup() would call the FuSubclass->setup() vfunc which
would have no way of either opting out of the FuUsbDevice->setup()-like
behaviour, or controlling if the parent class ->setup is run before or
after the subclass setup.
Split up FuUsbDevice->open() into clear ->open() and ->setup() phases
and add the parent class calls where appropriate.
This means that ->setup() now behaves the same as all the other vfuncs.
This allows us to 'nest' firmware formats, and removes a ton of duplication.
The aim here is to deprecate FuFirmwareImage -- it's almost always acting
as a 'child' FuFirmware instance, and even copies most of the vfuncs to allow
custom types. If I'm struggling to work out what should be a FuFirmware and
what should be a FuFirmwareImage then a plugin author has no hope.
For simple payloads we were adding bytes into an image and then the image into
a firmware. This gets really messy when most plugins are treating the FuFirmware
*as* the binary firmware file.
The GBytes saved in the FuFirmware would be considered the payload with the
aim of not using FuFirmwareImage in the single-image case.
Devices may want to support more than one protocol, and for some devices
(e.g. Unifying peripherals stuck in bootloader mode) you might not even be able
to query for the correct protocol anyway.
This allows a device subclass to call the parent method after doing an initial
action, or even deliberately not call the *generic* parent method at all.
It also simplifies the plugins; you no longer have to remember what the plugin
is deriving from and accidentally clobber the wrong superclass method.
At the moment FuChunks are sometimes mutable, and sometimes immutable, and it's
all a bit too low level for comfort.
Before we can do any kind of optimisation or verification we need plugins to
stop reading directly from the C structure. The aim here is to make FuChunk
optionally mutable without making assumptions about the memory model, and also
to be able to introspect it for the docs.
Quite a few plugins use HID commands to communicate with the hardware. At the
mement we have ~6 implementations of SET_REPORT and are soon to add one more.
Move this into common code.
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 plugins have devices with more than one protocol. Logically the protocol
belongs to the device, not the plugin, and in the future we could use this to
further check firmware that's about to be deployed.
This is also not exported into libfwupd (yet?) as it's remains a debug-feature
only -- protocols are not actually required for devices to be added.
There are several subtle bugs in various places in fwupd caused by not treating
user-provided offsets into buffers as unsafe. As fwupd runs as root we have to
assume that all user firmware is evil, and also that devices cannot be trusted.
Make a helper to put all the logic into one place and convert all users.
In many plugins we've wanted to use ->prepare_firmware() to parse the firmware
ahead of ->detach() and ->write_firmware() but this has the limitation that it
can only return a single blob of data.
For many devices, multiple binary blobs are required from one parsed image,
for instance providing signatures, config and data blobs that have to be pushed
to the device in different way.
This also means we parse the firmware *before* we ask the user to detach.
Break the internal FuDevice API to support these firmware types as they become
more popular.
This also allows us to move the Intel HEX and SREC parsing out of the dfu plugin
as they are used by a few plugins now, and resolving symbols between plugins
isn't exactly awesome.
This leads to madness, as some formats are supersets of the detected types,
e.g. 'intel-me' is detected as 'quad' and 'bcd' is detected as 'pair'.
Where the version format is defined in a specification or hardcoded in the
source use a hardcoded enum value, otherwise use a quirk override.
Additionally, warn if the version does not match the defined version format