Release fwupd 1.2.4

-----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJcVFf9AAoJEBesuo36lw4XAxkH/32Z7Q/ZzqSRR8bk9ItC8rai
 CX+51/v0jeX/BLXkjPRhAs1SpdMZSq0Te/6sGgPYEIzRZC60GexlIYYJAIlRWiw8
 GMg3nDxa7cCtnNFPPG+407uoriepI8dzyOM9ueeTf5/bC4f/4ofimMVsthSvYbHG
 4SQIwOitrP2yZt6lb1ZtzZqLn22vrEqBM/T1yO/dkc8Oo1nPCkbQiv8UmLOIG12D
 2EkFUTMyG9h0rPjGBLBW/4C4OdfUhg2acBPzaLRkLn1r/tmVmw5uJdbkeJGxh7bg
 1ooORP6SEqRWWAjKRhdYkson0lCF5i1Qh+txt2amtSmjOoxSp8oKo7amEBo2VJY=
 =9uvl
 -----END PGP SIGNATURE-----

Merge tag '1.2.4' into debian

Release fwupd 1.2.4
This commit is contained in:
Mario Limonciello 2019-02-06 20:29:48 -06:00
commit 996490ac67
371 changed files with 18329 additions and 6361 deletions

5
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,5 @@
Type of pull request:
- [ ] New plugin (Please include [new plugin checklist](https://github.com/hughsie/fwupd/wiki/New-plugin-checklist))
- [ ] Code fix
- [ ] Feature
- [ ] Documentation

1
.gitignore vendored
View File

@ -11,6 +11,7 @@
/prime
/stage
/snap/.snapcraft
/libxmlb
/*.deb
/*.ddeb
/*.changes

0
.gitmodules vendored Normal file
View File

893
NEWS
View File

@ -1,893 +0,0 @@
Version 1.1.4
~~~~~~~~~~~~~
Released: 2018-11-07
New Features:
- Stop any running daemon over dbus before loading engine (Mario Limonciello)
Bugfixes:
- Use HTTPS_PROXY if set (Richard Hughes)
- Make the dell-dock plugin more robust in several ways (Mario Limonciello)
- Adjust EVB board handling (Mario Limonciello, RyanChang)
Version 1.1.3
~~~~~~~~~~~~~
Released: 2018-10-12
New Features:
- Add a plugin for an upcoming Dell USB-C dock (Mario Limonciello)
- Add support for devices to show an estimated flash time (Mario Limonciello)
- Add support for Realtek USB devices using vendor HID and HUB commands (Richard Hughes)
- Allow firmware files to depend on versions from other devices (Richard Hughes)
Bugfixes:
- Adjust panamera ESM update routine for some reported issues (Mario Limonciello)
- Check the amount of free space on the ESP before upgrading (Richard Hughes)
- Don't show devices pending a reboot in GetUpgrades (Mario Limonciello)
- Fix possible crash in the thunderbolt-power plugin (Richard Hughes)
- Make various parts of the daemon thread-safe (Richard Hughes)
- Redirect all debugging output to stderr instead of stdout (Mario Limonciello)
- Run the Dell plugin initialization after the UEFI plugin (Mario Limonciello)
- Stop showing the current release during updates in fwupdmgr (Mario Limonciello)
- Update all sub-devices for a composite update (Mario Limonciello)
Version 1.1.2
~~~~~~~~~~~~~
Released: 2018-09-10
New Features:
- Add a new device flag "ignore-validation" that will override checks (Mario Limonciello)
- Add a new plugin to enumerate EC firmware (Richard Hughes)
- Add a new plugin to update NVMe hardware (Richard Hughes, Mario Limonciello)
- Add a plugin for updating using the flashrom command line tool (Richard Hughes)
- Allow the device list to take care of waiting for the device replug (Richard Hughes)
- Allow updating just one specific device from the command line (Richard Hughes)
- Allow upgrades using a self-signed fwupd.efi binary (Richard Hughes)
- Download firmware if the user specifies a URI (Richard Hughes)
- Include serial number in daemon device output when trusted (Mario Limonciello)
- Notify all plugins of device removals through a new vfunc (Mario Limonciello)
- Use boltd force power API if available (Mario Limonciello)
Bugfixes:
- Add an install hook for classic snap (Mario Limonciello)
- Allow forcing installation even if no AC power is applied (Mario Limonciello)
- Allow using --force to ignore version_lowest (Mario Limonciello)
- Always use the same HardwareIDs as Windows (Richard Hughes)
- Check the device state before assuming a fake DFU runtime (Richard Hughes)
- Copy over parent GUIDs from other plugin donors (Mario Limonciello)
- Detect location of python3 interpreter (Mario Limonciello)
- Do not add udev devices after a small delay (Richard Hughes)
- Don't fail to run if compiled without GPG/PKCS7 (Salud Lemus, Mario Limonciello)
- Fix a segfault in fwupdtool caused by cleanup of USB plugins (Mario Limonciello)
- Implement the systemd recommendations for offline updates (Richard Hughes)
- Improve performance when reading keys from the quirk database (Richard Hughes)
- Remove children of devices when the parent is removed (Mario Limonciello)
- Rewrite synapticsmst to use modern error handling (Mario Limonciello)
- Rewrite the unifying plugin to use the new daemon-provided functionality (Richard Hughes)
- Show a time estimate on the progressbar after an update has started (Mario Limonciello)
Version 1.1.1
~~~~~~~~~~~~~
Released: 2018-08-13
New Features:
- Add support for the Synaptics Panamera hardware (Mario Limonciello)
- Add validation for Alpine and Titan Ridge (Andrei Emeltchenko, Mika Westerberg)
- Improve the Redfish plugin to actually work with real hardware (Gary Lin)
Bugfixes:
- Allow different plugins to add the same device (Richard Hughes)
- Allow flashing unifying devices in recovery mode (Richard Hughes)
- Allow running synapticsmst on non-Dell hardware (Mario Limonciello)
- Check the ESP for sanity at at startup (Richard Hughes, Mario Limonciello)
- Do not hold hidraw devices open forever (Richard Hughes)
- Don't override _FORTIFY_SOURCE when building the EFI binary (Richard Hughes)
- Don't show passwords in fwupdmgr (Richard Hughes, Mario Limonciello)
- Fix a potential segfault in smbios data parsing (Mario Limonciello)
- Fix encoding the GUID into the capsule EFI variable (Mario Limonciello)
- Fix various bugs when reading the thunderbolt version number (Mika Westerberg)
- Reboot synapticsmst devices at the end of flash cycle (Mario Limonciello)
- Show status messages when the daemon is initializing (Mario Limonciello)
- Show the correct title when updating devices (Richard Hughes, Mario Limonciello)
- Show the reasons that plugins are not run on the CLI (Mario Limonciello)
- Use localedir in po/make-images (Jan Tojnar)
Version 1.1.0
~~~~~~~~~~~~~
Released: 2018-07-11
New Features:
- Add a initial Redfish support (Richard Hughes)
- Add a tool to mimic the original fwupdate CLI interface (Richard Hughes)
- Allow devices to assign a plugin from the quirk subsystem (Richard Hughes)
- Change the quirk file structure to be more efficient (Richard Hughes)
- Merge fwupdate functionality into fwupd (Richard Hughes, Mario Limonciello)
- Run a plugin vfunc before and after all the composite devices are updated (Richard Hughes)
- Support more Wacom tablets (Richard Hughes)
Bugfixes:
- Add release information for locked devices (Richard Hughes)
- Allow building with older meson (Mario Limonciello)
- Detect the EFI system partition location at runtime (Mario Limonciello)
- Do not use 8bitdo bootloader commands after a successful flash (Richard Hughes)
- Enable accesing downloaded files in flatpak and snap (Mario Limonciello)
- Fix a potential buffer overflow when applying a DFU patch (Richard Hughes)
- Fix downgrading older releases to devices (Richard Hughes)
- Fix flashing devices that require a manual replug (Richard Hughes)
- Fix several small memory leaks in various places (Richard Hughes)
- Fix the retrieval of Redfish version (Gary Lin)
- Fix unifying failure to detach when using a slow host controller (Richard Hughes)
- Set the Wacom device status when erasing and writing firmware (Richard Hughes)
- Show errors in the CLI if unable to access directory (Mario Limonciello)
- Use the parent device name for Wacom sub-modules (Richard Hughes)
Version 1.0.8
~~~~~~~~~~~~~
Released: 2018-06-07
New Features:
- Add an plugin to update some future Wacom tablets (Richard Hughes)
- Add 'fwupdmgr get-topology' to show logical device tree (Richard Hughes, Mario Limonciello)
- Add support for creating a flatpak (Richard Hughes)
- Add support for creating a snap (Mario Limonciello, Richard Hughes)
- Add support for Motorola S-record files (Richard Hughes)
- Add the Linux Foundation public GPG keys for firmware and metadata (Richard Hughes)
- Show a translated warning when the server is limiting downloads (Richard Hughes)
Bugfixes:
- Add a firmware diagnostic tool called fwupdtool (Richard Hughes, Mario Limonciello)
- Adjust all licensing to LGPL 2.1+ (Mario Limonciello)
- Allow installing more than one firmware using 'fwupdmgr install' (Richard Hughes)
- Allow specifying hwids with OR relationships (Richard Hughes)
- Do not call fu_plugin_init() on blacklisted plugins (Richard Hughes)
- Do not require libcolorhug to build (Richard Hughes)
- Fix a crash in libfwupd where no device ID is set (Richard Hughes)
- Fix a potential DoS in libdfu by limiting holes to 1MiB (Richard Hughes)
- Fix a segfault that sometimes occurs during cleanup of USB plugins (Mario Limonciello)
- Fix Hardware-ID{0,1,2,12} compatibility with Microsoft (Gergely Risko)
- Hide devices that aren't updatable by default in fwupdmgr (Mario Limonciello)
- Search all UEFI GUIDs when matching hardware (Richard Hughes, Mario Limonciello)
- Stop matching Nintendo Switch Pro in the 8bitdo plugin (Mario Limonciello)
Version 1.0.7
~~~~~~~~~~~~~
Released: 2018-04-30
New Features:
- Add enable-remote and disable-remote commands to fwupdmgr (Richard Hughes)
- Add fu_plugin_add_compile_version() for libraries to use (Richard Hughes)
- Allow requiring specific versions of libraries for firmware updates (Richard Hughes)
- If no remotes are enabled try to enable the LVFS (Mario Limonciello)
- Show a warning with interactive prompt when enabling a remote (Richard Hughes)
Bugfixes:
- Check that EFI system partition is mounted before update (Mario Limonciello)
- Disable synapticsmst remote control on failure (Sjoerd Simons)
- Don't recoldplug thunderbolt to fix a flashing failure (Mario Limonciello)
- Fix SQL error when running 'fwupdmgr clear-offline' (Richard Hughes)
- Improve the update report message (Mario Limonciello)
- Only enumerate Dell Docks if the type is known (Sjoerd Simons)
- Only run certtool if a new enough gnutls is present (Mario Limonciello)
- Prevent a client crash if the daemon somehow sends invalid data (Richard Hughes)
- Reboot after scheduling using logind not systemd (Richard Hughes)
- Use the right encoding for the label in make-images (Niels Ole Salscheider)
Version 1.0.6
~~~~~~~~~~~~~
Released: 2018-03-12
New Features:
- Add bash completion for fwupdmgr (Mario Limonciello)
- Add support for newest Thunderbolt chips (Andrei Emeltchenko)
- Allow all functions that take device arguments to be prompted (Mario Limonciello)
- Allow devices to use the runtime version when in bootloader mode (Richard Hughes)
- Allow overriding ESP mount point via conf file (Mario Limonciello)
- Delete any old fwupdate capsules and efivars when launching fwupd (Richard Hughes)
- Generate Vala bindings (Robert Ancell)
Bugfixes:
- Allow ctrl-d out of the prompt for devices (Mario Limonciello)
- Allow to create package out of provided binary (Andrei Emeltchenko)
- Correct handling of unknown Thunderbolt devices (Yehezkel Bernat)
- Correctly detect new remotes that are manually copied (Richard Hughes)
- Fix a crash related to when passing device to downgrade in CLI (Mario Limonciello)
- Fix running the self tests when no fwupd is installed (Richard Hughes)
- Fix Unifying signature writing and parsing for Texas bootloader (Ogier Bouvier)
- Only send success and failure reports to the server (Richard Hughes)
- Use a CNAME to redirect to the correct CDN for metadata (Richard Hughes)
- Use a longer timeout when powering back the Thunderbolt device (Richard Hughes)
Version 1.0.5
~~~~~~~~~~~~~
Released: 2018-02-14
New Features:
- Offer to reboot when processing an offline update (Richard Hughes)
- Report the efivar, libsmbios and fwupdate library versions (Mario Limonciello)
- Report Thunderbolt safe mode and SecureBoot status (Mario Limonciello)
- Show the user a URL when they report a known problem (Richard Hughes)
- Support split cabinet archives as produced by Windows Update (Richard Hughes)
Bugfixes:
- Be more careful deleting and modifying device history (Richard Hughes)
- Clarify which devices don't have upgrades (Mario Limonciello)
- Ensure the Thunderbolt version is xx.yy (Richard Hughes)
- Fix a daemon warning when using fwupdmgr get-results (Richard Hughes)
- Fix crasher with MST flashing (Mario Limonciello)
- Fix DFU detach with newer releases of libusb (Richard Hughes)
- Include the device VID and PID when generating the device-id (Richard Hughes)
- Set the RemoteId when using GetDetails (Richard Hughes)
- Stop matching 8bitdo DS4 controller VID/PID (Mario Limonciello)
- Use help2man for dfu-tool and drop docbook dependencies (Mario Limonciello)
- Use ngettext for any strings with plurals (Piotr Drąg)
- Use the default value if ArchiveSizeMax is unspecified (Richard Hughes)
Version 1.0.4
~~~~~~~~~~~~~
Released: 2018-01-25
New Features:
- Add D-Bus methods to get and modify the history information (Richard Hughes)
- Allow the user to share firmware update success or failure (Richard Hughes)
- Ask the user to refresh metadata when it is very old (Richard Hughes)
- Store firmware update success and failure to a local database (Richard Hughes)
Bugfixes:
- Add a device name for locked UEFI devices (Mario Limonciello)
- Allow each plugin to opt-in to the recoldplug action (Richard Hughes)
- Fix firmware downloading using gnome-software (Richard Hughes)
- Fix UX capsule reference to the one specified in efivar (Mario Limonciello)
- Never add two devices to the daemon with the same ID (Richard Hughes)
- Rescan supported flags when refreshing metadata (Richard Hughes)
Version 1.0.3
~~~~~~~~~~~~~
Released: 2018-01-09
New Features:
- Add a new plugin to add support for CSR "Driverless DFU" (Richard Hughes)
- Add initial SF30/SN30 Pro support (Mario Limonciello)
- Support AppStream metadata with relative <location> URLs (Richard Hughes)
Bugfixes:
- Add more metadata to the user-agent string (Richard Hughes)
- Block owned Dell TPM updates (Mario Limonciello)
- Choose the correct component from provides matches using requirements (Richard Hughes)
- Do not try to parse huge compressed archive files (Richard Hughes)
- Fix a double-free bug in the Udev code (Philip Withnall)
- Handle Thunderbolt "native" mode (Yehezkel Bernat)
- Use the new functionality in libgcab >= 1.0 to avoid writing temp files (Richard Hughes)
Version 1.0.2
~~~~~~~~~~~~~
Released: 2017-11-28
New Features:
- Add a plugin for the Nitrokey Storage device (Richard Hughes)
- Add support for the original AVR DFU protocol (Richard Hughes)
- Allow different plugins to claim the same device (Richard Hughes)
- Allow quirks to set common USB properties (Richard Hughes)
- Move a common plugin functionality out to a new shared object (Richard Hughes)
- Optionally delay the device removal for better replugging (Richard Hughes)
- Set environment variables to allow easy per-plugin debugging (Richard Hughes)
- Use a SHA1 hash for the internal DeviceID (Richard Hughes)
Bugfixes:
- Add quirk for AT32UC3B1256 as used in the RubberDucky (Richard Hughes)
- Disable the dell plugin if libsmbios fails (Mario Limonciello)
- Don't register for USB UDev events to later ignore them (Richard Hughes)
- Fix a possible buffer overflow when debugging ebitdo devices (Richard Hughes)
- Fix critical warning when more than one remote fails to load (Richard Hughes)
- Fix DFU attaching AVR32 devices like the XMEGA (Richard Hughes)
- Ignore useless Thunderbolt device types (Mario Limonciello)
- Refactor ColorHug into a much more modern plugin (Richard Hughes)
- Release the Steelseries interface if getting the version failed (Richard Hughes)
- Remove autoconf-isms from the meson configure options (Richard Hughes)
- Show a nicer error message if the requirement fails (Richard Hughes)
- Sort the output of GetUpgrades correctly (Richard Hughes)
Version 1.0.1
~~~~~~~~~~~~~
Released: 2017-11-09
New Features:
- Add support for HWID requirements (Richard Hughes)
- Add support for programming various AVR32 and XMEGA parts using DFU (Richard Hughes)
- Add the various DFU quirks for the Jabra Speak devices (Richard Hughes)
- Allow specifying the output file type for 'dfu-tool read' (Richard Hughes)
- Move the database of supported devices out into runtime loaded files (Richard Hughes)
- Support the IHEX record type 0x05 (Richard Hughes)
- Use help2man to generate the man page at build time (Richard Hughes)
- Use the new quirk infrastructure for version numbers (Richard Hughes)
Bugfixes:
- Catch invalid Dell dock component requests (Mario Limonciello)
- Correctly output Intel HEX files with > 16bit offset addresses (Richard Hughes)
- Do not try to verify the element write if upload is unsupported (Richard Hughes)
- Fix a double-unref when updating any 8Bitdo device (Richard Hughes)
- Fix crash when enumerating with Dell dock connected but with no UEFI (Mario Limonciello)
- Fix uploading large firmware files over DFU (Richard Hughes)
- Format the BCD USB revision numbers correctly (Richard Hughes)
- Guess the DFU transfer size if it is not specified (Richard Hughes)
- Include the reset timeout as wValue to fix some DFU bootloaders (Richard Hughes)
- Make the error message clearer when sans fonts are missing (Mario Limonciello)
- Support devices with truncated DFU interface data (Richard Hughes)
- Use the correct remote-specified username and passord when using fwupdmgr (Richard Hughes)
- Use the correct wDetachTimeOut when writing DFU firmware (Richard Hughes)
- Verify devices with legacy VIDs are actually 8Bitdo controllers (Richard Hughes)
Version 1.0.0
~~~~~~~~~~~~~
Released: 2017-10-09
Notes:
- This release breaks API and ABI to remove deprecated symbols
- libdfu is now not installed as a shared library
New Features:
- Add a human-readable title for each remote (Richard Hughes)
- Add a method to return a list of upgrades for a specific device (Richard Hughes)
- Add an 'Summary' and 'Icons' properties to each device (Richard Hughes)
- Add FuDeviceLocker to simplify device open/close lifecycles (Richard Hughes)
- Add functionality to blacklist Dell HW with problems (Mario Limonciello)
- Add fu_plugin_check_supported() (Richard Hughes)
- Add fwupd_remote_get_checksum() to use in client programs (Richard Hughes)
- Add ModifyRemote as an easy way to enable and disable remotes (Richard Hughes)
- Add the plugin documentation to the main gtk-doc (Richard Hughes)
- Allow plugins to depend on each other (Richard Hughes)
- Disable the fallback USB plugin (Richard Hughes)
- Parse the SMBIOS v2 and v3 DMI tables directly (Richard Hughes)
- Support uploading the UEFI firmware splash image (Richard Hughes)
- Use the intel-wmi-thunderbolt kernel module to force power (Mario Limonciello)
Bugfixes:
- Only run SMI to toggle host MST GPIO on Dell systems with host MST (Mario Limonciello)
- Disable unifying support if no CONFIG_HIDRAW support (Richard Hughes)
- Do not auto-open all USB devices at startup (Richard Hughes)
- Do not fail to load the daemon if cached metadata is invalid (Richard Hughes)
- Do not use system-specific infomation for UEFI PCI devices (Richard Hughes)
- Fix a crash when using fu_plugin_device_add_delay() (Richard Hughes)
- Fix the libdfu self test failure on s390 and ppc64 (Richard Hughes)
- Fix various printing issues with the progressbar (Richard Hughes)
- Generate the LD script from the GObject introspection data (Richard Hughes)
- Never fallback to an offline update from client code (Richard Hughes)
- Only set the Dell coldplug delay when we know we need it (Mario Limonciello)
- Prefer to use HWIDs to get DMI keys and DE table (Mario Limonciello)
Version 0.9.7
~~~~~~~~~~~~~
Released: 2017-09-01
New Features:
- Add a configure switch for the LVFS remotes (Richard Hughes)
- Add a FirmwareBaseURI parameter to the remote config (Richard Hughes)
- Add a firmware builder that uses bubblewrap (Richard Hughes)
- Add a python script to create fwupd compatible cab files from Microsoft .exe files (Max Ehrlich)
- Add a thunderbolt plugin for new kernel interface (Christian Kellner, Yehezkel Bernat)
- Allow plugins to get DMI data from the hardware in a safe way (Richard Hughes)
- Allow plugins to set metadata on devices created by other plugins (Richard Hughes, Mario Limonciello)
- Optionally install the LVFS PKCS7 root certificate (Richard Hughes)
- Optionally use GnuTLS to verify PKCS7 certificates (Richard Hughes)
Bugfixes:
- Add back options for HAVE_SYNAPTICS and HAVE_THUNDERBOLT (Mario Limonciello)
- Allow configuring systemd and udev directories (Mario Limonciello)
- Enable C99 support in meson.build (Philip Withnall)
- Fix an incomplete cipher when using XTEA on data not in 4 byte chunks (Richard Hughes)
- Fix minor const-correctness issues (Philip Withnall)
- Implement thunderbolt image validation (Yehezkel Bernat, Christian Kellner)
- Remove the confusing ALLOW_OFFLINE and ALLOW_ONLINE flags (Richard Hughes)
- Show a bouncing progress bar if the percentage remains at zero (Richard Hughes)
- Use a hwid to match supported systems for synapticsmst (Mario Limonciello)
- Use the new bootloader PIDs for Unifying pico receivers (Richard Hughes)
- When thunderbolt is in safe mode on a Dell recover using SMBIOS (Mario Limonciello)
Version 0.9.6
~~~~~~~~~~~~~
Released: 2017-08-03
New Features:
- Add DfuPatch to support forward-only firmware patching (Richard Hughes)
- Add --version option to fwupdmgr (Richard Hughes, Mario Limonciello)
- Display all errors recorded by efi_error tracing (Mario Limonciello)
- Make building introspection optional (Patrick Ohly)
- Support embedded devices with local firmware metadata (Richard Hughes)
Bugfixes:
- Check all the device GUIDs against the blacklist when added (Richard Hughes)
- Correct a memory leak in Dell plugin (Mario Limonciello, Richard Hughes)
- Default to "en" for UEFI capsule graphics (Mario Limonciello)
- Don't log a warning when an unknown unifying report is parsed (Richard Hughes)
- Enable test suite via /etc/fwupd.conf (Mario Limonciello)
- Fix a hang on 32 bit computers (Richard Hughes)
- Fix compilation of the policy on a variety of configurations (Mario Limonciello)
- Fix UEFI crash when the product name is NULL (Richard Hughes)
- Make flashing ebitdo devices work with fu-ebitdo-tool (Chris Lee)
- Make messages from installing capsules useful (Mario Limonciello)
- Make sure the unifying percentage completion goes from 0% to 100% (Richard Hughes)
- Run the plugin coldplug methods in a predictable order (Richard Hughes)
- Test UEFI for kernel support during coldplug (Mario Limonciello)
- Use new GUsb functionality to fix flashing Unifying devices (Richard Hughes)
Version 0.9.5
~~~~~~~~~~~~~
Released: 2017-07-04
New Features:
- Add a get-remotes command to fwupdmgr (Richard Hughes)
- Add a plugin to get the version of the AMT ME interface (Richard Hughes)
- Add Arch Linux to CI (Bruno Pagani)
- Add some installed tests flashing actual hardware (Richard Hughes)
- Allow flashing Unifying devices in bootloader modes (Richard Hughes)
- Allow ordering the metadata remotes (Richard Hughes)
Bugfixes:
- Do not check the runtime if the DFU device is in bootloader mode (Richard Hughes)
- Do not unlock devices when doing VerifyUpdate (Richard Hughes)
- Filter by Unifying SwId when making HID++2.0 requests (Richard Hughes)
- Fix downgrades when version_lowest is set (Richard Hughes)
- Fix the self tests when running on PPC64 big endian (Richard Hughes)
- Move the remotes parsing from the client to the server (Richard Hughes)
- Split up the Unifying HID++2.0 and HID++1.0 functionality (Richard Hughes)
- Store the metadata files rather than merging to one store (Richard Hughes)
- Use a longer timeout for some Unifying operations (Richard Hughes)
- Use the UFY DeviceID prefix for Unifying devides (Richard Hughes)
Version 0.9.4
~~~~~~~~~~~~~
Released: 2017-06-15
New Features:
- Add installed tests that use the daemon (Richard Hughes)
- Add the ability to restrict firmware to specific vendors (Richard Hughes)
- Enable Travis CI for Fedora and Debian (Richard Hughes, Mario Limonciello)
- Export some more API for dealing with checksums (Richard Hughes)
- Generate a images for status messages during system firmware update (Peter Jones)
- Show progress download when refreshing metadata (Richard Hughes)
Bugfixes:
- Compile with newer versions of meson (Richard Hughes, Mario Limonciello)
- Ensure that firmware provides are legal GUIDs (Richard Hughes)
- Fix a common crash when refreshing metadata (Richard Hughes)
- Use the correct type signature in the D-Bus introspection file (Richard Hughes)
Version 0.9.3
~~~~~~~~~~~~~
Released: 2017-06-07
New Features:
- Add a 'downgrade' command to fwupdmgr (Richard Hughes)
- Add a 'get-releases' command to fwupdmgr (Richard Hughes)
- Add support for ConsoleKit2 (Eric Koegel)
- Add support for Microsoft HardwareIDs (Richard Hughes)
- Allow downloading metadata from more than just the LVFS (Richard Hughes)
- Allow multiple checksums on devices and releases (Richard Hughes)
Bugfixes:
- Allow to specify bindir (Timo Gurr)
- Correctly open Unifying devices with original factory firmware (Richard Hughes)
- Deprecate some of the old FwupdResult API (Richard Hughes)
- Do not copy the origin from the new metadata file (Richard Hughes)
- Do not expect a Unifying reply when issuing a REBOOT command (Richard Hughes)
- Do not re-download firmware that exists in the cache (Richard Hughes)
- Fix a problem when testing for a Dell system (Mario Limonciello)
- Fix flashing new firmware to 8bitdo controllers (Richard Hughes)
- Increase minimum required AppStream-Glib version to 0.6.13 (Chris Mayo)
- Make documentation and man pages optional (Chris Mayo)
- Make systemd dependency at least version 231 (Mario Limonciello)
- Only decompress the firmware after the signature check (Richard Hughes)
- Remove 'lib' prefix when looking for libraries (Mirco Tischler)
- Return the remote ID when getting updates about hardware (Richard Hughes)
- Send the daemon the remote ID when sending firmware metadata (Richard Hughes)
Version 0.9.2
~~~~~~~~~~~~~
Released: 2017-05-22
New Features:
- Add support for Unifying DFU features (Richard Hughes)
Bugfixes:
- Do not spew a critial warning when parsing an invalid URI (Richard Hughes)
- Ensure device is closed if did not complete setup (Richard Hughes)
- Ensure steelseries device is closed if it returns an invalid packet (Richard Hughes)
- Fix man page installation location (Mario Limonciello)
- Ignore spaces in the Unifying version prefix (Richard Hughes)
- Set HAVE_POLKIT_0_114 when polkit is newer than 0.114 (Moritz Kiefer)
Version 0.9.1
~~~~~~~~~~~~~
Released: 2017-04-28
New Features:
- Add a config option to allow runtime disabling plugins by name (Richard Hughes)
- Add the Meson build system and remove autotools (Richard Hughes)
- Support signed Intel HEX files (Richard Hughes)
Bugfixes:
- Add DFU quirk for OpenPICC and SIMtrace (Richard Hughes)
- Create directories in /var/cache as required (Richard Hughes)
- Refactor the unifying plugin now we know more about the hardware (Richard Hughes)
- Set the source origin when saving metadata (Richard Hughes)
- Support proxy servers in fwupdmgr (Richard Hughes)
- Use a 60 second timeout on all client downloads (Richard Hughes)
Version 0.8.1
~~~~~~~~~~~~~
Released: 2017-02-27
Bugfixes:
- Adjust systemd confinement restrictions (Mario Limonciello, Richard Hughes)
- Do not hardcode docbook2man path (Kai Krakow)
- Don't initialize libsmbios on unsupported systems (Mario Limonciello)
- Fix a crash when enumerating devices on a Dell WLD15 (Richard Hughes)
- Fix compiler warnings (Kai Krakow)
- Fix fwupdmgr timeout with missing pending database (Richard Hughes)
Version 0.8.0
~~~~~~~~~~~~~
Released: 2017-02-08
New Features:
- Add a set of vfuncs that are run before and after a device update (Richard Hughes)
- Add Dell-specific functionality to allow other plugins turn on TBT/GPIO (Mario Limonciello)
- Add support for Intel Thunderbolt devices (Richard Hughes, Mario Limonciello)
- Add support for Logitech Unifying devices (Richard Hughes)
- Add support for Synaptics MST cascades hubs (Mario Limonciello)
- Add support for the Altus-Metrum ChaosKey device (Richard Hughes)
- Add VerifyUpdate to update the device checksums server-side (Richard Hughes)
- Allow the metadata to match a version of fwupd and the existing fw version (Richard Hughes)
Bugfixes:
- Add a new method for forcing a controller to flash mode (Mario Limonciello)
- Always make sure we're getting a C99 compiler (Richard Hughes)
- Close USB devices before error returns (Tsunghan Liu)
- Don't read data from some DfuSe targets (Richard Hughes)
- Include all debug messages when run with --verbose (Richard Hughes)
- Return the pending UEFI update when not on AC power (Richard Hughes)
- Use a heuristic for the start address if the firmware has no DfuSe footer (Richard Hughes)
- Use more restrictive settings when running under systemd (Richard Hughes, Mario Limonciello)
Version 0.7.5
~~~~~~~~~~~~~
Released: 2016-10-19
New Features:
- Add a 'replace-data' command to dfu-tool (Richard Hughes)
- Use an animated progress bar when performing DFU operations (Richard Hughes)
Bugfixes:
- Add quirks for HydraBus as it does not have a DFU runtime (Richard Hughes)
- Don't create the UEFI dummy device if the unlock will happen on next boot (Richard Hughes)
- Enable hardening flags on more binaries (Mario Limonciello)
- Fix an assert when unlocking the dummy ESRT device (Richard Hughes)
- Fix writing firmware to devices using the ST reference bootloader (Richard Hughes)
- Match the Dell TB16 device (Mario Limonciello)
- Re-get the quirks when the DfuDevice gets a new GUsbDevice (Richard Hughes)
- Show the nicely formatted target name for DfuSe devices (Richard Hughes)
- Verify devices support updating in mode they are called (Mario Limonciello)
Version 0.7.4
~~~~~~~~~~~~~
Released: 2016-09-19
New Features:
- Add dfu_firmware_add_symbol() (Richard Hughes)
- Allow the argument to 'dfu-tool set-release' be major.minor (Richard Hughes)
- Load the Altos USB descriptor from ELF files (Richard Hughes)
- Support writing the IHEX symbol table (Richard Hughes)
Bugfixes:
- Add a fallback for older appstream-glib releases (Richard Hughes)
- Fix a possible crash when uploading firmware files using libdfu (Richard Hughes)
- Fix libfwupd self tests when a host-provided fwupd is not available (Richard Hughes)
- Show the human-readable version in the 'dfu-tool dump' output (Richard Hughes)
- Write the ELF files with the correct section type (Richard Hughes)
Version 0.7.3
~~~~~~~~~~~~~
Released: 2016-08-29
New Features:
- Add a set-address and set-target-size commands to dfu-util (Richard Hughes)
- Add a small library for talking with 0bitdo hardware (Richard Hughes)
- Add Dell TPM and TB15/WD15 support via new Dell provider (Mario Limonciello)
- Add FU_DEVICE_FLAG_NEEDS_BOOTLOADER (Richard Hughes)
- Add fwupd_client_get_status() (Richard Hughes)
- Add fwupd_result_get_unique_id() (Richard Hughes)
- Add initial ELF reading and writing support to libdfu (Richard Hughes)
- Add support for installing multiple devices from a CAB file (Richard Hughes)
- Allow providers to export percentage completion (Richard Hughes)
- Show a progress notification when installing firmware (Richard Hughes)
- Show the vendor flashing instructions when installing (Richard Hughes)
Bugfixes:
- Add XPS 9250 to Dell TPM modeswitch blacklist (Mario Limonciello)
- Allow blacklisting devices by their GUID (Richard Hughes)
- Conditionally enable all providers based upon installed (Mario Limonciello)
- Display flashes left in results output when it gets low (Mario Limonciello)
- Do not attempt to add DFU devices not in runtime mode (Richard Hughes)
- Do not use the deprecated GNOME_COMPILE_WARNINGS (Richard Hughes)
- Don't fail while checking versions or locked state (Richard Hughes)
- Embed fwupd version in generated documentation (Mario Limonciello)
- Ensure the ID is set when getting local firmware details (Richard Hughes)
- Fix gtk-doc build when srcdir != builddir (Ting-Wei Lan)
- Fix libdfu hang when parsing corrupt IHEX files (Richard Hughes)
- Ignore devices that do not add at least one GUID (Richard Hughes)
- In get-details output, display the blob filename (Mario Limonciello)
- Save the unique ID in the pending database (Richard Hughes)
- Support the 'DEVO' cipher kind in libdfu (Richard Hughes)
- Switch to the Amazon S3 CDN for firmware metadata (Richard Hughes)
- Update fwupdmgr manpage for new commands and arguments (Mario Limonciello)
- Use a private gnupg key store (Richard Hughes)
- Use the correct firmware when installing a composite device (Richard Hughes)
- Use the SHA1 hash of the local file data as the origin (Richard Hughes)
Version 0.7.2
~~~~~~~~~~~~~
Released: 2016-06-13
New Features:
- Add a GetDetailsLocal() method to eventually replace GetDetails() (Richard Hughes)
- Add fu_device_get_alternate() (Richard Hughes)
- Allow devices to have multiple assigned GUIDs (Richard Hughes)
- Allow metainfo files to match only specific revisions of devices (Richard Hughes)
- Show the DFU protocol version in 'dfu-tool list' (Richard Hughes)
Bugfixes:
- Enforce allowing providers to take away flash abilities (Mario Limonciello)
- Only claim the DFU interface when required (Richard Hughes)
- Only return updatable devices from GetDevices() (Richard Hughes)
Version 0.7.1
~~~~~~~~~~~~~
Released: 2016-05-13
New Features:
- Add a --force flag to override provider warnings (Mario Limonciello)
- Add device-added, device-removed and device-changed signals (Richard Hughes)
- Add dfu_image_get_element_default() (Richard Hughes)
- Add for a new device field "Flashes Left" (Mario Limonciello)
- Add fwupd_client_connect() (Richard Hughes)
- Add the 'monitor' debugging command for fwupdmgr (Richard Hughes)
- Add the 'supported' flag to the FuDevice (Richard Hughes)
Bugfixes:
- Add summary and name field for Rival SteelSeries (Mario Limonciello)
- Fix a critical warning when restarting the daemon (Richard Hughes)
- Fix BE issues when reading and writing DFU files (Mario Limonciello, Richard Hughes)
- Make the device display name nicer (Richard Hughes, Richard Hughes)
- Match the AppStream metadata after a device has been added (Richard Hughes)
- Remove non-interactive pinentry setting from fu-keyring (Mario Limonciello)
- Return all update descriptions newer than the installed version (Richard Hughes)
- Set the device description when parsing local firmware files (Richard Hughes)
Version 0.7.0
~~~~~~~~~~~~~
Released: 2016-04-01
New Features:
- Add a version plugin for SteelSeries hardware (Richard Hughes)
- Add FwupdClient and FwupdResult to libfwupd (Richard Hughes)
- Generate gtk-doc documentation for libfwupd (Richard Hughes)
- Return the device flags when getting firmware details (Richard Hughes)
- Support other checksum kinds (Richard Hughes)
Bugfixes:
- Add Alienware to the version quirk table (Mario Limonciello)
- Allow the test suite to run in %check (Richard Hughes)
- Do not return updates that require AC when on battery (Richard Hughes)
- Do not use /tmp for downloaded files (Richard Hughes)
- Test that GPG key import actually was successful (Mario Limonciello)
Version 0.6.3
~~~~~~~~~~~~~
Released: 2016-03-14
New Features:
- Add an unlock method for devices (Richard Hughes)
- Add a simple plugin infrastructure (Richard Hughes)
- Add ESRT enable method into UEFI provider (Mario Limonciello)
- Install the hardcoded firmware AppStream file (Richard Hughes)
Bugfixes:
- Correct the BCD version number for DFU 1.1 (Richard Hughes)
- Do not use deprecated API from libappstream-glib (Richard Hughes)
- Ignore the DFU runtime on the DW1820A (Richard Hughes)
- Only read PCI OptionROM firmware when devices are manually unlocked (Richard Hughes)
- Require AC power before scheduling some types of firmware update (Richard Hughes)
- Show ignored DFU devices in dfu-util, but not in fwupd (Richard Hughes)
Version 0.6.2
~~~~~~~~~~~~~
Released: 2016-02-12
New Features:
- Add 'Created' and 'Modified' properties on managed devices (Richard Hughes)
Bugfixes:
- Fix get-results for UEFI provider (Mario Limonciello)
- Support vendor-specific UEFI version encodings (Richard Hughes)
Version 0.6.1
~~~~~~~~~~~~~
Released: 2016-01-19
Bugfixes:
- Always persist ColorHug devices after replug (Richard Hughes)
- Do not misdetect different ColorHug devices (Richard Hughes)
- Only dump the profiling data when run with --verbose (Richard Hughes)
Version 0.6.0
~~~~~~~~~~~~~
Released: 2015-12-07
Notes:
- This release adds a new GObject library called libdfu and a command line
client called dfu-tool. This is a low-level tool used to upgrade USB device
firmware and can either be shipped in the same package as fwupd or split off
as separate subpackages.
New Features:
- Add support for automatically updating USB DFU-capable devices (Richard Hughes)
Bugfixes:
- Emit the changed signal after doing an update (Richard Hughes)
- Export the AppStream ID when returning device results (Richard Hughes)
- Fix compile with --disable-shared (Richard Hughes)
- Use new API available in fwup 0.5 (Richard Hughes, Mario Limonciello)
- Use the same device identification string format as Microsoft (Richard Hughes)
Version 0.5.3
~~~~~~~~~~~~~
Released: 2015-11-05
Bugfixes:
- Avoid seeking when reading the file magic during refresh (Richard Hughes)
- Do not assume that the compressed XML data will be NUL terminated (Richard Hughes)
- Use the correct user agent string for fwupdmgr (Richard Hughes)
Version 0.5.2
~~~~~~~~~~~~~
Released: 2015-10-28
New Features:
- Add profiling data to debug slow startup times (Richard Hughes)
- Support cabinet archives files with more than one firmware (Richard Hughes)
Bugfixes:
- Add the update description to the GetDetails results (Richard Hughes)
- Clear the in-memory firmware store only after parsing a valid XML file (Richard Hughes)
- Ensure D-Bus remote errors are registered at fwupdmgr startup (Richard Hughes)
- Fix verify-update to produce components with the correct provide values (Richard Hughes)
- Require appstream-glib 0.5.1 (Mirco Tischler)
- Show the dotted-decimal representation of the UEFI version number (Richard Hughes)
- When the version is from the 'FW' extension do not cache the device (Richard Hughes)
Version 0.5.1
~~~~~~~~~~~~~
Released: 2015-09-21
Bugfixes:
- Fix the error message when no devices can be updated (Richard Hughes)
- Fix reading symlink to prevent crash with some compilers (Kalev Lember)
Version 0.5.0
~~~~~~~~~~~~~
Released: 2015-09-15
New Features:
- Raise the dep on GLib to support and use g_autoptr() (Richard Hughes)
Bugfixes:
- Do not merge existing firmware metadata (Richard Hughes)
- Do not reboot if racing with the PackageKit offline update mechanism (Richard Hughes)
Version 0.1.6
~~~~~~~~~~~~~
Released: 2015-09-10
New Features:
- Remove fwsignd, we have the LVFS now (Richard Hughes)
Bugfixes:
- Add application metadata when getting the updates list (Richard Hughes)
- Depend on appstream-glib >= 0.5.0 (Richard Hughes)
- Don't apply firmware if something else is processing the update (Richard Hughes)
- Install fwupd into /usr/lib/$(triplet)/fwupd instead (Mario Limonciello)
- Simplify the version properties on devices to avoid complexity (Richard Hughes)
- Update the offline update service to invoke right command (Kalev Lember)
- Use the new secure metadata URI (Richard Hughes)
Version 0.1.5
~~~~~~~~~~~~~
Released: 2015-08-12
Notes:
- For the device verification code to work correctly you need at least
libappstream-glib 0.5.0 installed.
New Features:
- Add a Raspberry Pi firmware provider (Richard Hughes)
- Add a simple config file to store the correct LVFS download URI (Richard Hughes)
- Make parsing the option ROM runtime optional (Richard Hughes)
Bugfixes:
- Allow fwupd to be autostarted by systemd (Richard Hughes)
- Allow no arguments to 'fwupdmgr verify-update' and use sane defaults (Richard Hughes)
- Devices with option ROM are always internal (Richard Hughes)
- Do not pre-convert the update description from AppStream XML (Richard Hughes)
- Fix validation of written firmware (Richard Hughes)
- Move the verification and metadata matching phase to the daemon (Richard Hughes)
- Sign the test binary with the correct key (Richard Hughes)
- Use the AppStream 0.9 firmware specification by default (Richard Hughes)
Version 0.1.4
~~~~~~~~~~~~~
Released: 2015-07-25
Notes:
- In this release we've moved the LVFS website to the fwupd project and made
them work really well together. To update all the firmware on your system
is now just a case of "fwupdmgr refresh && fwupdmgr update"
- We've also added verification of BIOS and PCI ROM firmware, which may be
useful for forensics or to verify that system updates have been applied.
New Features:
- Actually parse the complete PCI option ROM (Richard Hughes)
- Add a 'fwupdmgr update' command to update all devices to latest versions (Richard Hughes)
- Add a simple signing server that operates on .cab files (Richard Hughes)
- Add a 'verify' command that verifies the cryptographic hash of device firmware (Richard Hughes)
- Allow clients to add new firmware metadata to the system cache (Richard Hughes)
- Move GetUpdates to the daemon (Richard Hughes)
- Move the LVFS website to the fwupd project (Richard Hughes)
Bugfixes:
- Accept multiple files at one time when using fwupdmgr dump-rom (Richard Hughes)
- Automatically download metadata using fwupdmgr if required (Richard Hughes)
- Do not return NULL as a gboolean (Thomas Hindoe Paaboel Andersen)
- Don't call efibootmgr after fwupdate (Mario Limonciello)
- Fallback to offline install when calling the update argument (Mario Limonciello)
- Fix Intel VBIOS detection on Dell hardware (Richard Hughes)
- Reload appstream data after refreshing (Mario Limonciello)
- Use the new LVFS GPG key (Richard Hughes)
- Fix build: libgusb is required even without colorhug support (Jussi Kukkonen)
Version 0.1.3
~~~~~~~~~~~~~
Released: 2015-05-28
New Features:
- Get the firmware version from the device descriptors (Richard Hughes)
- Run the offline actions using systemd when required (Richard Hughes)
- Support OpenHardware devices using the fwupd vendor extensions (Richard Hughes)
Bugfixes:
- Add an UNKNOWN status so we can return meaningful enum values (Richard Hughes)
- Coldplug the devices before acquiring the well known name (Richard Hughes)
Version 0.1.2
~~~~~~~~~~~~~
Released: 2015-04-22
- Add some guidelines for vendors to README (Richard Hughes)
- Only allow signed firmware to be upgraded without a password (Richard Hughes)
Version 0.1.1
~~~~~~~~~~~~~
Released: 2015-03-23
New Features:
- Add a 'get-updates' command to fwupdmgr (Richard Hughes)
- Add and document the offline-update lifecycle (Richard Hughes)
- Create a libfwupd shared library (Richard Hughes)
Bugfixes:
- Create runtime directories if they do not exist (Richard Hughes)
- Do not crash when there are no devices to return (Richard Hughes)
Version 0.1.0
~~~~~~~~~~~~~
Released: 2015-03-16
Notes:
- fwupd is a simple daemon to allow session software to update firmware.

View File

@ -3,6 +3,8 @@ fwupd
[![Build Status](https://travis-ci.org/hughsie/fwupd.png?branch=master)](https://travis-ci.org/hughsie/fwupd)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/10744/badge.svg)](https://scan.coverity.com/projects/10744)
[![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-white.svg)](https://snapcraft.io/fwupd)
This project aims to make updating firmware on Linux automatic, safe and reliable.
Additional information is available at the website: https://fwupd.org
@ -73,14 +75,19 @@ To clear the local history of updates:
Other frontends
-------------------
Currently [GNOME Software](https://wiki.gnome.org/Apps/Software) is the only graphical
frontend available. When compiled with firmware support, it will check for updates
periodically and automatically download firmware in the background.
1. [GNOME Software](https://wiki.gnome.org/Apps/Software) is the graphical
frontend available. When compiled with firmware support, it will check for
updates periodically and automatically download firmware in the background.
After the firmware has been downloaded a popup will be displayed in Gnome
Software to perform the update.
After the firmware has been downloaded a popup will be displayed in Gnome Software
to perform the update.
2. [KDE Discover](https://userbase.kde.org/Discover) is the software centre,
generally bundled with KDE Plasma. With the release of
[KDE Plasma 5.14](https://www.kde.org/announcements/plasma-5.14.0.php),
a new fwupd backend has been implemented in KDE Discover for firmware updates.
These firmware updates are shown with other system updates.
On Dell IoT gateways, [Wyse Cloud Client Manager (CCM)](http://www.dell.com/us/business/p/wyse-cloud-client-manager/pd)
has been built with fwupd support.
The remote administration interface can be used to download and deploy
firmware updates.
3. [Wyse Cloud Client Manager (CCM)](http://www.dell.com/us/business/p/wyse-cloud-client-manager/pd)
A software suite available on Dell IoT gateways with built-in fwupd support.
The remote administration interface can be used to download and deploy firmware
updates.

21
RELEASE
View File

@ -1,20 +1,23 @@
fwupd Release Notes
1. Write NEWS entries for fwupd in the same format as usual.
Write release entries:
git shortlog 1.1.3.. | grep -i -v trivial | grep -v Merge > NEWS.new
git log --format="%s" --cherry-pick --right-only 1.2.3... | grep -i -v trivial | grep -v Merge | sort | uniq
Add any user visible changes into ../data/org.freedesktop.fwupd.metainfo.xml
appstream-util appdata-to-news ../data/org.freedesktop.fwupd.metainfo.xml > NEWS
Version 1.1.4
~~~~~~~~~~~~~
Released: 2018-xx-xx
Update translations:
New Features:
Bugfixes:
ninja-build fwupd-pot
tx push --source
tx pull --all --force --minimum-perc=5
../contrib/fix_translations.py ../po
git add ../po/*.po
2. Commit changes to git:
# MAKE SURE THESE ARE CORRECT
export release_ver="1.1.4"
# MAKE SURE THIS IS CORRECT
export release_ver="1.2.4"
git commit -a -m "Release fwupd ${release_ver}"
git tag -s -f -m "Release fwupd ${release_ver}" "${release_ver}"

View File

@ -8,7 +8,8 @@ pkgdesc='A simple daemon to allow session software to update firmware'
arch=('i686' 'x86_64')
url='https://github.com/hughsie/fwupd'
license=('GPL2')
depends=('appstream-glib' 'libgusb')
depends=('libgusb')
optdepends=('tpm2-abrmd' 'tpm2-tools')
makedepends=('meson' 'valgrind' 'gobject-introspection' 'gtk-doc' 'python-pillow' 'git'
'python-cairo' 'noto-fonts' 'noto-fonts-cjk' 'python-gobject' 'vala'
'libsoup' 'polkit' 'gcab')

View File

@ -7,7 +7,6 @@ RUN echo fubar > /etc/machine-id
RUN yum install epel-release -y
RUN echo fubar > /etc/machine-id
%%%INSTALL_DEPENDENCIES_COMMAND%%%
RUN yum install -y https://kojipkgs.fedoraproject.org//packages/libstemmer/0/10.585svn.fc29/x86_64/libstemmer-0-10.585svn.fc29.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/libappstream-glib/0.7.7/3.fc29/x86_64/libappstream-glib-0.7.7-3.fc29.x86_64.rpm https://kojipkgs.fedoraproject.org//packages/libappstream-glib/0.7.7/3.fc29/x86_64/libappstream-glib-devel-0.7.7-3.fc29.x86_64.rpm
RUN pip3 install pillow pygobject
RUN wget https://copr.fedorainfracloud.org/coprs/jsynacek/systemd-backports-for-centos-7/repo/epel-7/jsynacek-systemd-backports-for-centos-7-epel-7.repo -O /etc/yum.repos.d/jsynacek-systemd-centos-7.repo
RUN yum --enablerepo=epel-testing -y update

View File

@ -1,10 +1,10 @@
FROM fedora:28
FROM fedora:29
%%%OS%%%
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN echo fubar > /etc/machine-id
RUN dnf --enablerepo=updates-testing -y update
RUN dnf -y update
RUN echo fubar > /etc/machine-id
%%%INSTALL_DEPENDENCIES_COMMAND%%%
RUN mkdir /build

View File

@ -1,11 +1,12 @@
FROM fedora:28
FROM fedora:29
%%%OS%%%
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN echo fubar > /etc/machine-id
%%%INSTALL_DEPENDENCIES_COMMAND%%%
RUN dnf --enablerepo=updates-testing -y update
RUN mkdir /build
WORKDIR /build
COPY . .
CMD ["./contrib/ci/flatpak.sh"]
CMD ["./contrib/ci/flatpak.py"]

View File

@ -16,6 +16,8 @@ meson .. \
-Dplugin_redfish=false \
-Dintrospection=false \
-Dgtkdoc=false \
-Dlibxmlb:introspection=false \
-Dlibxmlb:gtkdoc=false \
-Dman=false
ninja -v
ninja test -v

View File

@ -366,15 +366,6 @@
<package variant="i386">gnu-efi</package>
</distro>
</dependency>
<dependency type="build" id="gir1.2-appstreamglib-1.0">
<distro id="debian">
<package variant="x86_64" />
<package variant="i386" />
</distro>
<distro id="ubuntu">
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="git">
<distro id="arch">
<package />
@ -551,30 +542,34 @@
<package />
</distro>
</dependency>
<dependency type="build" id="libappstream-glib-dev">
<dependency type="build" id="libxmlb-dev">
<distro id="arch">
<package>appstream-glib</package>
<package>libxmlb</package>
</distro>
<!--
<distro id="centos">
<package>libappstream-glib-devel</package>
<package>libxmlb-devel</package>
</distro>
-->
<distro id="fedora">
<package>libappstream-glib-devel</package>
<package>libxmlb-devel</package>
</distro>
<!--
<distro id="debian">
<control>
<version>(>= 0.7.4)</version>
<version>(>= 0.1.3)</version>
</control>
<package variant="x86_64" />
<package variant="s390x">libappstream-glib-dev:s390x</package>
<package variant="s390x">libxmlb-dev:s390x</package>
<package variant="i386" />
</distro>
<distro id="ubuntu">
<control>
<version>(>= 0.6.9)</version>
<version>(>= 0.1.3)</version>
</control>
<package variant="x86_64" />
</distro>
-->
</dependency>
<dependency type="build" id="libarchive-dev">
<distro id="centos">
@ -1052,6 +1047,27 @@
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="shared-mime-info">
<distro id="arch">
<package />
</distro>
<distro id="centos">
<package />
</distro>
<distro id="fedora">
<package />
</distro>
<distro id="debian">
<control />
<package variant="x86_64" />
<package variant="s390x" />
<package variant="i386" />
</distro>
<distro id="ubuntu">
<control />
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="texlive-fonts-recommended">
<distro id="debian">
<package variant="x86_64" />
@ -1093,10 +1109,20 @@
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="uuid">
<dependency type="build" id="uuid-dev">
<distro id="centos">
<package>libuuid-devel</package>
</distro>
<distro id="debian">
<control />
<package variant="x86_64" />
<package variant="s390x">uuid-dev:s390x</package>
<package variant="i386" />
</distro>
<distro id="ubuntu">
<control />
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="valac">
<distro id="arch">

View File

@ -49,12 +49,22 @@ dnf install -y $HOME/rpmbuild/RPMS/*/*.rpm
cp $HOME/rpmbuild/RPMS/*/*.rpm dist
# run the installed tests
if [ "$CI" = "true" ]; then
sed "s,^BlacklistPlugins=test,BlacklistPlugins=," -i /etc/fwupd/daemon.conf
# set up enough PolicyKit and D-Bus to run the daemon
mkdir -p /run/dbus
mkdir -p /var
ln -s /var/run /run
dbus-daemon --system --fork
/usr/lib/polkit-1/polkitd &
sleep 5
# run the daemon startup to check it can start
/usr/libexec/fwupd/fwupd --immediate-exit --verbose
# run the installed tests whilst the daemon debugging
/usr/libexec/fwupd/fwupd --verbose &
sleep 10
gnome-desktop-testing-runner fwupd
fi

81
contrib/ci/flatpak.py Executable file
View File

@ -0,0 +1,81 @@
#!/usr/bin/python3
import subprocess
import os
import json
import shutil
def prepare (target):
#clone the flatpak json
cmd = ['git', 'submodule', 'update', '--remote', 'contrib/flatpak']
subprocess.run (cmd, check=True)
#clone the submodules for that
cmd = ['git', 'submodule', 'update', '--init', '--remote', 'shared-modules/']
subprocess.run (cmd, cwd='contrib/flatpak', check=True)
#parse json
if os.path.isdir ('build'):
shutil.rmtree ('build')
data = {}
with open ('contrib/flatpak/org.freedesktop.fwupd.json', 'r') as rfd:
data = json.load (rfd)
platform = 'runtime/%s/x86_64/%s' % (data['runtime'], data['runtime-version'])
sdk = 'runtime/%s/x86_64/%s' % (data['sdk'], data['runtime-version'])
num_modules = len (data['modules'])
#update to build from master
data["branch"] = "master"
for index in range(0, num_modules):
module = data['modules'][index]
if type (module) != dict or not 'name' in module:
continue
name = module['name']
if not 'fwupd' in name:
continue
data['modules'][index]['sources'][0].pop ('url')
data['modules'][index]['sources'][0].pop ('sha256')
data['modules'][index]['sources'][0]['type'] = 'dir'
data['modules'][index]['sources'][0]['skip'] = [".git"]
data['modules'][index]['sources'][0]['path'] = ".."
#write json
os.mkdir('build')
with open (target, 'w') as wfd:
json.dump(data, wfd, indent=4)
os.symlink ('../contrib/flatpak/shared-modules','build/shared-modules')
# install the runtimes (parsed from json!)
repo = 'flathub'
repo_url = 'https://dl.flathub.org/repo/flathub.flatpakrepo'
print ("Installing dependencies")
cmd = ['flatpak', 'remote-add', '--if-not-exists', repo, repo_url]
subprocess.run (cmd, check=True)
cmd = ['flatpak', 'install', '--assumeyes', repo, sdk]
subprocess.run (cmd, check=True)
cmd = ['flatpak', 'install', '--assumeyes', repo, platform]
subprocess.run (cmd, check=True)
def build (target):
cmd = ['flatpak-builder', '--repo=repo', '--force-clean', '--disable-rofiles-fuse', 'build-dir', target]
subprocess.run (cmd, check=True)
cmd = ['flatpak', 'build-bundle', 'repo', 'fwupd.flatpak', 'org.freedesktop.fwupd']
subprocess.run (cmd, check=True)
if __name__ == '__main__':
t = os.path.join ('build', 'org.freedesktop.fwupd.json')
prepare (t)
build (t)
# to run from the builddir:
# sudo flatpak-builder --run build-dir org.freedesktop.fwupd.json /app/libexec/fwupd/fwupdtool get-devices
# install the single file bundle
# flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
# flatpak install fwupd.flatpak
# to run a shell in the same environment that flatpak sees:
# flatpak run --command=sh --devel org.freedesktop.fwupd
# to run fwupdtool as root:
# sudo flatpak run org.freedesktop.fwupd --verbose get-devices

View File

@ -1,33 +0,0 @@
#!/bin/bash
set -e
set -x
# install the runtimes
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install --assumeyes flathub runtime/org.gnome.Sdk/x86_64/3.28
flatpak install --assumeyes flathub runtime/org.gnome.Platform/x86_64/3.28
# build the repo
flatpak-builder --repo=repo --force-clean --disable-rofiles-fuse build-dir contrib/org.freedesktop.fwupd.json
# show the files that were included
tree build-dir
# build a single file bundle
flatpak build-bundle repo fwupd.flatpak org.freedesktop.fwupd
# make available as a deliverable
cp fwupd.flatpak dist
# to run from the builddir:
# sudo flatpak-builder --run build-dir org.freedesktop.fwupd.json /app/libexec/fwupd/fwupdtool get-devices
# install the single file bundle
# flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
# flatpak install fwupd.flatpak
# to run a shell in the same environment that flatpak sees:
# flatpak run --command=sh --devel org.freedesktop.fwupd
# to run fwupdtool as root:
# sudo flatpak run org.freedesktop.fwupd --verbose get-devices

View File

@ -26,21 +26,19 @@ bin file inside the archive, I would pass `--exe dell-thunderbolt-firmware.exe -
## Documentation
`--firmware-id` ID for the firmware package, can be a customized [fwupd.org](http://fwupd.org/vendors.html) recommends using "a reverse-DNS prefix similar to java" and to "always use a .firmware suffix" (e.g. net.queuecumber.DellTBT.firmware) **REQUIRED**
`--firmware-name` Short name of the firmware package can be customized (e.g. DellTBT) **REQUIRED**
`--firmware-summary` One line description of the firmware package (e.g. Dell thunderbolt firmware)
`--firmware-description` Longer description of the firmware package. Theoretically this can include HTML but I haven't tried it
`--device-unique-id` Unique ID of the device this firmware will run on, this *must* match the output from `fwupdmgr get-devices` (e.g. 72533768-6a6c-5c06-994a-367374336810) **REQUIRED**
`--device-guid` GUID ID of the device this firmware will run on, this *must* match the output from `fwupdmgr get-devices` (e.g. 72533768-6a6c-5c06-994a-367374336810) **REQUIRED**
`--firmware-homepage` Website for the firmware provider (e.g. http://www.dell.com)
`-contact-info` Email address of the firmware developer (e.g. someone@something.net)
`--developer-name` Name of the firmware developer (e.g. John Smith)
`--developer-name` Name of the firmware developer (e.g. Dell) **REQUIRED**
`--release-version` Version number of the firmware package (e.g. 4.21.01.002) **REQUIRED**
`--release-description` Description of the firmware release, again this can theoretically include HTML but I didnt try it.

View File

@ -24,14 +24,14 @@ def cd(path):
firmware_metainfo_template = """
<?xml version="1.0" encoding="UTF-8"?>
<component type="firmware">
<id>{firmware_id}</id>
<id>org.{developer_name}.guid{firmware_id}</id>
<name>{firmware_name}</name>
<summary>{firmware_summary}</summary>
<description>
{firmware_description}
</description>
<provides>
<firmware type="flashed">{device_unique_id}</firmware>
<firmware type="flashed">{device_guid}</firmware>
</provides>
<url type="homepage">{firmware_homepage}</url>
<metadata_license>CC0-1.0</metadata_license>
@ -50,7 +50,9 @@ firmware_metainfo_template = """
def make_firmware_metainfo(firmware_info, dst):
firmware_metainfo = firmware_metainfo_template.format(**vars(firmware_info), timestamp=time.time())
local_info = vars(firmware_info)
local_info["firmware_id"] = local_info["device_guid"][0:8]
firmware_metainfo = firmware_metainfo_template.format(**local_info, timestamp=time.time())
with open(os.path.join(dst, 'firmware.metainfo.xml'), 'w') as f:
f.write(firmware_metainfo)
@ -68,6 +70,14 @@ def get_firmware_bin(root, bin_path, dst):
def create_firmware_cab(exe, folder):
with cd(folder):
if os.name is "nt":
directive = os.path.join (folder, "directive")
with open (directive, 'w') as wfd:
wfd.write('"firmware.cab"\r\n')
wfd.write('"firmware.bin"\r\n')
wfd.write('"firmware.metainfo.xml"\r\n')
command = ['makecab.exe', '/f', directive]
else:
command = ['gcab', '--create', 'firmware.cab', 'firmware.bin', 'firmware.metainfo.xml']
subprocess.check_call(command)
@ -93,18 +103,17 @@ def main(args):
shutil.copy(os.path.join(dir, 'firmware.cab'), args.out)
parser = argparse.ArgumentParser(description='Create fwupd packaged from windows executables')
parser.add_argument('--firmware-id', help='ID for the firmware package, can be a customized (e.g. net.queuecumber.DellTBT.firmware)', required=True)
parser.add_argument('--firmware-name', help='Name of the firmware package can be customized (e.g. DellTBT)', required=True)
parser.add_argument('--firmware-summary', help='One line description of the firmware package')
parser.add_argument('--firmware-description', help='Longer description of the firmware package')
parser.add_argument('--device-unique-id', help='Unique ID of the device this firmware will run on, this *must* match the output from `fwupdmgr get-devices`', required=True)
parser.add_argument('--device-guid', help='GUID of the device this firmware will run on, this *must* match the output of one of the GUIDs in `fwupdmgr get-devices`', required=True)
parser.add_argument('--firmware-homepage', help='Website for the firmware provider')
parser.add_argument('--contact-info', help='Email address of the firmware developer')
parser.add_argument('--developer-name', help='Name of the firmware developer')
parser.add_argument('--developer-name', help='Name of the firmware developer', required=True)
parser.add_argument('--release-version', help='Version number of the firmware package', required=True)
parser.add_argument('--release-description', help='Description of the firmware release')
parser.add_argument('--exe', help='Executable file to extract firmware from')
parser.add_argument('--bin', help='Path to the .bin file inside the executable to use as the firmware image', required=True)
parser.add_argument('--exe', help='(optional) Executable file to extract firmware from')
parser.add_argument('--bin', help='Path to the .bin file (Relative if inside the executable; Absolute if outside) to use as the firmware image', required=True)
parser.add_argument('--out', help='Output cab file path', required=True)
args = parser.parse_args()

50
contrib/fix_translations.py Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1+
import sys
import os
import subprocess
def _do_msgattrib(fn):
argv = ['msgattrib',
'--no-location',
'--translated',
'--no-wrap',
'--sort-output',
fn,
'--output-file=' + fn]
ret = subprocess.run(argv)
if ret.returncode != 0:
return
def _do_nukeheader(fn):
clean_lines = []
with open(fn) as f:
lines = f.readlines()
for line in lines:
if line.startswith('"POT-Creation-Date:'):
continue
if line.startswith('"PO-Revision-Date:'):
continue
if line.startswith('"Last-Translator:'):
continue
clean_lines.append(line)
with open(fn, 'w') as f:
f.writelines(clean_lines)
def _process_file(fn):
_do_msgattrib(fn)
_do_nukeheader(fn)
if __name__ == '__main__':
if len(sys.argv) == 1:
print('path required')
sys.exit(1)
try:
dirname = sys.argv[1]
for fn in os.listdir(dirname):
if fn.endswith('.po'):
_process_file(os.path.join(dirname, fn))
except NotADirectoryError as _:
print('path required')
sys.exit(2)

View File

@ -1,5 +0,0 @@
all:
python3 setup.py build
install:
python3 setup.py install --prefix=/app ${ARGS}

View File

@ -1,5 +1,5 @@
%global glib2_version 2.45.8
%global libappstream_version 0.7.4
%global libxmlb_version 0.1.3
%global libgusb_version 0.2.11
%global libsoup_version 2.51.92
%global systemd_version 231
@ -36,7 +36,7 @@ Source0: http://people.freedesktop.org/~hughsient/releases/%{name}-%{version}.
BuildRequires: gettext
BuildRequires: glib2-devel >= %{glib2_version}
BuildRequires: libappstream-glib-devel >= %{libappstream_version}
BuildRequires: libxmlb-devel >= %{libxmlb_version}
BuildRequires: libgcab1-devel
BuildRequires: libgudev1-devel
BuildRequires: libgusb-devel >= %{libgusb_version}
@ -89,12 +89,14 @@ Requires(preun): systemd
Requires(postun): systemd
Requires: glib2%{?_isa} >= %{glib2_version}
Requires: libappstream-glib%{?_isa} >= %{libappstream_version}
Requires: libxmlb%{?_isa} >= %{libxmlb_version}
Requires: libgusb%{?_isa} >= %{libgusb_version}
Requires: libsoup%{?_isa} >= %{libsoup_version}
Requires: bubblewrap
Requires: shared-mime-info
Recommends: python3
Recommends: tpm2-tools tpm2-abrmd
Obsoletes: fwupd-sign < 0.1.6
Obsoletes: libebitdo < 0.7.5-3
@ -201,7 +203,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%systemd_postun_with_restart pesign.service
%files -f %{name}.lang
%doc README.md AUTHORS NEWS
%doc README.md AUTHORS
%license COPYING
%config(noreplace)%{_sysconfdir}/fwupd/daemon.conf
%if 0%{?have_uefi}
@ -226,6 +228,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/lvfs.conf
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/lvfs-testing.conf
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/vendor.conf
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/vendor-directory.conf
%config(noreplace)%{_sysconfdir}/pki/fwupd
%{_sysconfdir}/pki/fwupd-metadata
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf
@ -255,6 +258,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%dir %{_libdir}/fwupd-plugins-3
%{_libdir}/fwupd-plugins-3/libfu_plugin_altos.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_amt.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_ata.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_colorhug.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_csr.so
%if 0%{?have_dell}
@ -264,6 +268,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%{_libdir}/fwupd-plugins-3/libfu_plugin_dell_dock.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_dfu.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_ebitdo.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_fastboot.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_flashrom.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_nitrokey.so
%if 0%{?have_uefi}
@ -290,7 +295,8 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%endif
%{_libdir}/fwupd-plugins-3/libfu_plugin_unifying.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_wacomhid.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_wacom_raw.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_wacom_usb.so
%ghost %{_localstatedir}/lib/fwupd/gnupg
%if 0%{?have_uefi}
%{_datadir}/locale/*/LC_IMAGES/fwupd*
@ -306,12 +312,13 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%files tests
%dir %{_datadir}/installed-tests/fwupd
%{_datadir}/installed-tests/fwupd/firmware-example.xml.gz
%{_datadir}/installed-tests/fwupd/firmware-example.xml.gz.asc
%{_datadir}/installed-tests/fwupd/fwupd-tests.xml
%{_datadir}/installed-tests/fwupd/*.test
%{_datadir}/installed-tests/fwupd/*.cab
%{_datadir}/installed-tests/fwupd/*.sh
%{_datadir}/installed-tests/fwupd/*.py*
%dir %{_sysconfdir}/fwupd/remotes.d
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/fwupd-tests.conf
%changelog
* #LONGDATE# Richard Hughes <richard@hughsie.com> #VERSION#-0.#BUILD##ALPHATAG#

View File

@ -1,255 +0,0 @@
{
"app-id": "org.freedesktop.fwupd",
"runtime": "org.gnome.Platform",
"runtime-version": "3.28",
"branch": "master",
"sdk": "org.gnome.Sdk",
"command": "/app/libexec/fwupd/fwupdtool",
"finish-args": [
"--device=all",
"--filesystem=/boot",
"--filesystem=/sys",
"--filesystem=xdg-download",
"--share=network",
"--system-talk-name=org.freedesktop.fwupd",
"--system-talk-name=org.freedesktop.UPower"
],
"build-options": {
"cflags": "-O2 -g",
"cxxflags": "-O2 -g"
},
"cleanup": [
"*.a",
"*.la",
"/include",
"/lib/girepository-1.0",
"/lib/pkgconfig",
"/share/bash-completion",
"/share/dbus-1/system-services",
"/share/gir-1.0",
"/share/gtk-doc",
"/share/info",
"/share/man",
"/share/pkgconfig"
],
"modules": [
{
/* not using shared-modules as we need gudev */
"name": "udev",
"rm-configure": true,
"config-opts": [
"--disable-hwdb",
"--disable-logging",
"--disable-introspection",
"--disable-keymap",
"--disable-mtd_probe"
],
"cleanup": [
"/etc/udev",
"/libexec/*",
"/share/gtk-doc/html/libudev/",
"/sbin/udevadm"
],
"sources": [
{
"type": "archive",
"url": "http://kernel.org/pub/linux/utils/kernel/hotplug/udev-175.tar.bz2",
"sha256": "4c7937fe5a1521316ea571188745b9a00a9fdf314228cffc53a7ba9e5968b7ab"
},
{
"type": "script",
"dest-filename": "autogen.sh",
"commands": [
"autoreconf -vfi"
]
}
]
},
{
"name": "libusb",
"config-opts": [
"--disable-static"
],
"sources": [
{
"type": "archive",
"url": "https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.tar.bz2",
"sha256": "75aeb9d59a4fdb800d329a545c2e6799f732362193b465ea198f2aa275518157"
}
]
},
{
"name": "gusb",
"buildsystem": "meson",
"config-opts": [
"-Ddocs=false",
"-Dvapi=false",
"-Dtests=false"
],
"cleanup": [
"/bin/gusbcmd"
],
"sources": [
{
"type": "archive",
"url": "https://people.freedesktop.org/~hughsient/releases/libgusb-0.3.0.tar.xz",
"sha256": "d8e7950f99b6ae4c3e9b8c65f3692b9635289e6cff8de40c4af41b2e9b348edc"
}
]
},
{
"name": "efivar",
"buildsystem": "simple",
"build-commands": [
"make prefix=/app libdir=/app/lib",
"make install prefix=/app libdir=/app/lib"
],
"cleanup": [
"/bin/efivar"
],
"sources": [
{
"type": "archive",
"url": "https://github.com/rhboot/efivar/releases/download/35/efivar-35.tar.bz2",
"sha256": "1e033dc5d099a44fd473b0887dbcc4b105613efab0fb3c5df9f111ea5d147394"
}
]
},
{
"name": "libsmbios_c",
"only-arches": [
"x86_64"
],
"config-opts": [
"--disable-doxygen",
"--disable-graphviz",
"--disable-python"
],
"cleanup": [
"/sbin/smbios*",
"/share/locale/*/LC_MESSAGES/libsmbios.mo"
],
"sources": [
{
"type": "archive",
"url": "https://github.com/dell/libsmbios/archive/v2.4.2.tar.gz",
"sha256": "ebfe18415e24bbec06d0a9ea1066c8dcd82982555373712713d7e194138650de"
}
]
},
{
"name": "gnu-efi",
"only-arches": [
"aarch64",
"x86_64"
],
"buildsystem": "simple",
"build-commands": [
"make",
"make PREFIX=/app install"
],
"no-autogen": true,
"cleanup": [
"/bin/efivar"
],
"sources": [
{
"type": "archive",
"url": "http://superb-dca2.dl.sourceforge.net/project/gnu-efi/gnu-efi-3.0.5.tar.bz2",
"sha256": "bd8fcd5914f18fc0e4ba948ab03b00013e528504f529c60739b748f6ef130b22"
}
]
},
{
"name": "python3-olefile",
"only-arches": [
"aarch64",
"x86_64"
],
"buildsystem": "simple",
"build-commands": [
"pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} olefile"
],
"sources": [
{
"type": "file",
"url": "https://pypi.python.org/packages/35/17/c15d41d5a8f8b98cc3df25eb00c5cee76193114c78e5674df6ef4ac92647/olefile-0.44.zip",
"sha256": "61f2ca0cd0aa77279eb943c07f607438edf374096b66332fae1ee64a6f0f73ad"
}
]
},
{
"name": "python3-pillow",
"only-arches": [
"aarch64",
"x86_64"
],
"buildsystem": "simple",
"build-commands": [
"pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} Pillow"
],
"cleanup": [
"/bin/*.py"
],
"sources": [
{
"type": "file",
"url": "https://pypi.python.org/packages/93/73/66854f63b1941aad9af18a1de59f9cf95ad1a87c801540222e332f6688d7/Pillow-4.1.1.tar.gz",
"sha256": "00b6a5f28d00f720235a937ebc2f50f4292a5c7e2d6ab9a8b26153b625c4f431"
}
]
},
{
"name": "fwupd",
"buildsystem": "meson",
"config-opts": [
"-Dconsolekit=false",
"-Ddaemon=false",
"-Dgpg=false",
"-Dgtkdoc=false",
"-Dintrospection=false",
"-Dman=false",
"-Dpkcs7=false",
"-Dsystemd=false",
"-Dtests=false",
"-Defi-includedir=/app/include/efi",
"-Defi-ldsdir=/app/lib",
"-Defi-libdir=/app/lib",
"--sysconfdir=/app/etc",
"--localstatedir=/var/data"
],
"build-options" : {
"arch": {
"i386": {
"config-opts": [
"-Dplugin_dell=false",
"-Dplugin_uefi=false"
]
},
"arm": {
"config-opts": [
"-Dplugin_dell=false",
"-Dplugin_uefi=false"
]
},
"aarch64": {
"config-opts": [
"-Dplugin_dell=false"
]
}
}
},
"cleanup": [
"/etc/dbus-1/system.d/org.freedesktop.fwupd.conf",
"/share/fwupd/remotes.d/vendor"
],
"sources": [
{
"type": "dir",
"skip": [".git"],
"path": ".."
}
]
}
]
}

