We only had to pile everything into the src/fuzzing/firmware directory
because honggfuzz could not cope with more than one input path.
This way each plugin is self contained and easy to copy.
Also, install the fuzzing builder objects as this fixes the installed
tests when srcdir does not exist.
Based on a patch by Jan Tojnar <jtojnar@gmail.com>, many thanks.
This allows us to override the location we load data files from, which
allows us to do more kinds of installed tests in the future.
Also, move the global data/tests content into the place that it is used
as it was getting impossible to manage.
Quite a few plugins are using a FuDeviceLocker to detach then attach in
the error path, and finding them isn't easy as we explicitly cast to a
FuDeviceLockerFunc.
For sanity, just provide both symbols so we can do the right thing in
both cases. It seems like a sensible thing to allow.
Fixes https://github.com/fwupd/fwupd/issues/3771
It's actually quite hard to build a front-end for fwupd at the moment
as you're never sure when the progress bar is going to zip back to 0%
and start all over again. Some plugins go 0..100% for write, others
go 0..100% for erase, then again for write, then *again* for verify.
By creating a helper object we can easily split up the progress of the
specific task, e.g. write_firmware().
We can encode at the plugin level "the erase takes 50% of the time, the
write takes 40% and the read takes 10%". This means we can have a
progressbar which goes up just once at a consistent speed.
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.
Do not manually call config setup before adding the parent.
The ->setup() action is called on children explicitly in fu_device_setup()
after the parent device has all the required properties.
Fixes https://github.com/fwupd/fwupd/issues/3364
This makes a lot more sense; we can parse a firmware and export the same XML
we would use in a .builder.xml file. This allows us to two two things:
* Check we can round trip from XML -> binary -> XML
* Using a .builder.xml file we can check ->write() is endian safe
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.
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>
That giant uint64_t isn't looking so big now, and we'll want to add even more
to it in the future. Split out some private flags that are never useful to the
client, although the #defines will have to remain until we break API again.
The fprint daemon only keeps the device open for 5 seconds and then releases it,
which seems like a small window to hit.
But! We're asking the user to authenticate with the same device we're about to
upgrade so a different part of the stack woke up the hardware just before we're
about to deploy an update onto it.
Just retry a few times to make sure the device is idle. Use a flag to prevent
accidentally causing regressions in other plugins.
Fixes https://github.com/fwupd/fwupd/issues/2650
The GLib g_byte_array_set_size() function does not zero the contents if the
array size is larger, which leads to unpredictable output when using valgrind.
The FWUPD_INSTALL_FLAG_FORCE flag has really unclear semantics, and ignoring a
file CRC, checksum or model ID should only be done when using fwupdtool actually
debugging a plugin or firmware parser.
Use the existing --force flag when we want a "gentle nudge" like reuploading
previously processed reports.
At the moment there are commands to convert one file format to another, but not
to 'merge' or alter them. Some firmware files are containers which can store
multiple images, each with optional id, idx and addresses.
This would allow us to, for instance, create a DfuSe file with two different
raw files that are flashed to different addresses on the SPI flash. It would
also allow us to create very small complicated container formats for fuzzing.
This can be used by writing a `firmware.builder.xml` file like:
<?xml version="1.0" encoding="UTF-8"?>
<firmware gtype="FuBcm57xxFirmware">
<version>1.2.3</version>
<image>
<version>4.5.6</version>
<id>header</id>
<idx>456</idx>
<addr>0x456</addr>
<filename>header.bin</filename>
</image>
<image>
<version>7.8.9</version>
<id>payload</id>
<idx>789</idx>
<addr>0x789</addr>
<data>aGVsbG8=</data>
</image>
</firmware>
...and then using something like:
# fwupdtool firmware-convert firmware.builder.xml firmware.dfu builder dfu
This is nice in theory, until you need to look at the bootloader status of the
parent, or of a different device entirely. Handle this in plugins for the few
cases we care about and stop setting or clearing IS_BOOTLOADER manually just to
get the vfuncs to be run.
Note: I do not think we want to use cleanup() for attaching devices not in
bootloader states -- as cleanup is only run at the end of the composite update.
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.
We don't actually need either of the things it provides (looking up in source
and built, and converting to an absolute path) so just replace it with
g_build_filename() instead.
This also has the advantage that it does the right thing on Windows.