This allows us to replace the 'dfu-tool replace' with a much more
controlled 'fwupdtool firmware-patch' command that patches at a set of
specific offsets.
Drop in the new functionality into the existing firmware ->write()
vfuncs so that the image headers, footers and/or checksums are correct.
We were calling g_module_symbol() 2703 times, which is actually more
expensive than you'd think.
It also means the plugins are actually what we tell people they are:
A set of vfuncs that get run. The reality before that they were dlsym'd
functions that get called at pretty random times.
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.
Note that g_assert() should not be used in unit tests, since it is a
no-op when compiling with G_DISABLE_ASSERT. Use g_assert() in production
code, and g_assert_true() in unit tests.
See https://github.com/fwupd/fwupd/issues/3790
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.
Some Poly usb devices report zero in the bwPollTimeout field of
GET_STATUS request. The host can issue the next DFU_DNLOAD
request immediately without any delay.
Introduced a private flag to skip the default DNLOAD timeout
(5ms) fix. It could remarkably reduce the firmware downloading
time taking into account the large firmware (more than 500MB).
The CustomFlags feature is a bit of a hack where we just join the flags
and store in the device metadata section as a string. This makes it
inefficient to check if just one flag exists as we have to split the
string to a temporary array each time.
Rather than adding to the hack by splitting, appending (if not exists)
then joining again, store the flags in the plugin privdata directly.
This allows us to support negating custom properties (e.g. ~hint) and
also allows quirks to append custom values without duplicating them on
each GUID match, e.g.
[USB\VID_17EF&PID_307F]
Plugin = customflag1
[USB\VID_17EF&PID_307F&HUB_0002]
Flags = customflag2
...would result in customflag1,customflag2 which is the same as you'd
get from an enumerated device flag doing the same thing.
This will improve the pre-commit hook coverage.
For dfu: waive pre-commit checks for internal header file
This is internal to the plugin not to the library.
Until gi-docgen is declared stable support either of them.
This effectively means that hand builds and CI builds will use
gi-docgen, but distro builds use gtk-doc-tools.
fu_dfu_tool_get_default_device returns a newly create FuDfuDevice
'device'; but since it is marked as g_autoptr, it is destroyed when
leaving the scope and the caller receives garbage.
So steal the pointer before leaving the scope.
,----
| ==697985== Invalid read of size 8
| ==697985== at 0x4B50F49: g_type_check_instance_is_fundamentally_a (gtype.c:4080)
| ==697985== by 0x4B3A988: g_object_unref (gobject.c:3421)
| ==697985== by 0x406CF3: glib_autoptr_clear_GObject (gobject-autocleanups.h:27)
| ==697985== by 0x406DD5: glib_autoptr_clear_FwupdDevice (gusb-autocleanups.h:17)
| ==697985== by 0x406E9C: glib_autoptr_clear_FuDevice (fu-device.h:18)
| ==697985== by 0x406EE3: glib_autoptr_clear_FuUsbDevice (fu-usb-device.h:22)
| ==697985== by 0x406F6A: glib_autoptr_clear_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x406F88: glib_autoptr_cleanup_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x40898D: fu_dfu_tool_read (fu-dfu-tool.c:577)
| ==697985== by 0x407518: fu_dfu_tool_run (fu-dfu-tool.c:162)
| ==697985== by 0x4097E0: main (fu-dfu-tool.c:959)
| ==697985== Address 0x67fbfe0 is 640 bytes inside a block of size 672 free'd
| ==697985== at 0x48430E4: free (vg_replace_malloc.c:755)
| ==697985== by 0x4BD124C: g_free (gmem.c:199)
| ==697985== by 0x4BEB76F: g_slice_free1 (gslice.c:1180)
| ==697985== by 0x4B4FDBB: g_type_free_instance (gtype.c:1993)
| ==697985== by 0x406CF3: glib_autoptr_clear_GObject (gobject-autocleanups.h:27)
| ==697985== by 0x406DD5: glib_autoptr_clear_FwupdDevice (gusb-autocleanups.h:17)
| ==697985== by 0x406E9C: glib_autoptr_clear_FuDevice (fu-device.h:18)
| ==697985== by 0x406EE3: glib_autoptr_clear_FuUsbDevice (fu-usb-device.h:22)
| ==697985== by 0x406F6A: glib_autoptr_clear_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x406F88: glib_autoptr_cleanup_FuDfuDevice (fu-dfu-device.h:19)
| ==697985== by 0x407762: fu_dfu_tool_get_default_device (fu-dfu-tool.c:191)
| ==697985== by 0x408736: fu_dfu_tool_read (fu-dfu-tool.c:592)
| ==697985== Block was alloc'd at
| ==697985== at 0x484086F: malloc (vg_replace_malloc.c:380)
| ==697985== by 0x4BD4938: g_malloc (gmem.c:106)
| ==697985== by 0x4BEC1F4: g_slice_alloc (gslice.c:1069)
| ==697985== by 0x4BEC85D: g_slice_alloc0 (gslice.c:1095)
| ==697985== by 0x4B5511A: g_type_create_instance (gtype.c:1893)
| ==697985== by 0x4B3CB8C: g_object_new_internal (gobject.c:1939)
| ==697985== by 0x4B3E107: g_object_new_valist (gobject.c:2282)
| ==697985== by 0x4B3E63C: g_object_new (gobject.c:1782)
| ==697985== by 0x40B0CF: fu_dfu_device_new (fu-dfu-device.c:571)
| ==697985== by 0x407723: fu_dfu_tool_get_default_device (fu-dfu-tool.c:230)
| ==697985== by 0x408736: fu_dfu_tool_read (fu-dfu-tool.c:592)
| ==697985== by 0x407518: fu_dfu_tool_run (fu-dfu-tool.c:162)
`----
This prevents problems when cross compiling. Using help2man is now also of
limited use; if we can just tell the user to use --help we do not need to keep
the manual in sync.
It also allows us to drop the several other supporting files that we use when
the help2man output isn't actually that useful.
Fixes https://github.com/fwupd/fwupd/issues/3025