126
contrib/simple_client.py Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1+
"""A simple fwupd frontend"""
import sys
import os
import gi
from gi.repository import GLib
gi.require_version('Fwupd', '2.0')
from gi.repository import Fwupd #pylint: disable=wrong-import-position
class Progress():
"""Class to track the signal changes of progress events"""
def __init__(self):
self.device = None
self.status = None
self.percent = 0
self.erase = 0
def device_changed(self, new_device):
"""Indicate new device string to track"""
if self.device != new_device:
self.device = new_device
print("\nUpdating %s" % self.device)
def status_changed(self, percent, status):
"""Indicate new status string or % complete to track"""
if self.status != status or self.percent != percent:
for i in range(0, self.erase):
sys.stdout.write("\b \b")
self.status = status
self.percent = percent
status_str = "["
for i in range(0, 50):
if i < percent/2:
status_str += '*'
else:
status_str += ' '
status_str += "] %d%% %s" %(percent, status)
status_str.erase = len(status_str)
sys.stdout.write(status_str)
sys.stdout.flush()
if 'idle' in status:
sys.stdout.write("\n")
def parse_args():
"""Parse arguments for this client"""
import argparse
parser = argparse.ArgumentParser(description="Interact with fwupd daemon")
parser.add_argument("--allow-older", action="store_true",
help="Install older payloads(default False)")
parser.add_argument("--allow-reinstall", action="store_true",
help="Reinstall payloads(default False)")
parser.add_argument("command", choices=["get-devices",
"get-details",
"install"], help="What to do")
parser.add_argument('cab', nargs='?', help='CAB file')
parser.add_argument('deviceid', nargs='?',
help='DeviceID to operate on(optional)')
args = parser.parse_args()
return args
def get_devices(client):
"""Use fwupd client to fetch devices"""
devices = client.get_devices()
for item in devices:
print(item.to_string())
def get_details(client, cab):
"""Use fwupd client to fetch details for a CAB file"""
devices = client.get_details(cab, None)
for device in devices:
print(device.to_string())
def status_changed(client, spec, progress): #pylint: disable=unused-argument
"""Signal emitted by fwupd daemon indicating status changed"""
progress.status_changed(client.get_percentage(),
Fwupd.status_to_string(client.get_status()))
def device_changed(client, device, progress): #pylint: disable=unused-argument
"""Signal emitted by fwupd daemon indicating active device changed"""
progress.device_changed(device.get_name())
def install(client, cab, target, older, reinstall):
"""Use fwupd client to install CAB file to applicable devices"""
# FWUPD_DEVICE_ID_ANY
if not target:
target = '*'
flags = Fwupd.InstallFlags.NONE
if older:
flags |= Fwupd.InstallFlags.ALLOW_OLDER
if reinstall:
flags |= Fwupd.InstallFlags.ALLOW_REINSTALL
progress = Progress()
parent = super(client.__class__, client)
parent.connect('device-changed', device_changed, progress)
parent.connect('notify::percentage', status_changed, progress)
parent.connect('notify::status', status_changed, progress)
try:
client.install(target, cab, flags, None)
except GLib.Error as glib_err: #pylint: disable=catching-non-exception
progress.status_changed(0, 'idle')
print("%s" % glib_err)
sys.exit(1)
def check_cab(cab):
"""Check that CAB file exists"""
if not cab:
print("Need to specify payload")
sys.exit(1)
if not os.path.isfile(cab):
print("%s doesn't exist or isn't a file" % cab)
sys.exit(1)
if __name__ == '__main__':
ARGS = parse_args()
CLIENT = Fwupd.Client()
CLIENT.connect()
if ARGS.command == "get-devices":
get_devices(CLIENT)
elif ARGS.command == "get-details":
check_cab(ARGS.cab)
get_details(CLIENT, ARGS.cab)
elif ARGS.command == "install":
check_cab(ARGS.cab)
install(CLIENT, ARGS.cab, ARGS.deviceid, ARGS.allow_older, ARGS.allow_reinstall)

