Limits copying the get version response payload to the size of the out buffer.
Devices that return a larger payload pack the necessary version information at
the beginning of the payload.
Fixes: #1661
The "return error and hope the client resubmits the firmware again"
pattern is clunky. There are two plugins doing this now, and about to
be one more.
This adds FwupdRequest which provides a structured way of asking the
user to perform an action, e.g. to replug the device or to press a
special key or button.
This replaces much of the UpdateMessage and UpdateImage API although
it is still used internally. Clients capable of processing the new
DeviceRequest signal should add REQUESTS to their feature flags.
Also, this allows us go back to the old meaning of _NEEDS_BOOTLOADER,
which was "needs rebooting into a bootloader mode" rather than the
slightly weird "user needs to do something and resubmit request".
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.
The best way of not getting something wrong is to not require it in the first
place...
All plugins now use DeviceInstanceId-style quirk matches and we can just drop
the prefix in all files. We were treating HwId=, Guid= and DeviceInstanceId= in
exactly the same way -- they're just converted to GUIDs when building the silo!
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.
It is far too easy to forget to set FWUPD_DEVICE_FLAG_NO_GUID_MATCHING for new
plugins, and without it it all works really well *until* a user has two devices
of the same type installed at the same time and then one 'disappears' for hard
to explain reasons. Typically we only need it for replug anyway!
Explicitly opt-in to this rarely-required behaviour, with the default to just
use the physical and logical IDs. Also document the update behavior for each
plugin to explain why the flag is being used.
This allows you to have two identical Unifying plugged in without one of them
being hidden from the user, at the same time allowing a HIDRAW<->USB transition
when going to and from bootloader and runtime modes.
This removes the workaround added in 99eb3f06b6.
Fixes https://github.com/fwupd/fwupd/issues/2915
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.
When this is done, include:
* Including the hash
* Including anything that is not ABI stable in plugins yet
Suggested-by: Simon McVittie <smcv@debian.org>
The end year is legally and functionally redundant, and more importantly causes
cherry-pick conflicts when trying to maintain old branches. Use git for history.
This is a safer version of g_bytes_new_from_bytes() which returns a GError
if the offsets are invalid rather than emitting a critical warning.
This prevents a critical warning and potential crash when parsing invalid
bcm57xx firmware.
The idea here is that the device would not come back after it was restarted,
and skipping the attach in the engine was only working around the fact that the
ebitdo did not split out an ->attach() function.
We can't really blame it; we only decoupled the _IS_BOOTLOADER requirement
for ->attach() recently...
This also means we do the right thing when plugins call fu_device_add_flag()
directly, instead of just from a quirk file.
For instance, now `Flags = ~updatable` is a valid and useful thing to have and
allows us to remove the `Flags = None` hack.
Doing this unconditionally means we accidentally 'bleed' one device mode into
another in a non-obvious way. For instance, a device might have two operating
modes with different GUIDs. If firmware is supplied for both modes in the same
cabinet archive then we might accidentally match the 'wrong' firmware when
the daemon has observed a mode switch and added the counterpart GUIDs.
We only really need the counterpart GUIDs when switching between Jabra, 8bitdo
and DFU devices where the DFU bootloader VID:PID is not manually tagged with
`CounterpartGuid` in a quirk file. In the general case lets keep it simple to
avoid difficult to find bugs.
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.
This fixes a regression introduced by 2031ce3bf6
that leads to:
```
USB error on device 2dc8:5750 : No such device (it may have been disconnected) [-4]
```
This allows us to do three things:
* Fuzz the loader with `fwupdtool firmware-parse`
* Check the firmware *before* the hardware is put into bootloader mode
* Use FuChunk to build the 32 byte payload chunks