View File

@ -71,7 +71,7 @@ parts:
meson:
plugin: python
source: https://github.com/mesonbuild/meson.git
source-tag: 0.46.1
source-tag: 0.47.2
build-packages:
- ninja-build
prime:
@ -80,54 +80,6 @@ parts:
- -lib
- -share
- -usr
appstream-glib-dev:
plugin: meson
meson-parameters: [--prefix=/usr, -Dgtk-doc=false, -Dintrospection=false, -Dman=false, -Drpm=false]
source: https://github.com/hughsie/appstream-glib
source-type: git
build-packages:
- python3-pip
- gperf
- intltool
- libarchive-dev
- libgcab-dev
- libgdk-pixbuf2.0-dev
- libgirepository1.0-dev
- libglib2.0-dev
- libgtk-3-dev
- libjson-glib-dev
- libsoup2.4-dev
- libsqlite3-dev
- libyaml-dev
- libstemmer-dev
- uuid-dev
stage-packages:
- libarchive13
- libgcab-1.0-0
- libsoup2.4-1
- libstemmer0d
- libgdk-pixbuf2.0-0
prime:
- -usr/bin
- -usr/include
- -usr/share/doc
- -usr/lib/*/asb-plugins-5
- -usr/share/bash-completion
- -usr/share/aclocal
- -usr/lib/*/pkgconfig
- -usr/share/installed-tests
- -usr/lib/systemd
- -usr/lib/glib-networking
- -usr/lib/dconf
- -usr/share/X11
- -usr/share/GConf
- -usr/share/dbus-1
- -usr/share/glib-2.0/schemas
- -usr/share/lintian
- -usr/share/man
- -usr/lib/*/gdk-pixbuf-2.0
- -usr/share/gettext
after: [meson]
gudev:
plugin: autotools
source: https://gitlab.gnome.org/GNOME/libgudev.git
@ -238,6 +190,8 @@ parts:
-Dintrospection=false,
-Dman=false,
-Dudevdir=$SNAPCRAFT_STAGE/lib/udev,
-Dlibxmlb:gtkdoc=false,
-Dlibxmlb:introspection=false,
-Dpkcs7=false]
source: .
source-type: git
@ -310,7 +264,7 @@ parts:
- -usr/share/gir-1.0
- -usr/share/upstart
- -usr/lib/*/pkgconfig
after: [appstream-glib-dev, gudev, gusb, gnu-efi, libefivar-fixpkgconfig, libsmbios, build-introspection, gettext]
after: [gudev, gusb, gnu-efi, libefivar-fixpkgconfig, libsmbios, build-introspection, gettext]
fix-bash-completion:
plugin: make
source: contrib/snap/fix-bash-completion

View File

@ -1,337 +0,0 @@
name: fwupd
version-script: cat $SNAPCRAFT_STAGE/version
version: 'daily'
summary: A standalone version of fwupd to install newer firmware updates
description: |
This is a tool that can be used to install firmware updates on devices
not yet supported by the version of fwupd distributed with the OS.
grade: stable
confinement: classic
architectures:
- amd64
apps:
dfu-tool:
command: dfu-tool.wrapper
fwupdtool:
command: fwupdtool.wrapper
completer:
share/bash-completion/completions/fwupdtool
fwupd:
command: fwupd.wrapper
daemon: simple
fwupdmgr:
command: fwupdmgr.wrapper
completer:
share/bash-completion/completions/fwupdmgr
parts:
libefivar-dev:
plugin: make
make-parameters:
- prefix=/
- libdir=/lib
source: https://github.com/rhboot/efivar/releases/download/35/efivar-35.tar.bz2
build-packages:
- libpopt-dev
prime:
- -include
- -bin
- -share/man
- -lib/pkgconfig
#adjust the paths from libefivar
libefivar-fixpkgconfig:
plugin: make
source: contrib/snap/libefivar-fixpkgconfig
make-parameters:
- SNAPCRAFT_STAGE=$SNAPCRAFT_STAGE
after: [libefivar-dev]
libsmbios:
plugin: autotools
source: https://github.com/dell/libsmbios/archive/v2.4.2.tar.gz
build-packages:
- libxml2-dev
- pkg-config
- autoconf
- automake
- libtool
- autopoint
prime:
- -include/
- -lib/pkgconfig
- -lib/python3.5
- -sbin/
- -share/
- -etc/
- -lib/*.a
meson:
plugin: python
source: https://github.com/mesonbuild/meson/releases/download/0.46.1/meson-0.46.1.tar.gz
build-packages:
- ninja-build
prime:
- -bin
- -etc
- -lib
- -share
- -usr
appstream-glib-dev:
plugin: meson
meson-parameters: [--prefix=/usr, -Dgtk-doc=false, -Dintrospection=false, -Dman=false, -Drpm=false]
source: https://github.com/hughsie/appstream-glib/archive/appstream_glib_0_7_9.tar.gz
build-packages:
- python3-pip
- gperf
- intltool
- libarchive-dev
- libgcab-dev
- libgdk-pixbuf2.0-dev
- libgirepository1.0-dev
- libglib2.0-dev
- libgtk-3-dev
- libjson-glib-dev
- libsoup2.4-dev
- libsqlite3-dev
- libyaml-dev
- libstemmer-dev
- uuid-dev
stage-packages:
- libarchive13
- libgcab-1.0-0
- libsoup2.4-1
- libstemmer0d
- libgdk-pixbuf2.0-0
prime:
- -usr/bin
- -usr/include
- -usr/share/doc
- -usr/lib/*/asb-plugins-5
- -usr/share/bash-completion
- -usr/share/aclocal
- -usr/lib/*/pkgconfig
- -usr/share/installed-tests
- -usr/lib/systemd
- -usr/lib/glib-networking
- -usr/lib/dconf
- -usr/share/X11
- -usr/share/GConf
- -usr/share/dbus-1
- -usr/share/glib-2.0/schemas
- -usr/share/lintian
- -usr/share/man
- -usr/lib/*/gdk-pixbuf-2.0
- -usr/share/gettext
after: [meson]
gudev:
plugin: autotools
source: https://github.com/GNOME/libgudev/archive/232.tar.gz
configflags:
- --disable-umockdev
build-packages:
- libglib2.0-dev
- pkg-config
- libudev-dev
- gtk-doc-tools
- gnome-common
prime:
- -include
- -lib/girepository-1.0
- -lib/pkgconfig
- -share/
libusb:
plugin: autotools
source: https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.tar.bz2
configflags:
- --disable-static
prime:
- -include/
- -lib/pkgconfig
gusb:
plugin: meson
source: https://github.com/hughsie/libgusb/archive/0.3.0.tar.gz
meson-parameters: [--prefix=/,
-Dtests=false,
-Dvapi=false,
-Ddocs=false]
build-packages:
- libgirepository1.0-dev
prime:
- -bin/
- -include
- -share
- -lib/*/pkgconfig
- -lib/*/girepository-1.0
after: [meson, libusb]
gnu-efi:
plugin: make
source: http://superb-dca2.dl.sourceforge.net/project/gnu-efi/gnu-efi-3.0.5.tar.bz2
make-parameters:
- PREFIX=/usr
make-install-var: INSTALLROOT
prime:
- -usr/include/
- -usr/lib
#fetch the latest version of the signed bootloader
#this might not match our fwupdx64.efi, but it's better than nothing
fwup-efi-signed:
build-packages:
- python3-apt
plugin: make
source: contrib/snap/fwup-efi-signed
#needed for UEFI plugin to build UX labels
build-introspection:
plugin: nil
stage-packages:
- python3-gi
- python3-gi-cairo
- python3-pil
prime:
- -etc
- -usr
- -lib
- -var
#0.19.8.1 adds support for GETTEXTDATADIRS which is needed by meson's msgfmthelper
gettext:
source: https://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.1.tar.xz
plugin: autotools
build-packages:
- bison
- libunistring-dev
- libxml2-dev
configflags:
- --prefix=/usr
- --disable-static
- --disable-curses
- --disable-java
- --enable-relocatable
- --without-emacs
- --without-included-glib
- --without-included-libunistring
- --without-included-libxml
stage-packages:
- libunistring0
- libxml2
- libgomp1
prime:
- -**/*.a
- -**/*.la
- -usr/bin
- -usr/include
- -usr/lib/gettext
- -usr/share
fwupd:
plugin: meson
meson-parameters: [--prefix=/,
-Defi-includedir=$SNAPCRAFT_STAGE/usr/include/efi,
-Defi-ldsdir=$SNAPCRAFT_STAGE/usr/lib,
-Defi-libdir=$SNAPCRAFT_STAGE/usr/lib,
-Dtests=false,
-Ddaemon=true,
-Dgtkdoc=false,
-Dintrospection=false,
-Dman=false,
-Dudevdir=$SNAPCRAFT_STAGE/lib/udev,
-Dpkcs7=false]
source: .
source-type: git
override-build: |
snapcraftctl build
echo $(git describe HEAD --always) > $SNAPCRAFT_STAGE/version
build-packages:
- bash-completion
- gcab
- gnutls-dev
- libarchive-dev
- libcairo-dev
- libelf-dev
- libgcab-dev
- libglib2.0-dev
- libgpgme11-dev
- libjson-glib-dev
- libpango1.0-dev
- libpolkit-gobject-1-dev
- libsoup2.4-dev
- libsqlite3-dev
- locales
- pkg-config
- uuid-dev
stage-packages:
- libgcab-1.0-0
- libarchive13
- libassuan0
- liblcms2-2
- libelf1
- libgpgme11
- libjson-glib-1.0-0
- libpolkit-gobject-1-0
- libsoup2.4-1
- glib-networking
- libglib2.0-bin
prime:
# we explicitly don't want /usr/bin/gpgconf
# this will cause gpgme to error finding it
# but that also avoids trying to use non-existent
# /usr/bin/gpg2
- -usr/bin
- -usr/sbin
- -usr/share/man
- -usr/share/GConf
- -etc/X11
- -etc/ldap
- -etc/logcheck
- -usr/lib/dconf
- -usr/lib/gcc
- -usr/lib/glib-networking
- -usr/lib/gnupg2
- -usr/lib/sasl2
- -usr/lib/systemd
- -usr/lib/*/audit
- -usr/share/glib-2.0/schemas
- -usr/share/X11
- -include
- -lib/systemd
- -lib/udev
- -lib/*/pkgconfig
- -usr/share/lintian
- -usr/share/pkgconfig
- -usr/share/installed-tests
- -usr/share/polkit-1
- -usr/share/vala
- -usr/share/doc
- -usr/share/gnupg2
- -usr/share/info
- -usr/share/gir-1.0
- -usr/share/upstart
- -usr/lib/*/pkgconfig
after: [appstream-glib-dev, gudev, gusb, gnu-efi, libefivar-fixpkgconfig, libsmbios, build-introspection, gettext]
fix-bash-completion:
plugin: make
source: contrib/snap/fix-bash-completion
after: [fwupd]
update-mime:
plugin: make
source: contrib/snap/update-mime
stage-packages:
- shared-mime-info
- gsettings-desktop-schemas
- libxml2
prime:
- -usr/bin
- -usr/share/doc
- -usr/share/doc-base
- -usr/share/man
- -usr/share/lintian
- -usr/share/pkgconfig
- -usr/share/GConf
after: [fwupd]
fwupd-wrappers:
plugin: dump
source: contrib/snap
stage:
- dfu-tool.wrapper
- fwupd-command
- fwupdtool.wrapper
- fwupd.wrapper
- fwupdmgr.wrapper

View File

@ -128,7 +128,7 @@ def install_flatpak (directory, verbose, uninstall):
else:
output = None
#look for dependencies
dep = 'org.gnome.Platform/x86_64/3.28'
dep = 'org.gnome.Platform/x86_64/3.30'
repo = 'flathub'
repo_url = 'https://flathub.org/repo/flathub.flatpakrepo'
cmd = ['flatpak', 'info', dep]

View File

@ -85,8 +85,23 @@ def download_cab_file (directory, uri):
subprocess.run (cmd, cwd=directory, check=True)
def download_flatpak (directory):
cmd = ['wget', 'https://people.freedesktop.org/~hughsient/temp/fwupd.flatpak', '-O', 'fwupd.flatpak']
if 'DEBUG' in os.environ:
dep = 'org.freedesktop.fwupd'
flatpak_dir = os.path.join(os.getenv('HOME'),'.local', 'share', 'flatpak')
verbose = 'DEBUG' in os.environ
#check if we have installed locally already or not
if not os.path.exists (os.path.join (flatpak_dir, 'app', dep)):
# install into local user's repo
cmd = ['flatpak', 'install', '--user',
'https://www.flathub.org/repo/appstream/org.freedesktop.fwupd.flatpakref', '--no-deps', '-y']
if verbose:
print(cmd)
subprocess.run (cmd, cwd=directory, check=True)
# generate a bundle
repo = os.path.join(flatpak_dir, 'repo')
cmd = ['flatpak', 'build-bundle', repo, 'fwupd.flatpak', dep, 'stable']
if verbose:
print(cmd)
subprocess.run (cmd, cwd=directory, check=True)

39
contrib/vscode/README.md Normal file
View File

@ -0,0 +1,39 @@
# Using Visual Studio Code to debug
This directory contains a collection of scripts and assets to make debugging using Visual Studio Code easier.
## Preparing
First install the following applications locally:
* GDB Server
* GDB
* Visual Studio Code
In Visual Studio code, visit the extension store and install *C/C++* which is an extension provided by Microsoft.
Configure Visual Studio code to open the folder representing the root of the fwupd checkout.
## Building
Run `./contrib/debugging/build.sh` to build fwupd with all default options and create helper scripts pre-configured for debugger use.
The application will be placed into `./dist` and helper scripts will be created for `fwupdtool`, `fwupdmgr`, and `fwupd`.
## Running
To run any of the applications, execute the appropriate helper script in `./dist`.
## Debugging
To debug any of the applications, launch the helper script with the environment variable `DEBUG` set.
For example to debug `fwupdtool get-devices` the command to launch would be:
```
sudo DEBUG=1 ./dist/fwupdtool.sh get-devices
```
This will configure `gdbserver` to listen on a local port waiting for a debugger to connect.
## Using Visual Studio code
During build time a set of launch targets will have been created for use with Visual Studio Code.
Press the debugging button on the left and 3 targets will be listed at the top.
* gdbserver (fwupdtool)
* gdbserver (fwupd)
* gdbserver (fwupdmgr)
Select the appropriate target and press the green arrow to connect to `gdbserver` and start debugging.

32
contrib/vscode/build.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/sh
# Copyright (C) 2018 Dell, Inc.
SOURCE=$(dirname $0)
ROOT=$1
if [ -z "$ROOT" ]; then
ROOT=`pwd`
fi
# build in tree
rm -rf build ${ROOT}/dist
meson build --prefix=${ROOT}/dist -Dsystemd=false -Dudevdir=${ROOT}/dist
ninja -C build install
#create helper scripts
TEMPLATE=${SOURCE}/launcher.sh
sed "s,#ROOT#,${ROOT},; s,#EXECUTABLE#,libexec/fwupd/fwupd," \
${TEMPLATE} > ${ROOT}/dist/fwupd.sh
sed "s,#ROOT#,${ROOT},; s,#EXECUTABLE#,libexec/fwupd/fwupdtool," \
${TEMPLATE} > ${ROOT}/dist/fwupdtool.sh
sed "s,#ROOT#,${ROOT},; s,#EXECUTABLE#,bin/fwupdmgr," \
${TEMPLATE} > ${ROOT}/dist/fwupdmgr.sh
chmod +x ${ROOT}/dist/*.sh
#create debugging targets
TARGET=${ROOT}/.vscode
mkdir -p ${TARGET}
if [ -f ${TARGET}/launch.json ]; then
echo "${TARGET}/launch.json already exists, not overwriting"
else
cp ${SOURCE}/launch.json ${TARGET}
fi

View File

@ -0,0 +1,68 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gdbserver (fwupdtool)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/dist/libexec/fwupd/fwupdtool",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"miDebuggerServerAddress": "localhost:9091",
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "gdbserver (fwupd)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/dist/libexec/fwupd/fwupd",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"miDebuggerServerAddress": "localhost:9091",
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "gdbserver (fwupdmgr)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/dist/bin/fwupdmgr",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"miDebuggerServerAddress": "localhost:9091",
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
]
}

8
contrib/vscode/launcher.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
export ROOT=#ROOT#
export FWUPD_LOCALSTATEDIR=${ROOT}/dist
export FWUPD_SYSCONFDIR=${ROOT}/dist/etc
if [ -n "${DEBUG}" ]; then
DEBUG="gdbserver localhost:9091"
fi
${DEBUG} ${ROOT}/dist/#EXECUTABLE# "$@"

View File

@ -1,5 +1,4 @@
_fwupdmgr_cmd_list=(
'build-firmware'
'clear-history'
'clear-offline'
'clear-results'
@ -17,7 +16,6 @@ _fwupdmgr_cmd_list=(
'install'
'install-prepared'
'modify-remote'
'monitor'
'refresh'
'report-history'
'unlock'
@ -147,23 +145,6 @@ _fwupdmgr()
_show_modifiers
fi
;;
build-firmware)
#file in
if [[ "$prev" = "$command" ]]; then
_filedir
#file out
elif [[ "$prev" = "${COMP_WORDS[2]}" ]]; then
_filedir
#script
elif [[ "$prev" = "${COMP_WORDS[3]}" ]]; then
_filedir
#output
elif [[ "$prev" = "${COMP_WORDS[4]}" ]]; then
_filedir
else
_show_modifiers
fi
;;
*)
#find first command
if [[ ${COMP_CWORD} = 1 ]]; then

View File

@ -1,11 +1,15 @@
_fwupdtool_cmd_list=(
'build-firmware'
'get-updates'
'get-details'
'get-devices'
'get-plugins'
'get-topology'
'hwids'
'update'
'install'
'install-blob'
'monitor'
'smbios-dump'
'attach'
'detach'
@ -66,6 +70,23 @@ _fwupdtool()
_show_modifiers
fi
;;
build-firmware)
#file in
if [[ "$prev" = "$command" ]]; then
_filedir
#file out
elif [[ "$prev" = "${COMP_WORDS[2]}" ]]; then
_filedir
#script
elif [[ "$prev" = "${COMP_WORDS[3]}" ]]; then
_filedir
#output
elif [[ "$prev" = "${COMP_WORDS[4]}" ]]; then
_filedir
else
_show_modifiers
fi
;;
*)
#find first command
if [[ ${COMP_CWORD} = 1 ]]; then

View File

@ -10,3 +10,9 @@ BlacklistPlugins=test
# Maximum archive size that can be loaded in Mb, with 0 for the default
ArchiveSizeMax=0
# Idle time in seconds to shut down the daemon -- note some plugins might
# inhibit the auto-shutdown, for instance thunderbolt.
#
# A value of 0 specifies 'never'
IdleTimeout=7200

View File

@ -0,0 +1,78 @@
Installed tests
=========
A test suite that can be used to interact with a fake device is installed when
configured with `-Ddaemon=true` and `-Dtests=true`.
By default this test suite is disabled.
Enabling
=======
To enable the test suite:
1. Modify `/etc/fwupd/daemon.conf` to remove the `test` plugin from `BlacklistPlugins`
```
# sed "s,^Enabled=false,Enabled=true," -i /etc/fwupd/remotes.d/fwupd-tests.conf
```
2. Enable the `fwupd-tests` remote for local CAB files.
```
# fwupdmgr enable-remote fwupd-tests
```
Using test suite
=====
When the daemon is started with the test suite enabled a fake webcam device will be created with a pending update.
```
Integrated Webcam™
DeviceId: 08d460be0f1f9f128413f816022a6439e0078018
Guid: b585990a-003e-5270-89d5-3705a17f9a43
Summary: A fake webcam
Plugin: test
Flags: updatable|supported|registered
Vendor: ACME Corp.
VendorId: USB:0x046D
Version: 1.2.2
VersionLowest: 1.2.0
VersionBootloader: 0.1.2
Icon: preferences-desktop-keyboard
Created: 2018-11-29
```
## Upgrading
This can be upgraded to a firmware version `1.2.4` by using `fwupdmgr update` or any fwupd frontend.
```
$ fwupdmgr get-updates
Integrated Webcam™ has firmware updates:
GUID: b585990a-003e-5270-89d5-3705a17f9a43
ID: fakedevice.firmware
Update Version: 1.2.4
Update Name: FakeDevice Firmware
Update Summary: Firmware for the ACME Corp Integrated Webcam
Update Remote ID: fwupd-tests
Update Checksum: SHA1(fc0aabcf98bf3546c91270f2941f0acd0395dd79)
Update Location: ./fakedevice124.cab
Update Description: Fixes another bug with the flux capacitor to prevent time going backwards.
$ fwupdmgr update
Decompressing… [***************************************]
Authenticating… [***************************************]
Updating Integrated Webcam™… ]
Verifying… [***************************************] Less than one minute remaining…
```
## Downgrading
It can also be downgraded to firmware version `1.2.3`.
```
$ fwupdmgr downgrade
Choose a device:
0. Cancel
1. 08d460be0f1f9f128413f816022a6439e0078018 (Integrated Webcam™)
2. 8a21cacfb0a8d2b30c5ee9290eb71db021619f8b (XPS 13 9370 System Firmware)
3. d10c5f0ed12c6dc773f596b8ac51f8ace4355380 (XPS 13 9370 Thunderbolt Controller)
1
Decompressing… [***************************************]
Authenticating… [***************************************]
Downgrading Integrated Webcam™… \ ]
Verifying… [***************************************] Less than one minute remaining…
```

View File

@ -1,11 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
iQEcBAABAgAGBQJZQqy+AAoJEEim2A5FOLrCjuEH/1wIRvQ9FIUqQ2wV5pQRjF99
wTd1+VtQCPHkBXvMnrF2cnhNhr13lN8BhuY3kgT9TGQCPNM+8akNvDLKWiR/39rP
z+v6KpgaYA5kghFskvW4t/1lQ+Jj+PKExb1bAusexdVvRD1iEDZ0q8u/DRGwrjYn
GFbHD3K91B4nIzYQVHa8+9gRRH2uKa2U9foH3++e/PAPQCoGHa6gxV3zM05AiEpA
Am5G5u8v5WnL9W9H53unj9M47iAlzdxStzK4poshlJoNITLw9SLl6rmrgMYLHVfD
QyZTM8jSjFc+V1swslLNMVCkCWfx3ClzkEff50HKua/BxMxxJscShX43On59cik=
=XhuO
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<components version="0.9" origin="lvfs">
<component type="firmware">
<id>fakedevice.firmware</id>
<name>FakeDevice Firmware</name>
<summary>Firmware for the ACME Corp Integrated Webcam</summary>
<developer_name>ACME Corp</developer_name>
<project_license>GPL-2.0+</project_license>
<description><p>Updating the firmware on your webcam device improves performance and adds new features.</p></description>
<url type="homepage">http://www.acme.com/</url>
<releases>
<release version="1.2.4" timestamp="1497499200" urgency="medium">
<size type="installed">17</size>
<size type="download">1163</size>
<location>./fakedevice124.cab</location>
<checksum filename="fakedevice124.cab" target="container" type="sha1">fc0aabcf98bf3546c91270f2941f0acd0395dd79</checksum>
<checksum filename="fakedevice124.bin" target="content" type="sha1">2b8546ba805ad10bf8a2e5ad539d53f303812ba5</checksum>
<description><p>Fixes another bug with the flux capacitor to prevent time going backwards.</p></description>
</release>
<release version="1.2.3" timestamp="1497499200" urgency="medium">
<size type="installed">17</size>
<size type="download">1153</size>
<location>./fakedevice123.cab</location>
<checksum filename="fakedevice123.cab" target="container" type="sha1">bc3c32f42cf33fe5aade64f999417251fd8208d3</checksum>
<checksum filename="fakedevice123.bin" target="content" type="sha1">7998cd212721e068b2411135e1f90d0ad436d730</checksum>
<description><p>Fixes a bug with the flux capacitor to avoid year 2038 overflow.</p></description>
</release>
</releases>
<provides>
<firmware type="flashed">b585990a-003e-5270-89d5-3705a17f9a43</firmware>
</provides>
</component>
<component type="firmware">
<id>com.hughski.ColorHug2.firmware</id>
<name>ColorHug2</name>
<summary>Firmware for the Hughski ColorHug2 Colorimeter</summary>
<developer_name>Hughski Limited</developer_name>
<project_license>GPL-2.0+</project_license>
<description><p>Updating the firmware on your ColorHug2 device improves performance and adds new features.</p></description>
<url type="homepage">http://www.hughski.com/</url>
<releases>
<release version="2.0.7" timestamp="1482901200" urgency="medium">
<size type="installed">16384</size>
<size type="download">19592</size>
<location>hughski-colorhug2-2.0.7.cab</location>
<checksum filename="0a29848de74d26348bc5a6e24fc9f03778eddf0e-hughski-colorhug2-2.0.7.cab" target="container" type="sha1">490be5c0b13ca4a3f169bf8bc682ba127b8f7b96</checksum>
<checksum filename="firmware.bin" target="content" type="sha1">658851e6f27c4d87de19cd66b97b610d100efe09</checksum>
<description><p>This release fixes prevents the firmware returning an error when the remote SHA1 hash was never sent.</p></description>
</release>
</releases>
<provides>
<firmware type="flashed">2082b5e0-7a64-478a-b1b2-e3404fab6dad</firmware>
</provides>
</component>
<component type="firmware">
<id>com.hughski.ColorHug.firmware</id>
<name>ColorHug</name>
<summary>Firmware for the Hughski ColorHug Colorimeter</summary>
<developer_name>Hughski Limited</developer_name>
<project_license>GPL-2.0+</project_license>
<description><p>Updating the firmware on your ColorHug device improves performance and adds new features.</p></description>
<url type="homepage">http://www.hughski.com/</url>
<releases>
<release version="1.2.6" timestamp="1480683870" urgency="low">
<size type="installed">16384</size>
<size type="download">18054</size>
<location>hughski-colorhug-1.2.6.cab</location>
<checksum filename="aa1b94b36c91929fbf75551b8a376d7292f8c51c-hughski-colorhug-1.2.6.cab" target="container" type="sha1">570a4259af0c7670f3883e84d2f4e6ff7de572c2</checksum>
<checksum filename="firmware.bin" target="content" type="sha1">111784ffadfd5dd43f05655b266b5142230195b6</checksum>
<description><p>This release fixes prevents the firmware returning an error when the remote SHA1 hash was never sent.</p></description>
</release>
</releases>
<provides>
<firmware type="flashed">40338ceb-b966-4eae-adae-9c32edfcc484</firmware>
</provides>
</component>
</components>

View File

@ -9,8 +9,8 @@ fwupdmgr get-remotes
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
# ---
echo "Refreshing with dummy metadata..."
fwupdmgr refresh ${dirname}/firmware-example.xml.gz ${dirname}/firmware-example.xml.gz.asc lvfs
echo "Enabling fwupd-tests remote..."
fwupdmgr enable-remote fwupd-tests
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
# ---

View File

@ -13,8 +13,7 @@ configure_file(
install_data([
'fwupdmgr.sh',
'firmware-example.xml.gz',
'firmware-example.xml.gz.asc',
'fwupd-tests.xml',
'hardware.py',
],
install_dir : 'share/installed-tests/fwupd',
@ -46,3 +45,12 @@ custom_target('installed-cab124',
install: true,
install_dir: join_paths('share', 'installed-tests', 'fwupd'),
)
# replace @installedtestsdir@
configure_file(
input : 'remote.conf.in',
output : 'fwupd-tests.conf',
configuration : con2,
install: true,
install_dir: join_paths(sysconfdir, 'fwupd', 'remotes.d'),
)

View File

@ -0,0 +1,9 @@
[fwupd Remote]
# This is a local fwupd remote that is used only for installed tests
# either from continuous integration or for fake devices from fwupd
# frontends
Enabled=false
Title=fwupd test suite
Keyring=none
MetadataURI=file://@installedtestsdir@/fwupd-tests.xml

View File

@ -3,8 +3,10 @@ subdir('pki')
subdir('remotes.d')
subdir('bash-completion')
if get_option('tests') and get_option('daemon')
if get_option('tests')
subdir('tests')
endif
if get_option('daemon')
subdir('installed-tests')
endif
@ -38,7 +40,7 @@ if get_option('systemd')
rw_directories = []
rw_directories += join_paths (localstatedir, 'lib', 'fwupd')
rw_directories += join_paths (default_sysconfdir, 'fwupd', 'remotes.d')
rw_directories += join_paths (sysconfdir, 'fwupd', 'remotes.d')
if get_option('plugin_uefi')
rw_directories += ['-/boot/efi', '-/efi/EFI', '-/boot/EFI']
endif

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
Vendor Firmware
===============
These are the steps to add vendor that is installed as part of an OSTree image:
These are the steps to add vendor firmware that is installed as part of an embedded image such as an OSTree or ChromeOS image:
* Change `/etc/fwupd/remotes.d/vendor.conf` to have `Enabled=true`
* Change `/etc/fwupd/remotes.d/vendor.conf` to have the correct `Title`
* Deploy the firmware to `/usr/share/fwupd/remotes.d/vendor/firmware`
* Deploy the metadata to `/usr/share/fwupd/remotes.d/vendor/vendor.xml`
* Deploy the metadata to `/usr/share/fwupd/remotes.d/vendor/vendor.xml.gz`
The metadata should be of the form:
@ -39,6 +39,20 @@ certificate. If this is the case also change `Keyring=gpg` or `Keyring=pkcs7`
in `/etc/fwupd/remotes.d/vendor.conf` and ensure the correct public key or
signing certificate is installed in the `/etc/pki/fwupd` location.
Automatic metadata generation
=============================
`fwupd` and `fwupdtool` support automatically generating metadata for a remote
by configuring it to be a *directory* type. This is very convenient if you want to dynamically add firmware from multiple packages while generating the image but there are a few deficiencies:
* There will be a performance impact of starting the daemon or tool measured by O(# CAB files)
* It's not possible to verify metadata signature and any file validation should be part of the image validation.
To enable this:
* Change `/etc/fwupd/remotes.d/vendor-directory.conf` to have `Enabled=true`
* Change `/etc/fwupd/remotes.d/vendor.conf-directory` to have the correct `Title`
* Deploy the firmware to `/usr/share/fwupd/remotes.d/vendor/firmware`
* Change `MetadataURI` to that of the directory (Eg `/usr/share/fwupd/remotes.d/vendor/`)
Mirroring a Repository
======================

View File

@ -46,3 +46,10 @@ configure_file(
install: true,
install_dir: join_paths(sysconfdir, 'fwupd', 'remotes.d'),
)
configure_file(
input : 'vendor-directory.conf',
output : 'vendor-directory.conf',
configuration : con2,
install: true,
install_dir: join_paths(sysconfdir, 'fwupd', 'remotes.d'),
)

View File

@ -0,0 +1,7 @@
[fwupd Remote]
# this remote provides dynamically generated metadata shipped by the OS vendor and can
# be found in @datadir@/fwupd/remotes.d/vendor/firmware
Enabled=false
Title=Vendor (Automatic)
Keyring=none
MetadataURI=file://@datadir@/fwupd/remotes.d/vendor/firmware

View File

@ -1,7 +1,6 @@
[fwupd Remote]
# this remote provides metadata shipped by the OS vendor and can be found in
# /usr/share/fwupd/remotes.d/vendor and /usr/share/fwupd/remotes.d/vendor/firmware
# @datadir@/fwupd/remotes.d/vendor and firmware in @datadir@/fwupd/remotes.d/vendor/firmware
Enabled=false
Title=Vendor
Keyring=none

View File

@ -0,0 +1,4 @@
[fwupd Remote]
Enabled=true
Keyring=none
MetadataURI=file:///tmp/fwupd-self-test/var/cache/fwupd

17
debian/control.in vendored
View File

@ -22,8 +22,7 @@ Description: Firmware update daemon library
fwupd is a daemon to allow session software to update device firmware.
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Currently, firmware updates using the UEFI capsule format and for the
ColorHug are supported. More formats may be supported in the future.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
.
This package provides the library used by the daemon.
@ -34,6 +33,8 @@ Depends: ${misc:Depends},
${shlibs:Depends}
Recommends: python3,
bolt,
tpm2-tools,
tpm2-abrmd,
fwupd-signed
Breaks: gir1.2-dfu-1.0 (<< 0.9.7-1),
libdfu1 (<< 0.9.7-1),
@ -46,8 +47,7 @@ Description: Firmware update daemon
fwupd is a daemon to allow session software to update device firmware.
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Currently, firmware updates using the UEFI capsule format and for the
ColorHug are supported. More formats may be supported in the future.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
Package: fwupd-tests
@ -69,8 +69,7 @@ Description: Test suite for firmware update daemon
fwupd is a daemon to allow session software to update device firmware.
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Currently, firmware updates using the UEFI capsule format and for the
ColorHug are supported. More formats may be supported in the future.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
.
This package provides a set of installed tests that can be run to validate
@ -85,8 +84,7 @@ Description: Firmware update daemon documentation (HTML format)
fwupd is a daemon to allow session software to update device firmware.
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Currently, firmware updates using the UEFI capsule format and for the
ColorHug are supported. More formats may be supported in the future.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
.
This package provides development documentation for creating a package that
@ -105,8 +103,7 @@ Description: development files for libfwupd
fwupd is a daemon to allow session software to update device firmware.
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Currently, firmware updates using the UEFI capsule format and for the
ColorHug are supported. More formats may be supported in the future.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
.
This package provides the development files for libfwupd

2
debian/docs vendored
View File

@ -1 +1 @@
NEWS

View File

@ -5,3 +5,4 @@
usr/share/installed-tests/*
usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so
debian/lintian/fwupd-tests usr/share/lintian/overrides
etc/fwupd/remotes.d/fwupd-tests.conf

View File

@ -12,4 +12,12 @@ if [ "$1" = configure ] && [ -z "$2" ]; then
echo "To enable test suite, modify /etc/fwupd/daemon.conf"
fi
fi
if [ -f /etc/fwupd/remotes.d/fwupd-tests.conf ]; then
if [ "$CI" = "true" ]; then
sed "s,^Enabled=false,Enabled=true," -i /etc/fwupd/remotes.d/fwupd-tests.conf
else
echo "To enable test suite, enable fwupd-tests remote"
fi
fi
fi

View File

@ -1 +1 @@
usr/lib/*/girepository-1.0/Fwupd-2.0.typelib
usr/lib/*/girepository-1.0/*.typelib

View File

@ -1,6 +1,5 @@
usr/include/fwupd-1/fwupd.h
usr/include/fwupd-1/libfwupd
usr/lib/*/libfwupd*.so
usr/lib/*/pkgconfig/fwupd.pc
usr/share/gir-1.0/Fwupd*.gir
usr/include/*
usr/lib/*/*.so
usr/lib/*/pkgconfig/*.pc
usr/share/gir-1.0/*.gir
usr/share/vala/vapi

View File

@ -1 +1 @@
usr/lib/*/libfwup*.so.*
usr/lib/*/*.so.*

11
debian/rules vendored
View File

@ -10,7 +10,8 @@ ifeq "$(DEB_HOST_ARCH_BITS)" "32"
endif
ifneq ($(CI),)
export CI=--werror
export CI=--werror --wrap-mode=forcefallback
export DHSLIBS=-- --ignore-missing-info
endif
regenerate_control:
@ -57,10 +58,15 @@ override_dh_install:
dh_install -pfwupd usr/lib/fwupd/efi ;\
dh_install -pfwupd usr/lib/fwupd/fwupdate; \
fi
#if build with meson subproject in CI need to install this too
if [ -n "$CI" ] && [ -f debian/tmp/usr/lib/xb-tool ]; then \
dh_install -pfwupd usr/lib/xb-tool ;\
fi
dh_missing -a --fail-missing
#this is placed in fwupd-tests
rm -f debian/fwupd/usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so
rm -f debian/fwupd/etc/fwupd/remotes.d/fwupd-tests.conf
ifeq (debian,$(SB_STYLE))
# Generate the template source for the Debian signing service to use
@ -95,3 +101,6 @@ ifeq (ubuntu,$(SB_STYLE))
dpkg-distaddfile $(tar_name) raw-uefi - ;\
fi
endif
override_dh_shlibdeps:
dh_shlibdeps $$DHSLIBS

View File

@ -1,2 +1,4 @@
#github doesn't have these
fwupd source: debian-watch-does-not-check-gpg-signature
#to make CI happy until libxmlb lands
fwupd source: source-is-missing

58
docs/version-format.md Normal file
View File

@ -0,0 +1,58 @@
Version Formats
===============
In some circumstances fwupd has to convert from a unsigned integer version
number into something that has either been used in documentation or has been
defined in some specification.
A good example here is the UEFI ESRT table, which specifies a `uint32_t` for
the version but does not specify how this should be formatted for the user.
As is typical in underspecified specifications, vendors have converted the
integer in different ways. For instance, Dell uses version strings like 1.2.3
and Microsoft use versions like 1.2.3.4.
The fwudp daemon can match specific devices and apply the correct version style
using quirk files. The version format can also be specified in the firmware
`metainfo.xml` file so that the new version is correctly shown, and so that it
matches on the LVFS website.
The current version formats supported by fwupd and the LVFS are:
* `plain`: Use plain integer version numbers with no dots, e.g. `AABBCCDD`
* `quad`: Use Dell-style `AA.BB.CC.DD` version numbers
* `triplet`: Use Microsoft-style `AA.BB.CCDD` version numbers
* `pair`: Use two `AABB.CCDD` version numbers
* `bcd`: Use binary coded decimal notation
* `intel-me`: Use Intel ME-style notation (`aaa+11.bbbbb.CC.DDDD`)
* `intel-me2`: Use alternate Intel ME-style-style `A.B.CC.DDDD` notation
These can be specified in quirk files like this:
# Vendor Modelname
[Guid=5b92717b-2cad-4a96-a13b-9d65781df8bf]
VersionFormat = intel-me2
...or in metainfo.xml files like this:
<custom>
<value key="LVFS::VersionFormat">intel-me2</value>
</custom>
Runtime requirements
--------------------
Versions of fwupd `< 1.2.0` can only support firmware updates with key values
`LVFS::VersionFormat` of `quad` and `triplet`. Additionally, on older versions
no quirk `VersionFormat` device fixups are supported.
If want to use one of the additional version formats you should depend on a
specific version of fwupd in the firmware file:
<requires>
<id compare="ge" version="1.2.0">org.freedesktop.fwupd</id>
</requires>
This is not *strictly* required, as the integer value can be used for update
calculations if the version is specified in hex (e.g. `0x12345678`) in the
`<release>` tag, although the user might get a bit confused if the update
version does not match the update description.

View File

@ -37,6 +37,7 @@ static void fwupd_client_finalize (GObject *object);
typedef struct {
FwupdStatus status;
gboolean tainted;
guint percentage;
gchar *daemon_version;
GDBusConnection *conn;
@ -57,6 +58,7 @@ enum {
PROP_STATUS,
PROP_PERCENTAGE,
PROP_DAEMON_VERSION,
PROP_TAINTED,
PROP_LAST
};
@ -131,6 +133,14 @@ fwupd_client_properties_changed_cb (GDBusProxy *proxy,
g_object_notify (G_OBJECT (client), "status");
}
}
if (g_variant_dict_contains (dict, "Tainted")) {
g_autoptr(GVariant) val = NULL;
val = g_dbus_proxy_get_cached_property (proxy, "Tainted");
if (val != NULL) {
priv->tainted = g_variant_get_boolean (val);
g_object_notify (G_OBJECT (client), "tainted");
}
}
if (g_variant_dict_contains (dict, "Percentage")) {
g_autoptr(GVariant) val = NULL;
val = g_dbus_proxy_get_cached_property (proxy, "Percentage");
@ -203,6 +213,7 @@ fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **e
{
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_autoptr(GVariant) val = NULL;
g_autoptr(GVariant) val2 = NULL;
g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
@ -235,6 +246,9 @@ fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **e
val = g_dbus_proxy_get_cached_property (priv->proxy, "DaemonVersion");
if (val != NULL)
fwupd_client_set_daemon_version (client, g_variant_get_string (val, NULL));
val2 = g_dbus_proxy_get_cached_property (priv->proxy, "Tainted");
if (val2 != NULL)
priv->tainted = g_variant_get_boolean (val2);
return TRUE;
}
@ -1138,6 +1152,24 @@ fwupd_client_get_status (FwupdClient *client)
return priv->status;
}
/**
* fwupd_client_get_tainted:
* @client: A #FwupdClient
*
* Gets if the daemon has been tainted by 3rd party code.
*
* Returns: %TRUE if the daemon is unsupported
*
* Since: 1.2.4
**/
gboolean
fwupd_client_get_tainted (FwupdClient *client)
{
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE);
return priv->tainted;
}
/**
* fwupd_client_update_metadata:
* @client: A #FwupdClient
@ -1461,6 +1493,9 @@ fwupd_client_get_property (GObject *object, guint prop_id,
case PROP_STATUS:
g_value_set_uint (value, priv->status);
break;
case PROP_TAINTED:
g_value_set_boolean (value, priv->tainted);
break;
case PROP_PERCENTAGE:
g_value_set_uint (value, priv->percentage);
break;
@ -1595,9 +1630,20 @@ fwupd_client_class_init (FwupdClientClass *klass)
*/
pspec = g_param_spec_uint ("status", NULL, NULL,
0, FWUPD_STATUS_LAST, FWUPD_STATUS_UNKNOWN,
G_PARAM_READWRITE);
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_STATUS, pspec);
/**
* FwupdClient:tainted:
*
* If the daemon is tainted by 3rd party code.
*
* Since: 1.2.4
*/
pspec = g_param_spec_boolean ("tainted", NULL, NULL, FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_TAINTED, pspec);
/**
* FwupdClient:percentage:
*
@ -1607,7 +1653,7 @@ fwupd_client_class_init (FwupdClientClass *klass)
*/
pspec = g_param_spec_uint ("percentage", NULL, NULL,
0, 100, 0,
G_PARAM_READWRITE);
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_PERCENTAGE, pspec);
/**
@ -1618,7 +1664,7 @@ fwupd_client_class_init (FwupdClientClass *klass)
* Since: 0.9.6
*/
pspec = g_param_spec_string ("daemon-version", NULL, NULL,
NULL, G_PARAM_READABLE);
NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_DAEMON_VERSION, pspec);
}

View File

@ -116,6 +116,7 @@ gboolean fwupd_client_modify_device (FwupdClient *client,
GCancellable *cancellable,
GError **error);
FwupdStatus fwupd_client_get_status (FwupdClient *client);
gboolean fwupd_client_get_tainted (FwupdClient *client);
guint fwupd_client_get_percentage (FwupdClient *client);
const gchar *fwupd_client_get_daemon_version (FwupdClient *client);

View File

@ -45,7 +45,7 @@ fwupd_checksum_guess_kind (const gchar *checksum)
}
static const gchar *
_g_checksum_type_to_string (GChecksumType checksum_type)
fwupd_checksum_type_to_string_display (GChecksumType checksum_type)
{
if (checksum_type == G_CHECKSUM_MD5)
return "MD5";
@ -72,7 +72,9 @@ gchar *
fwupd_checksum_format_for_display (const gchar *checksum)
{
GChecksumType kind = fwupd_checksum_guess_kind (checksum);
return g_strdup_printf ("%s(%s)", _g_checksum_type_to_string (kind), checksum);
return g_strdup_printf ("%s(%s)",
fwupd_checksum_type_to_string_display (kind),
checksum);
}
/**
@ -350,12 +352,27 @@ fwupd_build_history_report_json_device (JsonBuilder *builder, FwupdDevice *dev)
{
FwupdRelease *rel = fwupd_device_get_release_default (dev);
GPtrArray *checksums;
const gchar *tmp;
/* identify the firmware used */
json_builder_set_member_name (builder, "Checksum");
checksums = fwupd_release_get_checksums (rel);
json_builder_add_string_value (builder, fwupd_checksum_get_by_kind (checksums, G_CHECKSUM_SHA1));
/* identify the firmware written */
checksums = fwupd_device_get_checksums (dev);
tmp = fwupd_checksum_get_by_kind (checksums, G_CHECKSUM_SHA1);
if (tmp != NULL) {
json_builder_set_member_name (builder, "ChecksumDevice");
json_builder_add_string_value (builder, tmp);
}
/* include the protocol used */
if (fwupd_release_get_protocol (rel) != NULL) {
json_builder_set_member_name (builder, "Protocol");
json_builder_add_string_value (builder, fwupd_release_get_protocol (rel));
}
/* set the error state of the report */
json_builder_set_member_name (builder, "UpdateState");
json_builder_add_int_value (builder, fwupd_device_get_update_state (dev));
@ -363,6 +380,10 @@ fwupd_build_history_report_json_device (JsonBuilder *builder, FwupdDevice *dev)
json_builder_set_member_name (builder, "UpdateError");
json_builder_add_string_value (builder, fwupd_device_get_update_error (dev));
}
if (fwupd_release_get_update_message (rel) != NULL) {
json_builder_set_member_name (builder, "UpdateMessage");
json_builder_add_string_value (builder, fwupd_release_get_update_message (rel));
}
/* map back to the dev type on the LVFS */
json_builder_set_member_name (builder, "Guid");

View File

@ -51,6 +51,7 @@ typedef struct {
guint32 install_duration;
FwupdUpdateState update_state;
gchar *update_error;
gchar *update_message;
GPtrArray *releases;
FwupdDevice *parent;
} FwupdDevicePrivate;
@ -977,6 +978,8 @@ fwupd_device_incorporate (FwupdDevice *self, FwupdDevice *donor)
fwupd_device_set_plugin (self, priv_donor->plugin);
if (priv->update_error == NULL)
fwupd_device_set_update_error (self, priv_donor->update_error);
if (priv->update_message == NULL)
fwupd_device_set_update_message (self, priv_donor->update_message);
if (priv->version == NULL)
fwupd_device_set_version (self, priv_donor->version);
if (priv->version_lowest == NULL)
@ -1133,6 +1136,11 @@ fwupd_device_to_variant_full (FwupdDevice *device, FwupdDeviceFlags flags)
FWUPD_RESULT_KEY_UPDATE_ERROR,
g_variant_new_string (priv->update_error));
}
if (priv->update_message != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_UPDATE_MESSAGE,
g_variant_new_string (priv->update_message));
}
if (priv->update_state != FWUPD_UPDATE_STATE_UNKNOWN) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_UPDATE_STATE,
@ -1287,6 +1295,10 @@ fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *va
fwupd_device_set_update_error (device, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_MESSAGE) == 0) {
fwupd_device_set_update_message (device, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_STATE) == 0) {
fwupd_device_set_update_state (device, g_variant_get_uint32 (value));
return;
@ -1385,6 +1397,42 @@ fwupd_device_set_update_state (FwupdDevice *device, FwupdUpdateState update_stat
priv->update_state = update_state;
}
/**
* fwupd_device_get_update_message:
* @device: A #FwupdDevice
*
* Gets the update message.
*
* Returns: the update message, or %NULL if unset
*
* Since: 1.2.4
**/
const gchar *
fwupd_device_get_update_message (FwupdDevice *device)
{
FwupdDevicePrivate *priv = GET_PRIVATE (device);
g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
return priv->update_message;
}
/**
* fwupd_device_set_update_message:
* @device: A #FwupdDevice
* @update_message: the update message string
*
* Sets the update message.
*
* Since: 1.2.4
**/
void
fwupd_device_set_update_message (FwupdDevice *device, const gchar *update_message)
{
FwupdDevicePrivate *priv = GET_PRIVATE (device);
g_return_if_fail (FWUPD_IS_DEVICE (device));
g_free (priv->update_message);
priv->update_message = g_strdup (update_message);
}
/**
* fwupd_device_get_update_error:
* @device: A #FwupdDevice
@ -1545,6 +1593,7 @@ fwupd_device_to_string (FwupdDevice *device)
fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_MODIFIED, priv->modified);
fwupd_pad_kv_ups (str, FWUPD_RESULT_KEY_UPDATE_STATE, priv->update_state);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_ERROR, priv->update_error);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_MESSAGE, priv->update_message);
for (guint i = 0; i < priv->releases->len; i++) {
FwupdRelease *release = g_ptr_array_index (priv->releases, i);
g_autofree gchar *tmp = fwupd_release_to_string (release);
@ -1590,6 +1639,7 @@ fwupd_device_finalize (GObject *object)
g_free (priv->vendor_id);
g_free (priv->plugin);
g_free (priv->update_error);
g_free (priv->update_message);
g_free (priv->version);
g_free (priv->version_lowest);
g_free (priv->version_bootloader);

View File

@ -112,6 +112,9 @@ void fwupd_device_set_update_state (FwupdDevice *device,
const gchar *fwupd_device_get_update_error (FwupdDevice *device);
void fwupd_device_set_update_error (FwupdDevice *device,
const gchar *update_error);
const gchar *fwupd_device_get_update_message (FwupdDevice *device);
void fwupd_device_set_update_message (FwupdDevice *device,
const gchar *update_message);
void fwupd_device_add_release (FwupdDevice *device,
FwupdRelease *release);
GPtrArray *fwupd_device_get_releases (FwupdDevice *device);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016-2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2016-2018 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
@ -14,11 +14,14 @@
#define FWUPD_RESULT_KEY_DEVICE_ID "DeviceId" /* s */
#define FWUPD_RESULT_KEY_PARENT_DEVICE_ID "ParentDeviceId"/* s */
#define FWUPD_RESULT_KEY_FILENAME "Filename" /* s */
#define FWUPD_RESULT_KEY_PROTOCOL "Protocol" /* s */
#define FWUPD_RESULT_KEY_FLAGS "Flags" /* t */
#define FWUPD_RESULT_KEY_FLASHES_LEFT "FlashesLeft" /* u */
#define FWUPD_RESULT_KEY_INSTALL_DURATION "InstallDuration" /* u */
#define FWUPD_RESULT_KEY_GUID "Guid" /* as */
#define FWUPD_RESULT_KEY_HOMEPAGE "Homepage" /* s */
#define FWUPD_RESULT_KEY_DETAILS_URL "DetailsUrl" /* s */
#define FWUPD_RESULT_KEY_SOURCE_URL "SourceUrl" /* s */
#define FWUPD_RESULT_KEY_ICON "Icon" /* as */
#define FWUPD_RESULT_KEY_LICENSE "License" /* s */
#define FWUPD_RESULT_KEY_MODIFIED "Modified" /* t */
@ -31,6 +34,7 @@
#define FWUPD_RESULT_KEY_SIZE "Size" /* t */
#define FWUPD_RESULT_KEY_SUMMARY "Summary" /* s */
#define FWUPD_RESULT_KEY_TRUST_FLAGS "TrustFlags" /* t */
#define FWUPD_RESULT_KEY_UPDATE_MESSAGE "UpdateMessage" /* s */
#define FWUPD_RESULT_KEY_UPDATE_ERROR "UpdateError" /* s */
#define FWUPD_RESULT_KEY_UPDATE_STATE "UpdateState" /* u */
#define FWUPD_RESULT_KEY_URI "Uri" /* s */

View File

@ -57,6 +57,8 @@ fwupd_status_to_string (FwupdStatus status)
return "downloading";
if (status == FWUPD_STATUS_WAITING_FOR_AUTH)
return "waiting-for-auth";
if (status == FWUPD_STATUS_SHUTDOWN)
return "shutdown";
return NULL;
}
@ -99,6 +101,8 @@ fwupd_status_from_string (const gchar *status)
return FWUPD_STATUS_DEVICE_BUSY;
if (g_strcmp0 (status, "waiting-for-auth") == 0)
return FWUPD_STATUS_WAITING_FOR_AUTH;
if (g_strcmp0 (status, "shutdown") == 0)
return FWUPD_STATUS_SHUTDOWN;
return FWUPD_STATUS_LAST;
}
@ -135,6 +139,8 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag)
return "registered";
if (device_flag == FWUPD_DEVICE_FLAG_NEEDS_REBOOT)
return "needs-reboot";
if (device_flag == FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN)
return "needs-shutdown";
if (device_flag == FWUPD_DEVICE_FLAG_REPORTED)
return "reported";
if (device_flag == FWUPD_DEVICE_FLAG_NOTIFIED)
@ -189,6 +195,8 @@ fwupd_device_flag_from_string (const gchar *device_flag)
return FWUPD_DEVICE_FLAG_REGISTERED;
if (g_strcmp0 (device_flag, "needs-reboot") == 0)
return FWUPD_DEVICE_FLAG_NEEDS_REBOOT;
if (g_strcmp0 (device_flag, "needs-shutdown") == 0)
return FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN;
if (g_strcmp0 (device_flag, "reported") == 0)
return FWUPD_DEVICE_FLAG_REPORTED;
if (g_strcmp0 (device_flag, "notified") == 0)

View File

@ -24,6 +24,7 @@
* @FWUPD_STATUS_DEVICE_ERASE: Erasing a device
* @FWUPD_STATUS_WAITING_FOR_AUTH: Waiting for authentication
* @FWUPD_STATUS_DEVICE_BUSY: The device is busy
* @FWUPD_STATUS_SHUTDOWN: The daemon is shutting down
*
* The flags to show daemon status.
**/
@ -41,6 +42,7 @@ typedef enum {
FWUPD_STATUS_DEVICE_ERASE, /* Since: 1.0.0 */
FWUPD_STATUS_WAITING_FOR_AUTH, /* Since: 1.0.0 */
FWUPD_STATUS_DEVICE_BUSY, /* Since: 1.0.1 */
FWUPD_STATUS_SHUTDOWN, /* Since: 1.2.1 */
/*< private >*/
FWUPD_STATUS_LAST
} FwupdStatus;
@ -81,6 +83,7 @@ typedef enum {
* @FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG: The hardware is waiting to be replugged
* @FWUPD_DEVICE_FLAG_IGNORE_VALIDATION: Ignore validation safety checks when flashing this device
* @FWUPD_DEVICE_FLAG_TRUSTED: Extra metadata can be exposed about this device
* @FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN: Requires system shutdown to apply firmware
*
* The device flags.
**/
@ -102,6 +105,7 @@ typedef enum {
#define FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG (1u << 14) /* Since: 1.1.2 */
#define FWUPD_DEVICE_FLAG_IGNORE_VALIDATION (1u << 15) /* Since: 1.1.2 */
#define FWUPD_DEVICE_FLAG_TRUSTED (1u << 16) /* Since: 1.1.2 */
#define FWUPD_DEVICE_FLAG_NEEDS_SHUTDOWN (1u << 17) /* Since: 1.2.4 */
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
typedef guint64 FwupdDeviceFlags;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2015-2018 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
@ -33,7 +33,10 @@ typedef struct {
GHashTable *metadata;
gchar *description;
gchar *filename;
gchar *protocol;
gchar *homepage;
gchar *details_url;
gchar *source_url;
gchar *appstream_id;
gchar *license;
gchar *name;
@ -43,7 +46,9 @@ typedef struct {
gchar *version;
gchar *remote_id;
guint64 size;
guint32 install_duration;
FwupdTrustFlags trust_flags;
gchar *update_message;
} FwupdReleasePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (FwupdRelease, fwupd_release, G_TYPE_OBJECT)
@ -157,6 +162,78 @@ fwupd_release_set_filename (FwupdRelease *release, const gchar *filename)
priv->filename = g_strdup (filename);
}
/**
* fwupd_release_get_update_message:
* @release: A #FwupdRelease
*
* Gets the update message.
*
* Returns: the update message, or %NULL if unset
*
* Since: 1.2.4
**/
const gchar *
fwupd_release_get_update_message (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
return priv->update_message;
}
/**
* fwupd_release_set_update_message:
* @release: A #FwupdRelease
* @update_message: the update message string
*
* Sets the update message.
*
* Since: 1.2.4
**/
void
fwupd_release_set_update_message (FwupdRelease *release, const gchar *update_message)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
g_free (priv->update_message);
priv->update_message = g_strdup (update_message);
}
/**
* fwupd_release_get_protocol:
* @release: A #FwupdRelease
*
* Gets the update protocol.
*
* Returns: the update protocol, or %NULL if unset
*
* Since: 1.2.2
**/
const gchar *
fwupd_release_get_protocol (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
return priv->protocol;
}
/**
* fwupd_release_set_protocol:
* @release: A #FwupdRelease
* @protocol: the update protocol, e.g. `org.usb.dfu`
*
* Sets the update protocol.
*
* Since: 1.2.2
**/
void
fwupd_release_set_protocol (FwupdRelease *release, const gchar *protocol)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
g_free (priv->protocol);
priv->protocol = g_strdup (protocol);
}
/**
* fwupd_release_get_checksums:
* @release: A #FwupdRelease
@ -355,6 +432,78 @@ fwupd_release_set_homepage (FwupdRelease *release, const gchar *homepage)
priv->homepage = g_strdup (homepage);
}
/**
* fwupd_release_get_details_url:
* @release: A #FwupdRelease
*
* Gets the URL for the online update notes.
*
* Returns: the update URL, or %NULL if unset
*
* Since: 1.2.4
**/
const gchar *
fwupd_release_get_details_url (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
return priv->details_url;
}
/**
* fwupd_release_set_details_url:
* @release: A #FwupdRelease
* @details_url: the URL
*
* Sets the URL for the online update notes.
*
* Since: 1.2.4
**/
void
fwupd_release_set_details_url (FwupdRelease *release, const gchar *details_url)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
g_free (priv->details_url);
priv->details_url = g_strdup (details_url);
}
/**
* fwupd_release_get_source_url:
* @release: A #FwupdRelease
*
* Gets the URL of the source code used to build this release.
*
* Returns: the update source_url, or %NULL if unset
*
* Since: 1.2.4
**/
const gchar *
fwupd_release_get_source_url (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
return priv->source_url;
}
/**
* fwupd_release_set_source_url:
* @release: A #FwupdRelease
* @source_url: the URL
*
* Sets the URL of the source code used to build this release.
*
* Since: 1.2.4
**/
void
fwupd_release_set_source_url (FwupdRelease *release, const gchar *source_url)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
g_free (priv->source_url);
priv->source_url = g_strdup (source_url);
}
/**
* fwupd_release_get_description:
* @release: A #FwupdRelease
@ -641,6 +790,41 @@ fwupd_release_set_trust_flags (FwupdRelease *release, FwupdTrustFlags trust_flag
priv->trust_flags = trust_flags;
}
/**
* fwupd_release_get_install_duration:
* @release: A #FwupdRelease
*
* Gets the time estimate for firmware installation (in seconds)
*
* Returns: the estimated time to flash this release (or 0 if unset)
*
* Since: 1.2.1
**/
guint32
fwupd_release_get_install_duration (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), 0);
return priv->install_duration;
}
/**
* fwupd_release_set_install_duration:
* @release: A #FwupdRelease
* @duration: The amount of time
*
* Sets the time estimate for firmware installation (in seconds)
*
* Since: 1.2.1
**/
void
fwupd_release_set_install_duration (FwupdRelease *release, guint32 duration)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
priv->install_duration = duration;
}
static GVariant *
_hash_kv_to_variant (GHashTable *hash)
{
@ -703,6 +887,11 @@ fwupd_release_to_variant (FwupdRelease *release)
FWUPD_RESULT_KEY_FILENAME,
g_variant_new_string (priv->filename));
}
if (priv->protocol != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_PROTOCOL,
g_variant_new_string (priv->protocol));
}
if (priv->license != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_LICENSE,
@ -750,6 +939,16 @@ fwupd_release_to_variant (FwupdRelease *release)
FWUPD_RESULT_KEY_HOMEPAGE,
g_variant_new_string (priv->homepage));
}
if (priv->details_url != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_DETAILS_URL,
g_variant_new_string (priv->details_url));
}
if (priv->source_url != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_SOURCE_URL,
g_variant_new_string (priv->source_url));
}
if (priv->version != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_VERSION,
@ -770,6 +969,11 @@ fwupd_release_to_variant (FwupdRelease *release)
FWUPD_RESULT_KEY_METADATA,
_hash_kv_to_variant (priv->metadata));
}
if (priv->install_duration > 0) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_INSTALL_DURATION,
g_variant_new_uint32 (priv->install_duration));
}
return g_variant_new ("a{sv}", &builder);
}
@ -789,6 +993,10 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
fwupd_release_set_filename (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_PROTOCOL) == 0) {
fwupd_release_set_protocol (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_LICENSE) == 0) {
fwupd_release_set_license (release, g_variant_get_string (value, NULL));
return;
@ -824,6 +1032,14 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
fwupd_release_set_homepage (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DETAILS_URL) == 0) {
fwupd_release_set_details_url (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_SOURCE_URL) == 0) {
fwupd_release_set_source_url (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION) == 0) {
fwupd_release_set_version (release, g_variant_get_string (value, NULL));
return;
@ -836,6 +1052,14 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
fwupd_release_set_trust_flags (release, g_variant_get_uint64 (value));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_INSTALL_DURATION) == 0) {
fwupd_release_set_install_duration (release, g_variant_get_uint32 (value));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_MESSAGE) == 0) {
fwupd_release_set_update_message (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_METADATA) == 0) {
g_hash_table_unref (priv->metadata);
priv->metadata = _variant_to_hash_kv (value);
@ -885,6 +1109,18 @@ fwupd_pad_kv_tfl (GString *str, const gchar *key, FwupdTrustFlags trust_flags)
fwupd_pad_kv_str (str, key, tmp->str);
}
static void
fwupd_pad_kv_int (GString *str, const gchar *key, guint32 value)
{
g_autofree gchar *tmp = NULL;
/* ignore */
if (value == 0)
return;
tmp = g_strdup_printf("%" G_GUINT32_FORMAT, value);
fwupd_pad_kv_str (str, key, tmp);
}
/**
* fwupd_release_to_string:
* @release: A #FwupdRelease
@ -911,6 +1147,7 @@ fwupd_release_to_string (FwupdRelease *release)
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION, priv->version);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_FILENAME, priv->filename);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PROTOCOL, priv->protocol);
for (guint i = 0; i < priv->checksums->len; i++) {
const gchar *checksum = g_ptr_array_index (priv->checksums, i);
g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum);
@ -920,9 +1157,13 @@ fwupd_release_to_string (FwupdRelease *release)
fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_SIZE, priv->size);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_URI, priv->uri);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_HOMEPAGE, priv->homepage);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DETAILS_URL, priv->details_url);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SOURCE_URL, priv->source_url);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR, priv->vendor);
fwupd_pad_kv_tfl (str, FWUPD_RESULT_KEY_TRUST_FLAGS, priv->trust_flags);
fwupd_pad_kv_int (str, FWUPD_RESULT_KEY_INSTALL_DURATION, priv->install_duration);
if (priv->update_message != NULL)
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_MESSAGE, priv->update_message);
/* metadata */
keys = g_hash_table_get_keys (priv->metadata);
for (GList *l = keys; l != NULL; l = l->next) {
@ -957,15 +1198,19 @@ fwupd_release_finalize (GObject *object)
g_free (priv->description);
g_free (priv->filename);
g_free (priv->protocol);
g_free (priv->appstream_id);
g_free (priv->license);
g_free (priv->name);
g_free (priv->summary);
g_free (priv->uri);
g_free (priv->homepage);
g_free (priv->details_url);
g_free (priv->source_url);
g_free (priv->vendor);
g_free (priv->version);
g_free (priv->remote_id);
g_free (priv->update_message);
g_ptr_array_unref (priv->checksums);
g_hash_table_unref (priv->metadata);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2015-2018 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
@ -54,6 +54,9 @@ const gchar *fwupd_release_get_metadata_item (FwupdRelease *release,
const gchar *fwupd_release_get_filename (FwupdRelease *release);
void fwupd_release_set_filename (FwupdRelease *release,
const gchar *filename);
const gchar *fwupd_release_get_protocol (FwupdRelease *release);
void fwupd_release_set_protocol (FwupdRelease *release,
const gchar *protocol);
const gchar *fwupd_release_get_appstream_id (FwupdRelease *release);
void fwupd_release_set_appstream_id (FwupdRelease *release,
const gchar *appstream_id);
@ -75,6 +78,12 @@ void fwupd_release_set_description (FwupdRelease *release,
const gchar *fwupd_release_get_homepage (FwupdRelease *release);
void fwupd_release_set_homepage (FwupdRelease *release,
const gchar *homepage);
const gchar *fwupd_release_get_details_url (FwupdRelease *release);
void fwupd_release_set_details_url (FwupdRelease *release,
const gchar *details_url);
const gchar *fwupd_release_get_source_url (FwupdRelease *release);
void fwupd_release_set_source_url (FwupdRelease *release,
const gchar *source_url);
guint64 fwupd_release_get_size (FwupdRelease *release);
void fwupd_release_set_size (FwupdRelease *release,
guint64 size);
@ -84,6 +93,12 @@ void fwupd_release_set_license (FwupdRelease *release,
FwupdTrustFlags fwupd_release_get_trust_flags (FwupdRelease *release);
void fwupd_release_set_trust_flags (FwupdRelease *release,
FwupdTrustFlags trust_flags);
guint32 fwupd_release_get_install_duration (FwupdRelease *release);
void fwupd_release_set_install_duration (FwupdRelease *release,
guint32 duration);
const gchar *fwupd_release_get_update_message (FwupdRelease *release);
void fwupd_release_set_update_message (FwupdRelease *release,
const gchar *update_message);
G_END_DECLS

View File

@ -275,6 +275,8 @@ fwupd_remote_kind_from_string (const gchar *kind)
return FWUPD_REMOTE_KIND_DOWNLOAD;
if (g_strcmp0 (kind, "local") == 0)
return FWUPD_REMOTE_KIND_LOCAL;
if (g_strcmp0 (kind, "directory") == 0)
return FWUPD_REMOTE_KIND_DIRECTORY;
return FWUPD_REMOTE_KIND_UNKNOWN;
}
@ -295,6 +297,8 @@ fwupd_remote_kind_to_string (FwupdRemoteKind kind)
return "download";
if (kind == FWUPD_REMOTE_KIND_LOCAL)
return "local";
if (kind == FWUPD_REMOTE_KIND_DIRECTORY)
return "directory";
return NULL;
}
@ -384,6 +388,13 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
if (metadata_uri == NULL)
return FALSE;
if (g_str_has_prefix (metadata_uri, "file://")) {
const gchar *filename_cache = metadata_uri;
if (g_str_has_prefix (filename_cache, "file://"))
filename_cache += 7;
fwupd_remote_set_filename_cache (self, filename_cache);
if (g_file_test (filename_cache, G_FILE_TEST_IS_DIR))
priv->kind = FWUPD_REMOTE_KIND_DIRECTORY;
else
priv->kind = FWUPD_REMOTE_KIND_LOCAL;
} else if (g_str_has_prefix (metadata_uri, "http://") ||
g_str_has_prefix (metadata_uri, "https://")) {
@ -444,14 +455,6 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
fwupd_remote_set_filename_cache (self, filename_cache);
}
/* all LOCAL remotes have to include a valid MetadataURI */
if (priv->kind == FWUPD_REMOTE_KIND_LOCAL) {
const gchar *filename_cache = metadata_uri;
if (g_str_has_prefix (filename_cache, "file://"))
filename_cache += 7;
fwupd_remote_set_filename_cache (self, filename_cache);
}
/* load the checksum */
if (priv->filename_cache_sig != NULL &&
g_file_test (priv->filename_cache_sig, G_FILE_TEST_EXISTS)) {
@ -473,6 +476,25 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
if (firmware_base_uri != NULL)
fwupd_remote_set_firmware_base_uri (self, firmware_base_uri);
/* some validation around DIRECTORY types */
if (priv->kind == FWUPD_REMOTE_KIND_DIRECTORY) {
if (priv->keyring_kind != FWUPD_KEYRING_KIND_NONE) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"Keyring kind %s is not supported with directory remote",
fwupd_keyring_kind_to_string (priv->keyring_kind));
return FALSE;
}
if (firmware_base_uri != NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"Directory remotes don't support firmware base URI");
return FALSE;
}
}
/* dep logic */
order_before = g_key_file_get_string (kf, group, "OrderBefore", NULL);
if (order_before != NULL)
@ -1099,7 +1121,7 @@ fwupd_remote_class_init (FwupdRemoteClass *klass)
* Since: 0.9.3
*/
pspec = g_param_spec_string ("id", NULL, NULL,
NULL, G_PARAM_READWRITE);
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_ID, pspec);
/**
@ -1110,7 +1132,7 @@ fwupd_remote_class_init (FwupdRemoteClass *klass)
* Since: 0.9.3
*/
pspec = g_param_spec_boolean ("enabled", NULL, NULL,
FALSE, G_PARAM_READWRITE);
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_ENABLED, pspec);
}

View File

@ -39,6 +39,7 @@ typedef enum {
FWUPD_REMOTE_KIND_UNKNOWN,
FWUPD_REMOTE_KIND_DOWNLOAD,
FWUPD_REMOTE_KIND_LOCAL,
FWUPD_REMOTE_KIND_DIRECTORY, /* Since: 1.2.4 */
/*< private >*/
FWUPD_REMOTE_KIND_LAST
} FwupdRemoteKind;

View File

@ -279,3 +279,31 @@ LIBFWUPD_1.1.3 {
fwupd_device_set_install_duration;
local: *;
} LIBFWUPD_1.1.2;
LIBFWUPD_1.2.1 {
global:
fwupd_release_get_install_duration;
fwupd_release_set_install_duration;
local: *;
} LIBFWUPD_1.1.3;
LIBFWUPD_1.2.2 {
global:
fwupd_release_get_protocol;
fwupd_release_set_protocol;
local: *;
} LIBFWUPD_1.2.1;
LIBFWUPD_1.2.4 {
global:
fwupd_client_get_tainted;
fwupd_device_get_update_message;
fwupd_device_set_update_message;
fwupd_release_get_details_url;
fwupd_release_get_source_url;
fwupd_release_get_update_message;
fwupd_release_set_details_url;
fwupd_release_set_source_url;
fwupd_release_set_update_message;
local: *;
} LIBFWUPD_1.2.2;

View File

@ -1,7 +1,7 @@
project('fwupd', 'c',
version : '1.1.4',
version : '1.2.4',
license : 'LGPL-2.1+',
meson_version : '>=0.43.0',
meson_version : '>=0.47.0',
default_options : ['warning_level=2', 'c_std=c99'],
)
@ -111,18 +111,13 @@ add_project_arguments(cc.get_supported_arguments(warning_flags), language : 'c')
global_link_args = []
test_link_args = [
'-Wl,-z,relro',
'-Wl,-z,defs',
'-Wl,-z,now',
]
foreach arg: test_link_args
if meson.version().version_compare('>=0.46.0')
if cc.has_link_argument(arg)
global_link_args += arg
endif
else
if cc.has_argument(arg)
global_link_args += arg
endif
endif
endforeach
add_global_link_arguments(
global_link_args,
@ -160,7 +155,7 @@ gudev = dependency('gudev-1.0')
if gudev.version().version_compare('>= 232')
conf.set('HAVE_GUDEV_232', '1')
endif
appstream_glib = dependency('appstream-glib', version : '>= 0.7.4')
libxmlb = dependency('xmlb', version : '>= 0.1.5', fallback : ['libxmlb', 'libxmlb_dep'])
gusb = dependency('gusb', version : '>= 0.2.9')
sqlite = dependency('sqlite3')
libarchive = dependency('libarchive')
@ -198,6 +193,7 @@ if libgcab.version().version_compare('>= 1.0')
endif
gcab = find_program('gcab', required : true)
bashcomp = dependency('bash-completion', required: false)
python3 = find_program('python3')
if valgrind.found()
conf.set('HAVE_VALGRIND', '1')
@ -242,8 +238,6 @@ if get_option('plugin_uefi')
gnu_efi_arch = ''
endif
conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
python3 = find_program('python3')
r = run_command([python3, 'po/test-deps'])
if r.returncode() != 0
error(r.stdout())
@ -310,14 +304,8 @@ configure_file(
configuration : conf
)
default_sysconfdir = get_option('sysconfdir')
if default_sysconfdir == 'etc'
message('sysconfdir of etc makes no sense, using /etc')
default_sysconfdir = '/etc'
endif
plugin_deps = []
plugin_deps += appstream_glib
plugin_deps += libxmlb
plugin_deps += gio
plugin_deps += giounix
plugin_deps += gmodule

View File

@ -11,6 +11,9 @@ If you have a firmware specification and would like to see support
in this project, please file an issue and share the spec. Patches are also
welcome.
We will not accept plugins that upgrade hardware using a proprietary Linux
executable, library, or DBus interface.
Plugin interaction
------------------
Some plugins may be able to influence the behavior of other plugins.

View File

@ -15,6 +15,25 @@ The bootloader communication is not handled in the kernel, and a tty device is
created so userspace can communicate with the hardware. Commands the bootloader
accept are as follows:
Firmware Format
---------------
The daemon will decompress the cabinet archive and extract a firmware blob in
ELF file format. The firmware image is inserted into the `.text` section.
This plugin supports the following protocol ID:
* org.altusmetrum.altos
GUID Generation
---------------
These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_1D50&PID_60C6&REV_0001`
* `USB\VID_1D50&PID_60C6`
* `USB\VID_1D50`
### List Information
Command: `l\n`

View File

@ -12,6 +12,7 @@
#include <termios.h>
#include <errno.h>
#include "fu-io-channel.h"
#include "fu-altos-device.h"
#include "fu-altos-firmware.h"
@ -25,7 +26,7 @@ struct _FuAltosDevice {
guint64 addr_base;
guint64 addr_bound;
struct termios tty_termios;
gint tty_fd;
FuIOChannel *io_channel;
};
G_DEFINE_TYPE (FuAltosDevice, fu_altos_device, FU_TYPE_USB_DEVICE)
@ -149,60 +150,15 @@ fu_altos_device_tty_write (FuAltosDevice *self,
gssize data_len,
GError **error)
{
gint rc;
gssize idx = 0;
guint timeout_ms = 500;
struct pollfd fds;
/* lets assume this is text */
if (data_len < 0)
data_len = strlen (data);
fds.fd = self->tty_fd;
fds.events = POLLOUT;
g_debug ("write, with timeout %ums", timeout_ms);
while (idx < data_len) {
/* wait for data to be allowed to write without blocking */
rc = poll (&fds, 1, (gint) timeout_ms);
if (rc == 0)
break;
if (rc < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"failed to poll %i",
self->tty_fd);
return FALSE;
}
/* we can write data */
if (fds.revents & POLLOUT) {
gssize len;
g_debug ("writing %" G_GSSIZE_FORMAT " bytes: %s", data_len, data);
len = write (self->tty_fd, data + idx, data_len - idx);
if (len < 0) {
if (errno == EAGAIN) {
g_debug ("got EAGAIN, trying harder");
continue;
}
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_WRITE,
"failed to write %" G_GSSIZE_FORMAT
" bytes to %i: %s" ,
data_len,
self->tty_fd,
strerror (errno));
return FALSE;
}
g_debug ("wrote %" G_GSSIZE_FORMAT " bytes", len);
idx += len;
}
}
return TRUE;
return fu_io_channel_write_raw (self->io_channel,
(const guint8 *) data,
(gsize) data_len,
500, /* ms */
FU_IO_CHANNEL_FLAG_NONE,
error);
}
static GString *
@ -211,90 +167,12 @@ fu_altos_device_tty_read (FuAltosDevice *self,
gssize max_size,
GError **error)
{
gint rc;
struct pollfd fds;
g_autoptr(GString) str = g_string_new (NULL);
fds.fd = self->tty_fd;
fds.events = POLLIN;
g_debug ("read, with timeout %ums", timeout_ms);
for (;;) {
/* wait for data to appear */
rc = poll (&fds, 1, (gint) timeout_ms);
if (rc == 0)
break;
if (rc < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"failed to poll %i",
self->tty_fd);
g_autoptr(GBytes) buf = NULL;
buf = fu_io_channel_read_bytes (self->io_channel, max_size,
timeout_ms, FU_IO_CHANNEL_FLAG_NONE, error);
if (buf == NULL)
return NULL;
}
/* we have data to read */
if (fds.revents & POLLIN) {
guint8 buf[1024];
gssize len = read (self->tty_fd, buf, sizeof (buf));
if (len < 0) {
if (errno == EAGAIN) {
g_debug ("got EAGAIN, trying harder");
continue;
}
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"failed to read %i: %s",
self->tty_fd,
strerror (errno));
return NULL;
}
if (len > 0) {
g_debug ("read %" G_GSSIZE_FORMAT " bytes from device", len);
g_string_append_len (str, (gchar *) buf, len);
}
/* check maximum size */
if (max_size > 0 && str->len >= (guint) max_size)
break;
continue;
}
if (fds.revents & POLLERR) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"error condition");
return NULL;
}
if (fds.revents & POLLHUP) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"connection hung up");
return NULL;
}
if (fds.revents & POLLNVAL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"invalid request");
return NULL;
}
}
/* no data */
if (str->len == 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"no data received from device in %ums",
timeout_ms);
return NULL;
}
/* return blob */
return g_steal_pointer (&str);
return g_string_new_len (g_bytes_get_data (buf, NULL), g_bytes_get_size (buf));
}
static gboolean
@ -304,18 +182,12 @@ fu_altos_device_tty_open (FuAltosDevice *self, GError **error)
g_autoptr(GString) str = NULL;
/* open device */
self->tty_fd = open (self->tty, O_RDWR | O_NONBLOCK);
if (self->tty_fd < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to open %s",
self->tty);
self->io_channel = fu_io_channel_new_file (self->tty, error);
if (self->io_channel == NULL)
return FALSE;
}
/* get the old termios settings so we can restore later */
if (tcgetattr (self->tty_fd, &termios) < 0) {
if (tcgetattr (fu_io_channel_unix_get_fd (self->io_channel), &termios) < 0) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
@ -340,7 +212,8 @@ fu_altos_device_tty_open (FuAltosDevice *self, GError **error)
termios.c_cc[VTIME] = 0;
/* set all new data */
if (tcsetattr (self->tty_fd, TCSAFLUSH, &termios) < 0) {
if (tcsetattr (fu_io_channel_unix_get_fd (self->io_channel),
TCSAFLUSH, &termios) < 0) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
@ -359,10 +232,11 @@ fu_altos_device_tty_open (FuAltosDevice *self, GError **error)
static gboolean
fu_altos_device_tty_close (FuAltosDevice *self, GError **error)
{
tcsetattr (self->tty_fd, TCSAFLUSH, &self->tty_termios);
close (self->tty_fd);
tcsetattr (fu_io_channel_unix_get_fd (self->io_channel),
TCSAFLUSH, &self->tty_termios);
if (!fu_io_channel_shutdown (self->io_channel, error))
return FALSE;
g_clear_object (&self->io_channel);
return TRUE;
}

View File

@ -13,7 +13,9 @@
void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_REQUIRES_QUIRK, FU_QUIRKS_PLUGIN);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_SUPPORTS_PROTOCOL, "org.altusmetrum.altos");
}
gboolean

View File

@ -5,6 +5,7 @@ install_data(['altos.quirk'],
)
shared_module('fu_plugin_altos',
fu_hash,
sources : [
'fu-altos-device.c',
'fu-altos-firmware.c',
@ -17,6 +18,9 @@ shared_module('fu_plugin_altos',
],
install : true,
install_dir: plugin_dir,
link_with : [
libfwupdprivate,
],
c_args : cargs,
dependencies : [
libelf,

View File

@ -15,3 +15,8 @@ which can be found here: https://github.com/mjg59/mei-amt-check
That tool in turn is heavily based on mei-amt-version from samples/mei in the
Linux source tree and copyright Intel Corporation.
GUID Generation
---------------
These devices use the existing GUID provided by the AMT host interface.

View File

@ -86,13 +86,11 @@ mei_context_new (mei_context *ctx,
return TRUE;
}
static gssize
static gboolean
mei_recv_msg (mei_context *ctx, guchar *buffer,
gssize len, unsigned long timeout, GError **error)
gssize len, guint32 *readsz, unsigned long timeout, GError **error)
{
gssize rc;
g_debug ("call read length = %zd", len);
rc = read (ctx->fd, buffer, len);
if (rc < 0) {
g_set_error (error,
@ -100,13 +98,14 @@ mei_recv_msg (mei_context *ctx, guchar *buffer,
FWUPD_ERROR_READ,
"read failed with status %zd %s",
rc, strerror(errno));
} else {
g_debug ("read succeeded with result %zd", rc);
return FALSE;
}
return rc;
if (readsz != NULL)
*readsz = rc;
return TRUE;
}
static gssize
static gboolean
mei_send_msg (mei_context *ctx, const guchar *buffer,
gssize len, unsigned long timeout, GError **error)
{
@ -118,7 +117,6 @@ mei_send_msg (mei_context *ctx, const guchar *buffer,
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000000;
g_debug ("call write length = %zd", len);
written = write (ctx->fd, buffer, len);
if (written < 0) {
g_set_error (error,
@ -126,16 +124,22 @@ mei_send_msg (mei_context *ctx, const guchar *buffer,
FWUPD_ERROR_WRITE,
"write failed with status %zd %s",
written, strerror(errno));
return -errno;
return FALSE;
}
if (written != len) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_WRITE,
"only wrote %" G_GSSIZE_FORMAT " of %" G_GSSIZE_FORMAT,
written, len);
return FALSE;
}
FD_ZERO(&set);
FD_SET(ctx->fd, &set);
rc = select (ctx->fd + 1 , &set, NULL, NULL, &tv);
if (rc > 0 && FD_ISSET(ctx->fd, &set)) {
g_debug ("write success");
return written;
}
if (rc > 0 && FD_ISSET(ctx->fd, &set))
return TRUE;
/* timed out */
if (rc == 0) {
@ -143,7 +147,7 @@ mei_send_msg (mei_context *ctx, const guchar *buffer,
FWUPD_ERROR,
FWUPD_ERROR_WRITE,
"write failed on timeout with status");
return 0;
return FALSE;
}
/* rc < 0 */
@ -151,7 +155,7 @@ mei_send_msg (mei_context *ctx, const guchar *buffer,
FWUPD_ERROR,
FWUPD_ERROR_WRITE,
"write failed on select with status %zd", rc);
return rc;
return FALSE;
}
/***************************************************************************
@ -254,50 +258,91 @@ struct amt_host_if {
mei_context mei_cl;
};
static guint32
amt_verify_code_versions (const struct amt_host_if_resp_header *resp)
static gboolean
amt_verify_code_versions (const struct amt_host_if_resp_header *resp, GError **error)
{
struct amt_code_versions *code_ver = (struct amt_code_versions *)resp->data;
gsize code_ver_len = resp->header.length - sizeof(guint32);
guint32 ver_type_cnt = code_ver_len -
sizeof(code_ver->bios) -
sizeof(code_ver->count);
if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type))
return AMT_STATUS_INTERNAL_ERROR;
if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"invalid offset");
return FALSE;
}
for (guint32 i = 0; i < code_ver->count; i++) {
guint32 len = code_ver->versions[i].description.length;
if (len > AMT_UNICODE_STRING_LEN)
return AMT_STATUS_INTERNAL_ERROR;
if (len > AMT_UNICODE_STRING_LEN) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"string too large");
return FALSE;
}
len = code_ver->versions[i].version.length;
if (code_ver->versions[i].version.string[len] != '\0' ||
len != strlen(code_ver->versions[i].version.string))
return AMT_STATUS_INTERNAL_ERROR;
len != strlen(code_ver->versions[i].version.string)) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"string was invalid size");
return FALSE;
}
return AMT_STATUS_SUCCESS;
}
return TRUE;
}
static guint32
amt_verify_response_header (guint32 command,
const struct amt_host_if_msg_header *resp_hdr,
guint32 response_size)
static gboolean
amt_status_set_error (guint32 status, GError **error)
{
if (response_size < sizeof(struct amt_host_if_resp_header)) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (response_size != (resp_hdr->length +
sizeof(struct amt_host_if_msg_header))) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (resp_hdr->command != command) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (resp_hdr->_reserved != 0) {
return AMT_STATUS_INTERNAL_ERROR;
} else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
resp_hdr->version.minor < AMT_MINOR_VERSION) {
return AMT_STATUS_INTERNAL_ERROR;
if (status == AMT_STATUS_SUCCESS)
return TRUE;
if (status == AMT_STATUS_INTERNAL_ERROR) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"internal error");
return FALSE;
}
return AMT_STATUS_SUCCESS;
if (status == AMT_STATUS_NOT_READY) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"not ready");
return FALSE;
}
if (status == AMT_STATUS_INVALID_AMT_MODE) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"invalid AMT mode");
return FALSE;
}
if (status == AMT_STATUS_INVALID_MESSAGE_LENGTH) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"invalid message length");
return FALSE;
}
if (status == AMT_STATUS_HOST_IF_EMPTY_RESPONSE) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"Intel AMT is disabled");
return FALSE;
}
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"unknown error");
return FALSE;
}
static guint32
static gboolean
amt_host_if_call (mei_context *mei_cl,
const guchar *command,
gssize command_sz,
@ -309,53 +354,86 @@ amt_host_if_call (mei_context *mei_cl,
{
guint32 in_buf_sz;
guint32 out_buf_sz;
gssize written;
guint32 status;
struct amt_host_if_resp_header *msg_hdr;
in_buf_sz = mei_cl->buf_size;
*read_buf = (guint8 *) g_malloc0 (in_buf_sz);
msg_hdr = (struct amt_host_if_resp_header *) *read_buf;
written = mei_send_msg (mei_cl, command, command_sz, send_timeout, error);
if (written != command_sz)
return AMT_STATUS_INTERNAL_ERROR;
out_buf_sz = mei_recv_msg (mei_cl, *read_buf, in_buf_sz, 2000, error);
if (out_buf_sz <= 0)
return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
status = msg_hdr->status;
if (status != AMT_STATUS_SUCCESS)
return status;
status = amt_verify_response_header(rcmd, &msg_hdr->header, out_buf_sz);
if (status != AMT_STATUS_SUCCESS)
return status;
if (expected_sz && expected_sz != out_buf_sz)
return AMT_STATUS_INTERNAL_ERROR;
return AMT_STATUS_SUCCESS;
if (!mei_send_msg (mei_cl, command, command_sz, send_timeout, error))
return FALSE;
if (!mei_recv_msg (mei_cl, *read_buf, in_buf_sz, &out_buf_sz, 2000, error))
return FALSE;
if (out_buf_sz <= 0) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"empty response");
return FALSE;
}
if (expected_sz && expected_sz != out_buf_sz) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_WRITE,
"expected %u but got %" G_GUINT32_FORMAT,
expected_sz, out_buf_sz);
return FALSE;
}
if (!amt_status_set_error (msg_hdr->status, error))
return FALSE;
if (out_buf_sz < sizeof(struct amt_host_if_resp_header)) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"invalid response: too small");
return FALSE;
}
if (out_buf_sz != (msg_hdr->header.length +
sizeof(struct amt_host_if_msg_header))) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"invalid response: headerlen");
return FALSE;
}
if (msg_hdr->header.command != rcmd) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"invalid response: rcmd");
return FALSE;
}
if (msg_hdr->header._reserved != 0) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"invalid response: reserved");
return FALSE;
}
if (msg_hdr->header.version.major != AMT_MAJOR_VERSION ||
msg_hdr->header.version.minor < AMT_MINOR_VERSION) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"invalid response: version");
return FALSE;
}
return TRUE;
}
static guint32
static gboolean
amt_get_provisioning_state (mei_context *mei_cl, guint8 *state, GError **error)
{
g_autofree struct amt_host_if_resp_header *response = NULL;
guint32 status;
status = amt_host_if_call (mei_cl,
if (!amt_host_if_call (mei_cl,
(const guchar *)&PROVISIONING_STATE_REQUEST,
sizeof(PROVISIONING_STATE_REQUEST),
(guint8 **)&response,
AMT_HOST_IF_PROVISIONING_STATE_RESPONSE, 0,
5000, error);
if (status != AMT_STATUS_SUCCESS) {
5000, error)) {
g_prefix_error (error, "unable to get provisioning state: ");
return FALSE;
}
*state = response->data[0];
return TRUE;
}
@ -369,12 +447,13 @@ static FuDevice *
fu_plugin_amt_create_device (GError **error)
{
gchar guid_buf[37];
guint32 status;
guint8 state;
struct amt_code_versions ver;
uuid_t uu;
g_autofree struct amt_host_if_resp_header *response = NULL;
g_autoptr(FuDevice) dev = NULL;
g_autoptr(GString) version_bl = g_string_new (NULL);
g_autoptr(GString) version_fw = g_string_new (NULL);
g_autoptr(mei_context) ctx = g_new0 (mei_context, 1);
const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \
@ -385,33 +464,18 @@ fu_plugin_amt_create_device (GError **error)
return NULL;
/* check version */
status = amt_host_if_call (ctx,
if (!amt_host_if_call (ctx,
(const guchar *) &CODE_VERSION_REQ,
sizeof(CODE_VERSION_REQ),
(guint8 **) &response,
AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0,
5000,
error);
if (status != AMT_STATUS_SUCCESS) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Failed to check version");
error)) {
g_prefix_error (error, "Failed to check version: ");
return NULL;
}
status = amt_verify_code_versions (response);
if (status == AMT_STATUS_HOST_IF_EMPTY_RESPONSE) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"Intel AMT is disabled");
return NULL;
}
if (status != AMT_STATUS_SUCCESS) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"Failed to verify code versions");
if (!amt_verify_code_versions (response, error)) {
g_prefix_error (error, "failed to verify code versions: ");
return NULL;
}
memcpy (&ver, response->data, sizeof(struct amt_code_versions));
@ -449,18 +513,38 @@ fu_plugin_amt_create_device (GError **error)
/* get version numbers */
for (guint i = 0; i < ver.count; i++) {
if (g_strcmp0 (ver.versions[i].description.string, "AMT") == 0) {
fu_device_set_version (dev, ver.versions[i].version.string);
g_string_append (version_fw, ver.versions[i].version.string);
continue;
}
if (g_strcmp0 (ver.versions[i].description.string,
"Recovery Version") == 0) {
fu_device_set_version_bootloader (dev, ver.versions[i].version.string);
if (g_strcmp0 (ver.versions[i].description.string, "Recovery Version") == 0) {
g_string_append (version_bl, ver.versions[i].version.string);
continue;
}
if (g_strcmp0 (ver.versions[i].description.string, "Build Number") == 0) {
g_string_append_printf (version_fw, ".%s",
ver.versions[i].version.string);
continue;
}
if (g_strcmp0 (ver.versions[i].description.string, "Recovery Build Num") == 0) {
g_string_append_printf (version_bl, ".%s",
ver.versions[i].version.string);
continue;
}
}
if (version_fw->len > 0)
fu_device_set_version (dev, version_fw->str);
if (version_bl->len > 0)
fu_device_set_version_bootloader (dev, version_bl->str);
return g_steal_pointer (&dev);
}
void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
}
gboolean
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
{

View File

@ -1,6 +1,7 @@
cargs = ['-DG_LOG_DOMAIN="FuPluginAmt"']
shared_module('fu_plugin_amt',
fu_hash,
sources : [
'fu-plugin-amt.c',
],
@ -11,6 +12,9 @@ shared_module('fu_plugin_amt',
],
install : true,
install_dir: plugin_dir,
link_with : [
libfwupdprivate,
],
c_args : cargs,
dependencies : [
plugin_deps,

44
plugins/ata/README.md Normal file
View File

@ -0,0 +1,44 @@
ATA
===
Introduction
------------
This plugin allows updating ATA/ATAPI storage hardware. Devices are enumerated
from the block devices and if ID_ATA_DOWNLOAD_MICROCODE is supported they can
be updated with appropriate firmware file.
Updating ATA devices is more dangerous than other hardware such as DFU or NVMe
and should be tested carefully with the help of the drive vendor.
The device GUID is read from the trimmed model string.
Firmware Format
---------------
The daemon will decompress the cabinet archive and extract a firmware blob in
an unspecified binary file format.
This plugin supports the following protocol ID:
* org.t13.ata
GUID Generation
---------------
These device use the Microsoft DeviceInstanceId values, e.g.
* `IDE\VENDOR[40]REVISION[8]`
* `IDE\0VENDOR[40]`
See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices
for more details.
Quirk use
---------
This plugin uses the following plugin-specific quirks:
| Quirk | Description | Minimum fwupd version |
|------------------------|-------------------------------------------|-----------------------|
| `AtaTransferBlocks` | Blocks to transfer, or `0xffff` for max | 1.2.4 |
| `AtaTransferMode` | The transfer mode, `0x3`, `0x7` or `0xe` | 1.2.4 |

1
plugins/ata/ata.quirk Normal file
View File

@ -0,0 +1 @@

626
plugins/ata/fu-ata-device.c Normal file
View File

@ -0,0 +1,626 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#include <glib/gstdio.h>
#include "fu-ata-device.h"
#include "fu-chunk.h"
#define FU_ATA_IDENTIFY_SIZE 512 /* bytes */
#define FU_ATA_BLOCK_SIZE 512 /* bytes */
struct ata_tf {
guint8 dev;
guint8 command;
guint8 error;
guint8 status;
guint8 feat;
guint8 nsect;
guint8 lbal;
guint8 lbam;
guint8 lbah;
};
#define ATA_USING_LBA (1 << 6)
#define ATA_STAT_DRQ (1 << 3)
#define ATA_STAT_ERR (1 << 0)
#define ATA_OP_IDENTIFY 0xec
#define ATA_OP_DOWNLOAD_MICROCODE 0x92
#define ATA_SUBCMD_MICROCODE_OBSOLETE 0x01
#define ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS_ACTIVATE 0x03
#define ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNK 0x07
#define ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS 0x0e
#define ATA_SUBCMD_MICROCODE_ACTIVATE 0x0f
#define SG_CHECK_CONDITION 0x02
#define SG_DRIVER_SENSE 0x08
#define SG_ATA_12 0xa1
#define SG_ATA_12_LEN 12
#define SG_ATA_PROTO_NON_DATA (3 << 1)
#define SG_ATA_PROTO_PIO_IN (4 << 1)
#define SG_ATA_PROTO_PIO_OUT (5 << 1)
enum {
SG_CDB2_TLEN_NODATA = 0 << 0,
SG_CDB2_TLEN_FEAT = 1 << 0,
SG_CDB2_TLEN_NSECT = 2 << 0,
SG_CDB2_TLEN_BYTES = 0 << 2,
SG_CDB2_TLEN_SECTORS = 1 << 2,
SG_CDB2_TDIR_TO_DEV = 0 << 3,
SG_CDB2_TDIR_FROM_DEV = 1 << 3,
SG_CDB2_CHECK_COND = 1 << 5,
};
struct _FuAtaDevice {
FuUdevDevice parent_instance;
guint pci_depth;
gint fd;
guint16 transfer_blocks;
guint8 transfer_mode;
};
G_DEFINE_TYPE (FuAtaDevice, fu_ata_device, FU_TYPE_UDEV_DEVICE)
#ifndef HAVE_GUDEV_232
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
#pragma clang diagnostic pop
#endif
guint8
fu_ata_device_get_transfer_mode (FuAtaDevice *self)
{
return self->transfer_mode;
}
guint16
fu_ata_device_get_transfer_blocks (FuAtaDevice *self)
{
return self->transfer_blocks;
}
static gchar *
fu_ata_device_get_string (const guint16 *buf, guint start, guint end)
{
g_autoptr(GString) str = g_string_new (NULL);
for (guint i = start; i <= end; i++) {
g_string_append_c (str, (gchar) (buf[i] >> 8));
g_string_append_c (str, (gchar) (buf[i] & 0xff));
}
/* remove whitespace before returning */
if (str->len > 0) {
g_strchomp (str->str);
if (str->str[0] == '\0')
return NULL;
}
return g_string_free (g_steal_pointer (&str), FALSE);
}
static void
fu_ata_device_to_string (FuDevice *device, GString *str)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
g_string_append (str, " FuAtaDevice:\n");
g_string_append_printf (str, " fd:\t\t\t%i\n", self->fd);
g_string_append_printf (str, " transfer-mode:\t0x%x\n", (guint) self->transfer_mode);
g_string_append_printf (str, " transfer-size:\t0x%x\n", (guint) self->transfer_blocks);
g_string_append_printf (str, " pci-depth:\t\t%u\n", self->pci_depth);
}
/* https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices */
static gchar *
fu_ata_device_pad_string_for_id (const gchar *name)
{
GString *str = g_string_new (name);
fu_common_string_replace (str, " ", "_");
for (guint i = str->len; i < 40; i++)
g_string_append_c (str, '_');
return g_string_free (str, FALSE);
}
static gboolean
fu_ata_device_parse_id (FuAtaDevice *self, const guint8 *buf, gsize sz, GError **error)
{
FuDevice *device = FU_DEVICE (self);
guint16 xfer_min = 1;
guint16 xfer_max = 0xffff;
guint16 id[FU_ATA_IDENTIFY_SIZE/2];
g_autofree gchar *name_pad = NULL;
g_autofree gchar *sku = NULL;
/* check size */
if (sz != FU_ATA_IDENTIFY_SIZE) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"ID incorrect size, got 0x%02x",
(guint) sz);
return FALSE;
}
/* read LE buffer */
for (guint i = 0; i < sz / 2; i++)
id[i] = fu_common_read_uint16 (buf + (i * 2), G_LITTLE_ENDIAN);
/* verify drive correctly supports DOWNLOAD_MICROCODE */
if (!(id[83] & 1 && id[86] & 1)) {
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"DOWNLOAD_MICROCODE not supported by device");
return FALSE;
}
/* firmware will be applied when the device restarts */
if (self->transfer_mode == ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
/* the newer, segmented transfer mode */
if (self->transfer_mode == ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS_ACTIVATE ||
self->transfer_mode == ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS) {
xfer_min = id[234];
if (xfer_min == 0x0 || xfer_min == 0xffff)
xfer_min = 1;
xfer_max = id[235];
if (xfer_max == 0x0 || xfer_max == 0xffff)
xfer_max = xfer_min;
}
/* fall back to a sane block size */
if (self->transfer_blocks == 0x0)
self->transfer_blocks = xfer_min;
else if (self->transfer_blocks == 0xffff)
self->transfer_blocks = xfer_max;
/* get values in case the kernel didn't */
if (fu_device_get_serial (device) == NULL) {
g_autofree gchar *tmp = NULL;
tmp = fu_ata_device_get_string (id, 10, 19);
fu_device_set_serial (device, tmp);
}
if (fu_device_get_name (device) == NULL) {
g_autofree gchar *tmp = NULL;
tmp = fu_ata_device_get_string (id, 27, 46);
fu_device_set_name (device, tmp);
}
if (fu_device_get_version (device) == NULL) {
g_autofree gchar *tmp = NULL;
tmp = fu_ata_device_get_string (id, 23, 26);
fu_device_set_version (device, tmp);
}
/* 8 byte additional product identifier == SKU? */
sku = fu_ata_device_get_string (id, 170, 173);
if (sku != NULL)
g_debug ("SKU=%s", sku);
/* add extra GUIDs */
name_pad = fu_ata_device_pad_string_for_id (fu_device_get_name (device));
if (name_pad != NULL &&
fu_device_get_version (device) != NULL) {
g_autofree gchar *tmp = NULL;
tmp = g_strdup_printf ("IDE\\%s%s", name_pad,
fu_device_get_version (device));
fu_device_add_guid (device, tmp);
}
if (name_pad != NULL) {
g_autofree gchar *tmp = NULL;
tmp = g_strdup_printf ("IDE\\0%s", name_pad);
fu_device_add_guid (device, tmp);
}
return TRUE;
}
static gboolean
fu_ata_device_open (FuDevice *device, GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
GUdevDevice *udev_device = fu_udev_device_get_dev (FU_UDEV_DEVICE (device));
/* open device */
self->fd = g_open (g_udev_device_get_device_file (udev_device), O_RDONLY);
if (self->fd < 0) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"failed to open %s: %s",
g_udev_device_get_device_file (udev_device),
strerror (errno));
return FALSE;
}
/* success */
return TRUE;
}
static gboolean
fu_ata_device_probe (FuUdevDevice *device, GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
/* set the physical ID */
if (!fu_udev_device_set_physical_id (device, "scsi", error))
return FALSE;
/* look at the PCI depth to work out if in an external enclosure */
self->pci_depth = fu_udev_device_get_slot_depth (device, "pci");
if (self->pci_depth <= 2)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
return TRUE;
}
static guint64
fu_ata_device_tf_to_pack_id (struct ata_tf *tf)
{
guint32 lba24 = (tf->lbah << 16) | (tf->lbam << 8) | (tf->lbal);
guint32 lbah = tf->dev & 0x0f;
return (((guint64) lbah) << 24) | (guint64) lba24;
}
static gboolean
fu_ata_device_command (FuAtaDevice *self, struct ata_tf *tf,
gint dxfer_direction, guint timeout_ms,
guint8 *dxferp, gsize dxfer_len, GError **error)
{
guint8 cdb[SG_ATA_12_LEN] = { 0x0 };
guint8 sb[32] = { 0x0 };
sg_io_hdr_t io_hdr = { 0x0 };
/* map _TO_DEV to PIO mode */
if (dxfer_direction == SG_DXFER_TO_DEV)
cdb[1] = SG_ATA_PROTO_PIO_OUT;
else if (dxfer_direction == SG_DXFER_FROM_DEV)
cdb[1] = SG_ATA_PROTO_PIO_IN;
else
cdb[1] = SG_ATA_PROTO_NON_DATA;
/* libata workaround: don't demand sense data for IDENTIFY */
if (dxfer_len > 0) {
cdb[2] |= SG_CDB2_TLEN_NSECT | SG_CDB2_TLEN_SECTORS;
cdb[2] |= dxfer_direction == SG_DXFER_TO_DEV ? SG_CDB2_TDIR_TO_DEV : SG_CDB2_TDIR_FROM_DEV;
} else {
cdb[2] = SG_CDB2_CHECK_COND;
}
/* populate non-LBA48 CDB */
cdb[0] = SG_ATA_12;
cdb[3] = tf->feat;
cdb[4] = tf->nsect;
cdb[5] = tf->lbal;
cdb[6] = tf->lbam;
cdb[7] = tf->lbah;
cdb[8] = tf->dev;
cdb[9] = tf->command;
fu_common_dump_raw (G_LOG_DOMAIN, "CBD", cdb, sizeof(cdb));
if (dxfer_direction == SG_DXFER_TO_DEV && dxferp != NULL) {
fu_common_dump_raw (G_LOG_DOMAIN, "outgoing_data",
dxferp, dxfer_len);
}
/* hit hardware */
io_hdr.interface_id = 'S';
io_hdr.mx_sb_len = sizeof(sb);
io_hdr.dxfer_direction = dxfer_direction;
io_hdr.dxfer_len = dxfer_len;
io_hdr.dxferp = dxferp;
io_hdr.cmdp = cdb;
io_hdr.cmd_len = SG_ATA_12_LEN;
io_hdr.sbp = sb;
io_hdr.pack_id = fu_ata_device_tf_to_pack_id (tf);
io_hdr.timeout = timeout_ms;
if (ioctl (self->fd, SG_IO, &io_hdr) == -1) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"SG_IO not supported: %s",
strerror (errno));
return FALSE;
}
g_debug ("ATA_%u status=0x%x, host_status=0x%x, driver_status=0x%x",
io_hdr.cmd_len, io_hdr.status, io_hdr.host_status, io_hdr.driver_status);
fu_common_dump_raw (G_LOG_DOMAIN, "SB", sb, sizeof(sb));
/* error check */
if (io_hdr.status && io_hdr.status != SG_CHECK_CONDITION) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"bad status: 0x%x", io_hdr.status);
return FALSE;
}
if (io_hdr.host_status) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"bad host status: 0x%x", io_hdr.host_status);
return FALSE;
}
if (io_hdr.driver_status && (io_hdr.driver_status != SG_DRIVER_SENSE)) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"bad driver status: 0x%x", io_hdr.driver_status);
return FALSE;
}
/* repopulate ata_tf */
tf->error = sb[8 + 3];
tf->nsect = sb[8 + 5];
tf->lbal = sb[8 + 7];
tf->lbam = sb[8 + 9];
tf->lbah = sb[8 + 11];
tf->dev = sb[8 + 12];
tf->status = sb[8 + 13];
g_debug ("ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x",
io_hdr.cmd_len, tf->status, tf->error, tf->nsect, tf->lbal, tf->lbam, tf->lbah, tf->dev);
/* io error */
if (tf->status & (ATA_STAT_ERR | ATA_STAT_DRQ)) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"I/O error, ata_op=0x%02x ata_status=0x%02x ata_error=0x%02x",
tf->command, tf->status, tf->error);
return FALSE;
}
/* success */
return TRUE;
}
static gboolean
fu_ata_device_setup (FuDevice *device, GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
struct ata_tf tf = { 0x0 };
guint8 id[FU_ATA_IDENTIFY_SIZE];
/* get ID block */
tf.dev = ATA_USING_LBA;
tf.command = ATA_OP_IDENTIFY;
tf.nsect = 1; /* 512 bytes */
if (!fu_ata_device_command (self, &tf, SG_DXFER_FROM_DEV, 1000,
id, sizeof(id), error)) {
g_prefix_error (error, "failed to IDENTIFY");
return FALSE;
}
if (!fu_ata_device_parse_id (self, id, sizeof(id), error))
return FALSE;
/* add the name fallback */
fu_device_add_guid (device, fu_device_get_name (device));
/* success */
return TRUE;
}
static gboolean
fu_ata_device_close (FuDevice *device, GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
if (!g_close (self->fd, error))
return FALSE;
self->fd = 0;
return TRUE;
}
static gboolean
fu_ata_device_fw_download (FuAtaDevice *self,
guint32 idx,
guint32 addr,
const guint8 *data,
guint32 data_sz,
GError **error)
{
struct ata_tf tf = { 0x0 };
guint32 block_count = data_sz / FU_ATA_BLOCK_SIZE;
guint32 buffer_offset = addr / FU_ATA_BLOCK_SIZE;
/* write block */
tf.dev = 0xa0 | ATA_USING_LBA;
tf.command = ATA_OP_DOWNLOAD_MICROCODE;
tf.feat = self->transfer_mode;
tf.nsect = block_count & 0xff;
tf.lbal = block_count >> 8;
tf.lbam = buffer_offset & 0xff;
tf.lbah = buffer_offset >> 8;
if (!fu_ata_device_command (self, &tf, SG_DXFER_TO_DEV,
120 * 1000, /* a long time! */
(guint8 *) data, data_sz, error)) {
g_prefix_error (error, "failed to write firmware @0x%0x",
(guint) addr);
return FALSE;
}
/* check drive status */
if (tf.nsect == 0x0)
return TRUE;
/* drive wants more data, or thinks it is all done */
if (tf.nsect == 0x1 || tf.nsect == 0x2)
return TRUE;
/* the offset was set up incorrectly */
if (tf.nsect == 0x4) {
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"alignment error");
return FALSE;
}
/* other error */
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"unknown return code 0x%02x",
tf.nsect);
return FALSE;
}
static gboolean
fu_ata_device_write_firmware (FuDevice *device, GBytes *fw, GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
guint32 chunksz = (guint32) self->transfer_blocks * FU_ATA_BLOCK_SIZE;
guint max_size = 0xffff * FU_ATA_BLOCK_SIZE;
g_autoptr(GPtrArray) chunks = NULL;
/* only one block allowed */
if (self->transfer_mode == ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNK)
max_size = 0xffff;
/* check is valid */
if (g_bytes_get_size (fw) > max_size) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"firmware is too large, maximum size is %u",
max_size);
return FALSE;
}
if (g_bytes_get_size (fw) % FU_ATA_BLOCK_SIZE != 0) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"firmware is not multiple of block size %i",
FU_ATA_BLOCK_SIZE);
return FALSE;
}
/* write each block */
fu_device_set_status (device, FWUPD_STATUS_DEVICE_WRITE);
chunks = fu_chunk_array_new_from_bytes (fw, 0x00, 0x00, chunksz);
for (guint i = 0; i < chunks->len; i++) {
FuChunk *chk = g_ptr_array_index (chunks, i);
if (!fu_ata_device_fw_download (self,
chk->idx,
chk->address,
chk->data,
chk->data_sz,
error)) {
g_prefix_error (error, "failed to write chunk %u: ", i);
return FALSE;
}
fu_device_set_progress_full (device, (gsize) i, (gsize) chunks->len + 1);
}
/* success! */
fu_device_set_progress (device, 100);
return TRUE;
}
static gboolean
fu_ata_device_set_quirk_kv (FuDevice *device,
const gchar *key,
const gchar *value,
GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
if (g_strcmp0 (key, "AtaTransferMode") == 0) {
guint64 tmp = fu_common_strtoull (value);
if (tmp != ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS_ACTIVATE &&
tmp != ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS &&
tmp != ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNK) {
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"AtaTransferMode only supports "
"values 0x3, 0x7 or 0xe");
return FALSE;
}
self->transfer_mode = (guint8) tmp;
return TRUE;
}
if (g_strcmp0 (key, "AtaTransferBlocks") == 0) {
guint64 tmp = fu_common_strtoull (value);
if (tmp > 0xffff) {
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"AtaTransferBlocks only supports "
"values <= 0xffff");
return FALSE;
}
self->transfer_blocks = (guint16) tmp;
return TRUE;
}
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"quirk key not supported");
return FALSE;
}
static void
fu_ata_device_init (FuAtaDevice *self)
{
/* we chose this default as _DOWNLOAD_CHUNKS_ACTIVATE applies the
* firmware straight away and the kernel might not like the unexpected
* ATA restart and panic */
self->transfer_mode = ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNKS;
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_set_summary (FU_DEVICE (self), "ATA Drive");
fu_device_add_icon (FU_DEVICE (self), "drive-harddisk");
}
static void
fu_ata_device_finalize (GObject *object)
{
G_OBJECT_CLASS (fu_ata_device_parent_class)->finalize (object);
}
static void
fu_ata_device_class_init (FuAtaDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
FuUdevDeviceClass *klass_udev_device = FU_UDEV_DEVICE_CLASS (klass);
object_class->finalize = fu_ata_device_finalize;
klass_device->to_string = fu_ata_device_to_string;
klass_device->set_quirk_kv = fu_ata_device_set_quirk_kv;
klass_device->open = fu_ata_device_open;
klass_device->setup = fu_ata_device_setup;
klass_device->close = fu_ata_device_close;
klass_device->write_firmware = fu_ata_device_write_firmware;
klass_udev_device->probe = fu_ata_device_probe;
}
FuAtaDevice *
fu_ata_device_new (FuUdevDevice *device)
{
FuAtaDevice *self = g_object_new (FU_TYPE_ATA_DEVICE, NULL);
fu_device_incorporate (FU_DEVICE (self), FU_DEVICE (device));
return self;
}
FuAtaDevice *
fu_ata_device_new_from_blob (const guint8 *buf, gsize sz, GError **error)
{
g_autoptr(FuAtaDevice) self = g_object_new (FU_TYPE_ATA_DEVICE, NULL);
if (!fu_ata_device_parse_id (self, buf, sz, error))
return NULL;
return g_steal_pointer (&self);
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#ifndef __FU_ATA_DEVICE_H
#define __FU_ATA_DEVICE_H
#include "fu-plugin.h"
G_BEGIN_DECLS
#define FU_TYPE_ATA_DEVICE (fu_ata_device_get_type ())
G_DECLARE_FINAL_TYPE (FuAtaDevice, fu_ata_device, FU, ATA_DEVICE, FuUdevDevice)
FuAtaDevice *fu_ata_device_new (FuUdevDevice *device);
FuAtaDevice *fu_ata_device_new_from_blob (const guint8 *buf,
gsize sz,
GError **error);
/* for self tests */
guint8 fu_ata_device_get_transfer_mode (FuAtaDevice *self);
guint16 fu_ata_device_get_transfer_blocks (FuAtaDevice *self);
G_END_DECLS
#endif /* __FU_ATA_DEVICE_H */

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include "fu-plugin-vfuncs.h"
#include "fu-ata-device.h"
gboolean
fu_plugin_udev_device_added (FuPlugin *plugin, FuUdevDevice *device, GError **error)
{
GUdevDevice *udev_device = fu_udev_device_get_dev (device);
g_autoptr(FuAtaDevice) dev = NULL;
g_autoptr(FuDeviceLocker) locker = NULL;
/* interesting device? */
if (udev_device == NULL)
return TRUE;
if (g_strcmp0 (g_udev_device_get_subsystem (udev_device), "block") != 0)
return TRUE;
if (g_strcmp0 (g_udev_device_get_devtype (udev_device), "disk") != 0)
return TRUE;
if (!g_udev_device_get_property_as_boolean (udev_device, "ID_ATA_SATA"))
return TRUE;
if (!g_udev_device_get_property_as_boolean (udev_device, "ID_ATA_DOWNLOAD_MICROCODE"))
return TRUE;
dev = fu_ata_device_new (device);
locker = fu_device_locker_new (dev, error);
if (locker == NULL)
return FALSE;
fu_plugin_device_add (plugin, FU_DEVICE (dev));
return TRUE;
}
void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_udev_subsystem (plugin, "block");
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_SUPPORTS_PROTOCOL, "org.t13.ata");
}
gboolean
fu_plugin_update (FuPlugin *plugin,
FuDevice *device,
GBytes *blob_fw,
FwupdInstallFlags flags,
GError **error)
{
g_autoptr(FuDeviceLocker) locker = NULL;
locker = fu_device_locker_new (device, error);
if (locker == NULL)
return FALSE;
return fu_device_write_firmware (device, blob_fw, error);
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include <fwupd.h>
#include "fu-ata-device.h"
#include "fu-test.h"
static void
fu_ata_id_func (void)
{
gboolean ret;
gsize sz;
g_autofree gchar *data = NULL;
g_autofree gchar *path = NULL;
g_autoptr(FuAtaDevice) dev = NULL;
g_autoptr(GError) error = NULL;
path = fu_test_get_filename (TESTDATADIR, "StarDrive-SBFM61.2.bin");
g_assert_nonnull (path);
ret = g_file_get_contents (path, &data, &sz, &error);
g_assert_no_error (error);
g_assert (ret);
dev = fu_ata_device_new_from_blob ((guint8 *)data, sz, &error);
g_assert_no_error (error);
g_assert_nonnull (dev);
g_assert_cmpint (fu_ata_device_get_transfer_mode (dev), ==, 0xe);
g_assert_cmpint (fu_ata_device_get_transfer_blocks (dev), ==, 0x1);
g_assert_cmpstr (fu_device_get_serial (FU_DEVICE (dev)), ==, "A45A078A198600476509");
g_assert_cmpstr (fu_device_get_name (FU_DEVICE (dev)), ==, "SATA SSD");
g_assert_cmpstr (fu_device_get_version (FU_DEVICE (dev)), ==, "SBFM61.2");
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
/* tests go here */
g_test_add_func ("/fwupd/id", fu_ata_id_func);
return g_test_run ();
}

58
plugins/ata/meson.build Normal file
View File

@ -0,0 +1,58 @@
cargs = ['-DG_LOG_DOMAIN="FuPluginAta"']
install_data([
'ata.quirk',
],
install_dir: join_paths(datadir, 'fwupd', 'quirks.d')
)
shared_module('fu_plugin_ata',
fu_hash,
sources : [
'fu-plugin-ata.c',
'fu-ata-device.c',
],
include_directories : [
include_directories('../..'),
include_directories('../../src'),
include_directories('../../libfwupd'),
],
install : true,
install_dir: plugin_dir,
c_args : [
cargs,
'-DLOCALSTATEDIR="' + localstatedir + '"',
],
link_with : [
libfwupdprivate,
],
dependencies : [
plugin_deps,
],
)
if get_option('tests')
testdatadir = join_paths(meson.current_source_dir(), 'tests')
cargs += '-DTESTDATADIR="' + testdatadir + '"'
e = executable(
'ata-self-test',
sources : [
'fu-self-test.c',
'fu-ata-device.c',
],
include_directories : [
include_directories('..'),
include_directories('../..'),
include_directories('../../libfwupd'),
include_directories('../../src'),
],
dependencies : [
plugin_deps,
],
link_with : [
libfwupdprivate,
],
c_args : cargs
)
test('ata-self-test', e)
endif

Binary file not shown.

View File

@ -10,3 +10,22 @@ accurate color matching.
ColorHug versions 1 and 2 support a custom HID-based flashing protocol, but
version 3 (ColorHug+) has now switched to DFU.
Firmware Format
---------------
The daemon will decompress the cabinet archive and extract a firmware blob in
a packed binary file format.
This plugin supports the following protocol ID:
* com.hughski.colorhug
GUID Generation
---------------
These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_273F&PID_1001&REV_0001`
* `USB\VID_273F&PID_1001`
* `USB\VID_273F`

View File

@ -6,6 +6,7 @@ Guid = 40338ceb-b966-4eae-adae-9c32edfcc484
FirmwareSizeMin = 0x2000
FirmwareSizeMax = 0x8000
CounterpartGuid = USB\VID_273F&PID_1001
InstallDuration = 8
[DeviceInstanceId=USB\VID_273F&PID_1001]
Plugin = colorhug
@ -14,6 +15,7 @@ Summary = An open source display colorimeter
Icon = colorimeter-colorhug
Guid = 40338ceb-b966-4eae-adae-9c32edfcc484
CounterpartGuid = USB\VID_273F&PID_1000
InstallDuration = 8
# ColorHug2
[DeviceInstanceId=USB\VID_273F&PID_1004]
@ -25,12 +27,14 @@ Guid = 2082b5e0-7a64-478a-b1b2-e3404fab6dad
FirmwareSizeMin = 0x2000
FirmwareSizeMax = 0x8000
CounterpartGuid = USB\VID_273F&PID_1005
InstallDuration = 8
[DeviceInstanceId=USB\VID_273F&PID_1005]
Plugin = colorhug
Flags = is-bootloader
Guid = 2082b5e0-7a64-478a-b1b2-e3404fab6dad
CounterpartGuid = USB\VID_273F&PID_1004
InstallDuration = 8
# ColorHugALS
[DeviceInstanceId=USB\VID_273F&PID_1007]
@ -41,9 +45,11 @@ Guid = 84f40464-9272-4ef7-9399-cd95f12da696
FirmwareSizeMin = 0x1000
FirmwareSizeMax = 0x4000
CounterpartGuid = USB\VID_273F&PID_1006
InstallDuration = 5
[DeviceInstanceId=USB\VID_273F&PID_1006]
Plugin = colorhug
Flags = halfsize,is-bootloader
Guid = 84f40464-9272-4ef7-9399-cd95f12da696
CounterpartGuid = USB\VID_273F&PID_1007
InstallDuration = 5

View File

@ -85,17 +85,3 @@ ch_strerror (ChError error_enum)
return "Self test failed: EEPROM";
return NULL;
}
void
ch_buffer_dump (const gchar *title, const guint8 *buf, gsize sz)
{
if (g_getenv ("FWUPD_COLORHUG_VERBOSE") == NULL)
return;
g_print ("%s (%" G_GSIZE_FORMAT "):\n", title, sz);
for (gsize i = 0; i < sz; i++) {
g_print ("%02x ", buf[i]);
if (i > 0 && (i + 1) % 256 == 0)
g_print ("\n");
}
g_print ("\n");
}

View File

@ -52,9 +52,6 @@ typedef enum {
} ChError;
const gchar *ch_strerror (ChError error_enum);
void ch_buffer_dump (const gchar *title,
const guint8 *buf,
gsize sz);
G_END_DECLS

View File

@ -82,7 +82,8 @@ fu_colorhug_device_msg (FuColorhugDevice *self, guint8 cmd,
memcpy (buf + 1, ibuf, ibufsz);
/* request */
ch_buffer_dump ("REQ", buf, ibufsz + 1);
if (g_getenv ("FWUPD_COLORHUG_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "REQ", buf, ibufsz + 1);
if (!g_usb_device_interrupt_transfer (usb_device,
CH_USB_HID_EP_OUT,
buf,
@ -115,7 +116,8 @@ fu_colorhug_device_msg (FuColorhugDevice *self, guint8 cmd,
g_prefix_error (error, "failed to get reply: ");
return FALSE;
}
ch_buffer_dump ("RES", buf, actual_length);
if (g_getenv ("FWUPD_COLORHUG_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "RES", buf, actual_length);
/* old bootloaders do not return the full block */
if (actual_length != CH_USB_HID_EP_SIZE &&

View File

@ -13,7 +13,9 @@
void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_REQUIRES_QUIRK, FU_QUIRKS_PLUGIN);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_SUPPORTS_PROTOCOL, "com.hughski.colorhug");
}
gboolean

View File

@ -7,6 +7,7 @@ install_data([
)
shared_module('fu_plugin_colorhug',
fu_hash,
sources : [
'fu-colorhug-common.c',
'fu-colorhug-device.c',
@ -19,6 +20,9 @@ shared_module('fu_plugin_colorhug',
],
install : true,
install_dir: plugin_dir,
link_with : [
libfwupdprivate,
],
c_args : cargs,
dependencies : [
plugin_deps,

36
plugins/csr/README.md Normal file
View File

@ -0,0 +1,36 @@
CSR Support
===========
Introduction
------------
CSR is often called “driverless DFU” and is used only by BlueCore chips from
Cambridge Silicon Radio (now owned by Qualcomm). The driverless just means that
it's DFU like, and is routed over HID.
CSR is a ODM that makes most of the Bluetooth audio chips in vendor hardware.
The hardware vendor can enable or disable features on the CSR microcontroller
depending on licensing options (for instance echo cancellation), and theres
even a little virtual machine to do simple vendor-specific things.
All the CSR chips are updatable in-field, and most vendors issue updates to fix
sound quality issues or to add support for new protocols or devices.
Firmware Format
---------------
The daemon will decompress the cabinet archive and extract a firmware blob in
DFU file format.
This plugin supports the following protocol ID:
* com.qualcomm.dfu
GUID Generation
---------------
These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_0A12&PID_1337&REV_2520`
* `USB\VID_0A12&PID_1337`
* `USB\VID_0A12`

View File

@ -67,17 +67,6 @@ fu_csr_device_to_string (FuDevice *device, GString *str)
g_string_append_printf (str, " timeout:\t\t%" G_GUINT32_FORMAT "\n", self->dnload_timeout);
}
static void
fu_csr_device_dump (const gchar *title, const guint8 *buf, gsize sz)
{
if (g_getenv ("FWUPD_CSR_VERBOSE") == NULL)
return;
g_print ("%s (%" G_GSIZE_FORMAT "):\n", title, sz);
for (gsize i = 0; i < sz; i++)
g_print ("%02x ", buf[i]);
g_print ("\n");
}
static gboolean
fu_csr_device_attach (FuDevice *device, GError **error)
{
@ -86,7 +75,8 @@ fu_csr_device_attach (FuDevice *device, GError **error)
gsize sz = 0;
guint8 buf[] = { FU_CSR_REPORT_ID_CONTROL, FU_CSR_CONTROL_RESET };
fu_csr_device_dump ("Reset", buf, sz);
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "Reset", buf, sz);
if (!g_usb_device_control_transfer (usb_device,
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
G_USB_DEVICE_REQUEST_TYPE_CLASS,
@ -135,7 +125,8 @@ fu_csr_device_get_status (FuCsrDevice *self, GError **error)
g_prefix_error (error, "Failed to GetStatus: ");
return FALSE;
}
fu_csr_device_dump ("GetStatus", buf, sz);
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "GetStatus", buf, sz);
/* check packet */
if (sz != FU_CSR_STATUS_HEADER_SIZE) {
@ -179,7 +170,8 @@ fu_csr_device_clear_status (FuCsrDevice *self, GError **error)
return TRUE;
/* hit hardware */
fu_csr_device_dump ("ClearStatus", buf, sz);
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "ClearStatus", buf, sz);
if (!g_usb_device_control_transfer (usb_device,
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
G_USB_DEVICE_REQUEST_TYPE_CLASS,
@ -230,7 +222,8 @@ fu_csr_device_upload_chunk (FuCsrDevice *self, GError **error)
g_prefix_error (error, "Failed to ReadFirmware: ");
return NULL;
}
fu_csr_device_dump ("ReadFirmware", buf, sz);
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "ReadFirmware", buf, sz);
/* too small to parse */
if (sz < FU_CSR_COMMAND_HEADER_SIZE) {
@ -362,7 +355,8 @@ fu_csr_device_download_chunk (FuCsrDevice *self, guint16 idx, GBytes *chunk, GEr
memcpy (buf + FU_CSR_COMMAND_HEADER_SIZE, chunk_data, chunk_sz);
/* hit hardware */
fu_csr_device_dump ("Upgrade", buf, sizeof(buf));
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL)
fu_common_dump_raw (G_LOG_DOMAIN, "Upgrade", buf, sizeof(buf));
if (!g_usb_device_control_transfer (usb_device,
G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
G_USB_DEVICE_REQUEST_TYPE_CLASS,

View File

@ -13,7 +13,9 @@
void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_REQUIRES_QUIRK, FU_QUIRKS_PLUGIN);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_SUPPORTS_PROTOCOL, "com.qualcomm.dfu");
}
gboolean

View File

@ -5,6 +5,7 @@ install_data(['csr-aiaiai.quirk'],
)
shared_module('fu_plugin_csr',
fu_hash,
sources : [
'fu-csr-device.c',
'fu-plugin-csr.c',
@ -22,6 +23,7 @@ shared_module('fu_plugin_csr',
plugin_deps,
],
link_with : [
libfwupdprivate,
dfu,
],
)

View File

@ -24,3 +24,48 @@ The MST controller is updated through either the DP Aux interface
When this plugin is used, devices present in other plugins may be shown in
the topology of this dock. This is intentional as this plugin works together
with those plugins to manage the flashing of all components.
Firmware Format
---------------
The daemon will decompress the cabinet archive and extract several firmware
blobs with an unspecified binary file format.
This plugin supports the following protocol ID:
* com.dell.dock
* com.synaptics.mst
GUID Generation
---------------
These devices use several different generation schemes, e.g.
* USB Hub1: `USB\VID_413C&PID_B06F&hub`
* USB Hub2: `USB\VID_413C&PID_B06E&hub`
* Embedded Controller: `USB\VID_413C&PID_B06E&hub&embedded`
* Update Level: `USB\VID_413C&PID_B06E&hub&status`
* MST Hub: `MST-panamera-vmm5331-259`
* Thunderbolt Controller: `TBT-00d4b070`
Custom flag use:
----------------
This plugin uses the following plugin-specific custom flags:
* `skip-restart`: Don't run the reset or reboot procedure of the component
Quirk use
---------
This plugin uses the following plugin-specific quirks:
| Quirk | Description | Minimum fwupd version |
|------------------------------|-------------------------------------------------------------------------|-----------------------|
| `DellDockUnlockTarget` | The EC argument needed for unlocking certain device usage. | 1.1.3 |
| `DellDockBlobMajorOffset` | The offset of the major version number in a payload | 1.1.3 |
| `DellDockBlobMinorOffset` | The offset of the minor version number in a payload | 1.1.3 |
| `DellDockBlobBuildOffset` | The offset of the build version number in a payload | 1.1.3 |
| `DellDockBlobVersionOffset` | The offset of the ASCII representation of a version string in a payload | 1.1.3 |
| `DellDockBoardMin` | The minimum board revision required to safely operate the plugin | 1.1.3 |
| `DellDockVersionLowest` | The minimum component version required to safely operate the plugin | 1.1.3 |
| `DellDockBoard*` | The board description of a board revision | 1.1.3 |
| `DellDockInstallDurationI2C` | The duration of time required to install a payload via I2C. | 1.1.3 |

View File

@ -70,8 +70,8 @@ FirmwareSizeMax = 0x20000
Flags = require-ac
Children = FuDellDockStatus|USB\VID_413C&PID_B06E&hub&status,FuDellDockMst|MST-panamera-vmm5331-259
DellDockUnlockTarget = 1
DellDockBoardMin = 2
DellDockVersionLowest = 00.00.00.09
DellDockBoardMin = 4
DellDockVersionLowest = 00.00.00.17
DellDockBlobVersionOffset = 0x1AFC0
InstallDuration = 60
@ -81,7 +81,6 @@ Name = Package level of Dell dock
Summary = A representation of dock update status
Plugin = dell_dock
Vendor = Dell Inc
Flags = updatable
FirmwareSizeMin = 24
FirmwareSizeMax = 24
InstallDuration = 5
@ -114,14 +113,8 @@ FirmwareSizeMin=0x40000
FirmwareSizeMax=0x80000
Flags = require-ac
InstallDuration = 22
# Thunderbolt controller (old ID)
# TODO: This should be dropped when DellDockBoardMin is 3+
[Guid=TBT-00d40012]
Name = Thunderbolt controller in Dell dock
Summary = Thunderbolt controller
Vendor = Dell Inc
ParentGuid = USB\VID_413C&PID_B06E&hub&embedded
FirmwareSizeMin=0x40000
FirmwareSizeMax=0x80000
Flags = require-ac,ignore-validation
DellDockInstallDurationI2C = 181
DellDockUnlockTarget = 10
DellDockHubVersionLowest = 1.31
DellDockBlobMajorOffset = 0x400a
DellDockBlobMinorOffset = 0x4009

Some files were not shown because too many files have changed in this diff Show More