mirror of
https://git.proxmox.com/git/fwupd
synced 2026-03-28 09:59:03 +00:00
Release fwupd 1.5.1
-----BEGIN PGP SIGNATURE----- iQFIBAABCAAyFiEEFj61ARkiXbPfj0nqF6y6jfqXDhcFAl+gHTsUHHJpY2hhcmRA aHVnaHNpZS5jb20ACgkQF6y6jfqXDhfxbQgAsN8WqqKcO1jb6E/ILQinfIIB9DYT t9p+7f9XrDtB8XAlUyvRF2UOQblLIYkzDRnUwozz3qxWPhpredeOPN/aJTHfk+qJ f/IsBhkPQX/ai1T62iEp0DLBlnrdWAk8RU1ZWxcQtUgnt+WoZQYIg7cDdzgbjLa2 0KW8nl6q8oXAssyxnBa/oBdGUE9r6WehfYPAPvanoFtXCtMLJYGha51DbxvbWe9M 5dNv4skG2vS+BoZaxPGgRqjFaOYLfApPR3lTxlfTyGF7ukQi0q7q8lyLfVrXqq1Z elqwiSeDdR//bW8bsj3d83o93nq7AtPtWuw9LX2HseDY9TFbnOSqxOZrHg== =AVqs -----END PGP SIGNATURE----- New upstream version (1.5.1)
This commit is contained in:
commit
79d8b60fe7
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@ -0,0 +1,14 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{c|h}]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
64
.github/ISSUE_TEMPLATE/bug-report-wd19.md
vendored
Normal file
64
.github/ISSUE_TEMPLATE/bug-report-wd19.md
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
---
|
||||
name: Bug report (Dell WD19)
|
||||
about: Create a report to help us improve
|
||||
title: 'Dell WD19 upgrade issue'
|
||||
labels: bug
|
||||
assignees: 'superm1'
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
|
||||
**Steps to Reproduce**
|
||||
Steps to reproduce the behavior.
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**fwupd version information**
|
||||
Please provide the version of the daemon and client.
|
||||
```shell
|
||||
$ fwupdmgr --version
|
||||
```
|
||||
|
||||
Please note how you installed it (`apt`, `dnf`, `pacman`, source, etc):
|
||||
|
||||
**fwupd device information**
|
||||
Please provide the output of the external fwupd devices recognized in your system.
|
||||
|
||||
```shell
|
||||
$ fwupdmgr get-devices --filter=~internal
|
||||
```
|
||||
|
||||
**Dock SKU**
|
||||
Please mention which module is installed in your WD19.
|
||||
|
||||
- [ ] WD19 (Single-C)
|
||||
- [ ] WD19TB (Thunderbolt)
|
||||
- [ ] WD19DC (Dual-C)
|
||||
|
||||
**Peripherals connected to the dock**
|
||||
Please describe all devices connected to the dock. Be as specific as possible,
|
||||
including USB devices, hubs, monitors, and downstream type-C devices.
|
||||
|
||||
**Verbose daemon logs**
|
||||
First enable daemon verbose logs collection.
|
||||
```shell
|
||||
fwupdmgr modify-config "VerboseDomains" "*"
|
||||
```
|
||||
|
||||
Then try to reproduce the issue. Even if it doesn't reproduce, please attach the
|
||||
daemon verbose logs collected from the system journal.
|
||||
```shell
|
||||
journalctl -b -u fwupd.service
|
||||
```
|
||||
|
||||
**Additional questions**
|
||||
- Operating system and version:
|
||||
- Have you tried unplugging the dock or any peripherals from your machine?
|
||||
- Have you tried to power cycle the dock from the AC adapter?
|
||||
- Is this a regression?
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -21,3 +21,12 @@
|
||||
/*.xz
|
||||
/*.gz
|
||||
__pycache__
|
||||
plugins/acpi-dmar/tests/
|
||||
plugins/acpi-facp/tests/
|
||||
plugins/ata/tests/
|
||||
plugins/dfu/tests/
|
||||
plugins/nvme/tests/
|
||||
plugins/synaptics-mst/tests/
|
||||
plugins/synaptics-prometheus/tests/
|
||||
plugins/tpm-eventlog/tests/
|
||||
plugins/uefi-dbx/tests/
|
||||
|
||||
@ -78,7 +78,7 @@ Enterprise use
|
||||
The flow of updates can be controlled in the enterprise using the
|
||||
"approved updates" feature. This allows the domain administrator to filter
|
||||
the possible updates from a central server (e.g. the LVFS, or a mirror)
|
||||
to only firmware that have been tested specifically in your organisation.
|
||||
to only firmware that have been tested specifically in your organization.
|
||||
|
||||
The list of approved updates can be enabled by adding `ApprovalRequired=true`
|
||||
to the remote configuration file, e.g. `lvfs.conf`. Once enabled, the
|
||||
@ -103,7 +103,7 @@ Other frontends
|
||||
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,
|
||||
2. [KDE Discover](https://userbase.kde.org/Discover) is the software center,
|
||||
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.
|
||||
@ -125,3 +125,4 @@ There are several automated fuzzing tests in fwupd. These take some time to run:
|
||||
ninja fuzz-synaptics-rmi
|
||||
ninja fuzz-firmware
|
||||
ninja fuzz-smbios
|
||||
ninja fuzz-efidbx
|
||||
|
||||
12
RELEASE
12
RELEASE
@ -2,14 +2,22 @@ fwupd Release Notes
|
||||
|
||||
Write release entries:
|
||||
|
||||
git log --format="%s" --cherry-pick --right-only 1.4.5... | grep -i -v trivial | grep -v Merge | sort | uniq
|
||||
git log --format="%s" --cherry-pick --right-only 1.5.0... | 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
|
||||
|
||||
Update translations:
|
||||
|
||||
ninja-build fwupd-pot
|
||||
tx push --source
|
||||
tx pull --all --force --minimum-perc=5
|
||||
ninja-build fix-translations
|
||||
git add ../po/*.po
|
||||
|
||||
2. Commit changes to git:
|
||||
|
||||
# MAKE SURE THIS IS CORRECT
|
||||
export release_ver="1.4.6"
|
||||
export release_ver="1.5.1"
|
||||
|
||||
git commit -a -m "Release fwupd ${release_ver}"
|
||||
git tag -s -f -m "Release fwupd ${release_ver}" "${release_ver}"
|
||||
|
||||
@ -31,5 +31,5 @@ this repository.
|
||||
|
||||
Failing that, please report the issue against the `fwupd` component in Red Hat
|
||||
bugzilla, with the security checkbox set. You should get a response within 3
|
||||
days. We have no bug bountry program, but we're happy to credit you in updates
|
||||
days. We have no bug bounty program, but we're happy to credit you in updates
|
||||
if this is what you would like us to do.
|
||||
|
||||
@ -2,6 +2,7 @@ FROM archlinux/base
|
||||
%%%OS%%%
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
ENV CI_NETWORK true
|
||||
RUN echo fubar > /etc/machine-id
|
||||
RUN rm /usr/share/libalpm/hooks/package-cleanup.hook
|
||||
RUN echo fubar > /etc/machine-id
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
FROM %%%ARCH_PREFIX%%%debian:testing
|
||||
%%%OS%%%
|
||||
ENV CI_NETWORK true
|
||||
RUN echo "deb http://ftp.us.debian.org/debian unstable main contrib non-free" >> /etc/apt/sources.list
|
||||
RUN echo 'Package: *\n\
|
||||
Pin: release a=testing\n\
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
FROM ubuntu:devel
|
||||
%%%OS%%%
|
||||
ENV CI_NETWORK true
|
||||
ENV CC clang
|
||||
RUN echo fubar > /etc/machine-id
|
||||
%%%ARCH_SPECIFIC_COMMAND%%%
|
||||
|
||||
@ -3,6 +3,12 @@ set -e
|
||||
set -x
|
||||
shopt -s extglob
|
||||
|
||||
#clone test firmware
|
||||
if [ "$CI_NETWORK" = "true" ]; then
|
||||
./contrib/ci/get_test_firmware.sh
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
fi
|
||||
|
||||
# prepare the build tree
|
||||
rm -rf build
|
||||
mkdir build && pushd build
|
||||
@ -13,8 +19,8 @@ popd
|
||||
chown nobody . -R
|
||||
|
||||
# install and run TPM simulator necessary for plugins/uefi/uefi-self-test
|
||||
pacman -S --noconfirm ibm-sw-tpm2 tpm2-tools
|
||||
tpm_server &
|
||||
pacman -S --noconfirm swtpm tpm2-tools
|
||||
swtpm socket --tpm2 --server port=2321 --ctrl type=tcp,port=2322 --flags not-need-init --tpmstate "dir=$PWD" &
|
||||
trap "kill $!" EXIT
|
||||
# extend a PCR0 value for test suite
|
||||
sleep 2
|
||||
|
||||
@ -15,6 +15,7 @@ meson .. \
|
||||
--libexecdir=$target \
|
||||
--bindir=$target \
|
||||
-Dbuild=standalone \
|
||||
-Dpolkit=false \
|
||||
-Dplugin_coreboot=false \
|
||||
-Dplugin_flashrom=false \
|
||||
-Dplugin_uefi=false \
|
||||
@ -22,7 +23,7 @@ meson .. \
|
||||
-Dplugin_altos=false \
|
||||
-Dplugin_dell=false \
|
||||
-Dplugin_nvme=false \
|
||||
-Dplugin_tpm=false \
|
||||
-Dtpm=false \
|
||||
-Dsystemd=false \
|
||||
-Dplugin_emmc=false \
|
||||
-Dplugin_amt=false \
|
||||
@ -40,6 +41,10 @@ meson .. \
|
||||
-Dlibjcat:man=false \
|
||||
-Dlibjcat:gpg=false \
|
||||
-Dlibjcat:introspection=false \
|
||||
-Dgusb:tests=false \
|
||||
-Dgusb:docs=false \
|
||||
-Dgusb:introspection=false \
|
||||
-Dgusb:vapi=false \
|
||||
-Dgudev=false $@
|
||||
VERSION=$(meson introspect . --projectinfo | jq -r .version)
|
||||
ninja -v
|
||||
|
||||
@ -2,6 +2,13 @@
|
||||
set -e
|
||||
set -x
|
||||
|
||||
#clone test firmware
|
||||
if [ "$CI_NETWORK" = "true" ]; then
|
||||
./contrib/ci/get_test_firmware.sh
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
fi
|
||||
|
||||
#build
|
||||
rm -rf build
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# remove when tpm2-tss is fixed
|
||||
mkdir -p /usr/include/tss
|
||||
|
||||
#although it's debian, we don't build packages
|
||||
if [ "$OS" = "debian-s390x" ]; then
|
||||
./contrib/ci/debian_s390x.sh
|
||||
@ -23,6 +26,20 @@ sed s/quilt/native/ debian/source/format -i
|
||||
#generate control file
|
||||
./contrib/ci/generate_debian.py
|
||||
|
||||
#check if we have all deps available
|
||||
#if some are missing, we're going to use subproject instead and
|
||||
#packaging CI will fail
|
||||
if ! dpkg-checkbuilddeps; then
|
||||
./contrib/ci/ubuntu.sh
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#clone test firmware
|
||||
if [ "$CI_NETWORK" = "true" ]; then
|
||||
./contrib/ci/get_test_firmware.sh
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
fi
|
||||
|
||||
#disable unit tests if fwupd is already installed (may cause problems)
|
||||
if [ -x /usr/lib/fwupd/fwupd ]; then
|
||||
export DEB_BUILD_OPTIONS=nocheck
|
||||
|
||||
@ -20,6 +20,7 @@ meson .. \
|
||||
-Dplugin_uefi=false \
|
||||
-Dplugin_dell=false \
|
||||
-Dplugin_modem_manager=false \
|
||||
-Dplugin_msr=false \
|
||||
-Dplugin_redfish=false \
|
||||
-Dintrospection=false \
|
||||
-Dgtkdoc=false \
|
||||
|
||||
@ -766,7 +766,7 @@
|
||||
</distro>
|
||||
<distro id="debian">
|
||||
<control>
|
||||
<version>(>= 0.2.9)</version>
|
||||
<version>(>= 0.3.5)</version>
|
||||
</control>
|
||||
<package variant="x86_64" />
|
||||
<package variant="s390x">libgusb-dev:s390x</package>
|
||||
@ -774,7 +774,7 @@
|
||||
</distro>
|
||||
<distro id="ubuntu">
|
||||
<control>
|
||||
<version>(>= 0.2.9)</version>
|
||||
<version>(>= 0.3.3)</version>
|
||||
</control>
|
||||
<package variant="x86_64" />
|
||||
</distro>
|
||||
|
||||
@ -54,7 +54,7 @@ mkdir -p dist
|
||||
cp $HOME/rpmbuild/RPMS/*/*.rpm dist
|
||||
|
||||
if [ "$CI" = "true" ]; then
|
||||
sed "s,^BlacklistPlugins=test;invalid,BlacklistPlugins=," -i /etc/fwupd/daemon.conf
|
||||
sed "s,^DisabledPlugins=test;invalid,DisabledPlugins=," -i /etc/fwupd/daemon.conf
|
||||
|
||||
# set up enough PolicyKit and D-Bus to run the daemon
|
||||
mkdir -p /run/dbus
|
||||
|
||||
8
contrib/ci/get_test_firmware.sh
Executable file
8
contrib/ci/get_test_firmware.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
#clone fwupd-test-firmware
|
||||
rm -rf fwupd-test-firmware
|
||||
git clone https://github.com/fwupd/fwupd-test-firmware
|
||||
#set up build tests to work
|
||||
cp fwupd-test-firmware/ci-tests/* . -R
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
@ -2,14 +2,21 @@
|
||||
set -e
|
||||
set -x
|
||||
|
||||
#clone test firmware
|
||||
if [ "$CI_NETWORK" = "true" ]; then
|
||||
./contrib/ci/get_test_firmware.sh
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
fi
|
||||
|
||||
# Builds using GPG and PKCS7 turned off to make
|
||||
# sure no assumptions of a trust backend
|
||||
rm -rf build
|
||||
meson build \
|
||||
-Dman=false \
|
||||
-Ddaemon=false \
|
||||
-Ddaemon=true \
|
||||
-Dpolkit=false \
|
||||
-Dgusb:tests=false \
|
||||
-Dplugin_tpm=false \
|
||||
-Dtpm=false \
|
||||
-Dplugin_modem_manager=false \
|
||||
-Dplugin_flashrom=false \
|
||||
-Dplugin_uefi=false \
|
||||
|
||||
@ -2,7 +2,14 @@
|
||||
set -e
|
||||
set -x
|
||||
|
||||
#clone test firmware
|
||||
if [ "$CI_NETWORK" = "true" ]; then
|
||||
./contrib/ci/get_test_firmware.sh
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
fi
|
||||
|
||||
#evaluate using Ubuntu's buildflags
|
||||
#evaluate using Debian/Ubuntu's buildflags
|
||||
eval "$(dpkg-buildflags --export=sh)"
|
||||
#filter out -Bsymbolic-functions
|
||||
export LDFLAGS=$(dpkg-buildflags --get LDFLAGS | sed "s/-Wl,-Bsymbolic-functions\s//")
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2017 Max Ehrlich max.ehr@gmail.com
|
||||
# Copyright (C) 2017 Max Ehrlich maxehr@gmail.com
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
@ -107,7 +107,7 @@ def main(args):
|
||||
print('Creating metainfo')
|
||||
make_firmware_metainfo(args, dir)
|
||||
|
||||
print('Cabbing firmware files')
|
||||
print('Creating cabinet file')
|
||||
create_firmware_cab(args, dir)
|
||||
|
||||
print('Done')
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
%global glib2_version 2.45.8
|
||||
%global libxmlb_version 0.1.3
|
||||
%global libgusb_version 0.2.11
|
||||
%global libgusb_version 0.3.5
|
||||
%global libsoup_version 2.51.92
|
||||
%global libjcat_version 0.1.0
|
||||
%global systemd_version 231
|
||||
@ -22,6 +22,15 @@
|
||||
%global have_uefi 1
|
||||
%endif
|
||||
|
||||
# flashrom is only available on these arches
|
||||
%ifarch i686 x86_64 armv7hl aarch64 ppc64le
|
||||
%global have_flashrom 1
|
||||
%endif
|
||||
|
||||
%ifarch i686 x86_64
|
||||
%global have_msr 1
|
||||
%endif
|
||||
|
||||
# redfish is only available on this arch
|
||||
%ifarch x86_64
|
||||
%global have_redfish 1
|
||||
@ -73,7 +82,9 @@ BuildRequires: json-glib-devel >= %{json_glib_version}
|
||||
BuildRequires: vala
|
||||
BuildRequires: bash-completion
|
||||
BuildRequires: git-core
|
||||
%if 0%{?have_flashrom}
|
||||
BuildRequires: flashrom-devel >= 1.2-2
|
||||
%endif
|
||||
|
||||
%if 0%{?have_modem_manager}
|
||||
BuildRequires: ModemManager-glib-devel >= 1.10.0
|
||||
@ -133,6 +144,14 @@ Provides: fwupdate
|
||||
Provides: fwupdate-efi
|
||||
%endif
|
||||
|
||||
# optional, but a really good idea
|
||||
%if 0%{?have_modem_manager}
|
||||
Recommends: %{name}-plugin-modem-manager
|
||||
%endif
|
||||
%if 0%{?have_flashrom}
|
||||
Recommends: %{name}-plugin-flashrom
|
||||
%endif
|
||||
|
||||
%description
|
||||
fwupd is a daemon to allow session software to update device firmware.
|
||||
|
||||
@ -147,11 +166,28 @@ Files for development with %{name}.
|
||||
|
||||
%package tests
|
||||
Summary: Data files for installed tests
|
||||
BuildArch: noarch
|
||||
|
||||
%description tests
|
||||
Data files for installed tests.
|
||||
|
||||
%if 0%{?have_modem_manager}
|
||||
%package plugin-modem-manager
|
||||
Summary: fwupd plugin using ModemManger
|
||||
|
||||
%description plugin-modem-manager
|
||||
This provides the optional package which is only required on hardware that
|
||||
might have mobile broadband hardware. It is probably not required on servers.
|
||||
%endif
|
||||
|
||||
%if 0%{?have_flashrom}
|
||||
%package plugin-flashrom
|
||||
Summary: fwupd plugin using flashrom
|
||||
|
||||
%description plugin-flashrom
|
||||
This provides the optional package which is only required on hardware that
|
||||
can be flashed using flashrom. It is probably not required on servers.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%autosetup -p1
|
||||
|
||||
@ -172,7 +208,16 @@ Data files for installed tests.
|
||||
%else
|
||||
-Dplugin_dummy=false \
|
||||
%endif
|
||||
%if 0%{?have_flashrom}
|
||||
-Dplugin_flashrom=true \
|
||||
%else
|
||||
-Dplugin_flashrom=false \
|
||||
%endif
|
||||
%if 0%{?have_msr}
|
||||
-Dplugin_msr=true \
|
||||
%else
|
||||
-Dplugin_msr=false \
|
||||
%endif
|
||||
-Dplugin_thunderbolt=true \
|
||||
%if 0%{?have_redfish}
|
||||
-Dplugin_redfish=true \
|
||||
@ -182,11 +227,11 @@ Data files for installed tests.
|
||||
%if 0%{?have_uefi}
|
||||
-Dplugin_uefi=true \
|
||||
-Dplugin_nvme=true \
|
||||
-Dplugin_tpm=true \
|
||||
-Dtpm=true \
|
||||
%else
|
||||
-Dplugin_uefi=false \
|
||||
-Dplugin_nvme=false \
|
||||
-Dplugin_tpm=false \
|
||||
-Dtpm=false \
|
||||
%endif
|
||||
%if 0%{?have_dell}
|
||||
-Dplugin_dell=true \
|
||||
@ -205,6 +250,9 @@ Data files for installed tests.
|
||||
%meson_build
|
||||
|
||||
%if 0%{?enable_tests}
|
||||
%if 0%{?enable_ci}
|
||||
./contrib/ci/get_test_firmware.sh
|
||||
%endif
|
||||
%check
|
||||
%meson_test
|
||||
%endif
|
||||
@ -256,6 +304,9 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
%config(noreplace)%{_sysconfdir}/fwupd/thunderbolt.conf
|
||||
%dir %{_libexecdir}/fwupd
|
||||
%{_libexecdir}/fwupd/fwupd
|
||||
%ifarch i686 x86_64
|
||||
%{_libexecdir}/fwupd/fwupd-detect-cet
|
||||
%endif
|
||||
%{_libexecdir}/fwupd/fwupdoffline
|
||||
%if 0%{?have_uefi}
|
||||
%{_libexecdir}/fwupd/efi/*.efi
|
||||
@ -281,6 +332,10 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/vendor-directory.conf
|
||||
%config(noreplace)%{_sysconfdir}/pki/fwupd
|
||||
%{_sysconfdir}/pki/fwupd-metadata
|
||||
%if 0%{?have_msr}
|
||||
%{_sysconfdir}/modules-load.d/fwupd-msr.conf
|
||||
%endif
|
||||
%{_sysconfdir}/modules-load.d/fwupd-platform-integrity.conf
|
||||
%{_datadir}/dbus-1/system.d/org.freedesktop.fwupd.conf
|
||||
%{_datadir}/bash-completion/completions/fwupdmgr
|
||||
%{_datadir}/bash-completion/completions/fwupdtool
|
||||
@ -328,12 +383,17 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
/usr/lib/udev/rules.d/*.rules
|
||||
/usr/lib/systemd/system-shutdown/fwupd.shutdown
|
||||
%dir %{_libdir}/fwupd-plugins-3
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_acpi_dmar.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_acpi_facp.so
|
||||
%{_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_bcm57xx.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_bios.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_ccgx.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_colorhug.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_coreboot.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_cros_ec.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_csr.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_cpu.so
|
||||
%if 0%{?have_dell}
|
||||
@ -343,20 +403,28 @@ 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_elantp.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_emmc.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_ep963x.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_fastboot.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_flashrom.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_fresco_pd.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_iommu.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_jabra.so
|
||||
%if 0%{?have_modem_manager}
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_modem_manager.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_lockdown.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_sleep.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_swap.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_linux_tainted.so
|
||||
%if 0%{?have_msr}
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_msr.so
|
||||
%endif
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_nitrokey.so
|
||||
%if 0%{?have_uefi}
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_nvme.so
|
||||
%endif
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_optionrom.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_pci_bcr.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_pci_mei.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_platform_integrity.so
|
||||
%if 0%{?have_redfish}
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_redfish.so
|
||||
%endif
|
||||
@ -390,11 +458,21 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_vli.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_wacom_raw.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_wacom_usb.so
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_goodixmoc.so
|
||||
%ghost %{_localstatedir}/lib/fwupd/gnupg
|
||||
%if 0%{?have_uefi}
|
||||
%{_datadir}/locale/*/LC_IMAGES/fwupd*
|
||||
%endif
|
||||
|
||||
%if 0%{?have_modem_manager}
|
||||
%files plugin-modem-manager
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_modem_manager.so
|
||||
%endif
|
||||
%if 0%{?have_flashrom}
|
||||
%files plugin-flashrom
|
||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_flashrom.so
|
||||
%endif
|
||||
|
||||
%files devel
|
||||
%{_datadir}/gir-1.0/Fwupd-2.0.gir
|
||||
%{_datadir}/gir-1.0/FwupdPlugin-1.0.gir
|
||||
@ -405,14 +483,17 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
||||
%{_libdir}/pkgconfig/fwupd.pc
|
||||
%{_libdir}/pkgconfig/fwupdplugin.pc
|
||||
|
||||
%if 0%{?enable_tests}
|
||||
%files tests
|
||||
%dir %{_datadir}/installed-tests/fwupd
|
||||
%{_datadir}/installed-tests/fwupd/fwupd-tests.xml
|
||||
%{_datadir}/installed-tests/fwupd/*.test
|
||||
%{_datadir}/installed-tests/fwupd/*.cab
|
||||
%{_datadir}/installed-tests/fwupd/*.sh
|
||||
%{_libexecdir}/installed-tests/fwupd/*
|
||||
%dir %{_sysconfdir}/fwupd/remotes.d
|
||||
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/fwupd-tests.conf
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* #LONGDATE# Richard Hughes <richard@hughsie.com> #VERSION#-0.#BUILD##ALPHATAG#
|
||||
|
||||
@ -4,23 +4,5 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
|
||||
# VIA USB 3.0 VL811 Hub
|
||||
SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0810", ENV{FWUPD_GUID}="adbb9034-b577-42c2-a661-1ee4f49ef64c", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL811 Hub"
|
||||
|
||||
# VIA USB 3.0 VL811+ Hub
|
||||
SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0811", ENV{FWUPD_GUID}="54f84d05-c917-4c50-8b35-44feabaaa323", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL811+ Hub"
|
||||
|
||||
# VIA USB 3.0 VL812 Hub
|
||||
SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0812", ENV{FWUPD_GUID}="cd0314ec-b80f-4d1a-a24f-c409183a8b2d", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL812 Hub"
|
||||
|
||||
# VIA USB 3.0 VL812 B2 Hub
|
||||
SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="2812", ENV{FWUPD_GUID}="26470009-97a8-4028-867a-bbbac6ee7bf0", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL812 B2 Hub"
|
||||
|
||||
ENV{FWUPD_GUID}=="*?", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id"
|
||||
ENV{FWUPD_GUID}=="*?", ENV{ID_MODEL_FROM_DATABASE}=="", IMPORT{builtin}="hwdb --subsystem=usb"
|
||||
|
||||
# PCI cards with ROM
|
||||
SUBSYSTEM=="pci", TEST=="/sys$devpath/rom", ENV{FWUPD_GUID}="$attr{vendor}:$attr{device}"
|
||||
|
||||
# NVMe hardware
|
||||
SUBSYSTEM=="nvme", ENV{ID_VENDOR_FROM_DATABASE}=="", IMPORT{builtin}="hwdb --subsystem=pci"
|
||||
|
||||
@ -2,6 +2,7 @@ _fwupdagent_cmd_list=(
|
||||
'get-devices'
|
||||
'get-updates'
|
||||
'get-upgrades'
|
||||
'security'
|
||||
)
|
||||
|
||||
_fwupdagent_opts=(
|
||||
|
||||
@ -18,13 +18,16 @@ _fwupdmgr_cmd_list=(
|
||||
'get-topology'
|
||||
'get-updates'
|
||||
'get-upgrades'
|
||||
'get-plugins'
|
||||
'install'
|
||||
'modify-config'
|
||||
'modify-remote'
|
||||
'reinstall'
|
||||
'refresh'
|
||||
'report-history'
|
||||
'security'
|
||||
'set-approved-firmware'
|
||||
'switch-branch'
|
||||
'unlock'
|
||||
'unblock-firmware'
|
||||
'update'
|
||||
@ -39,6 +42,7 @@ _fwupdmgr_opts=(
|
||||
'--offline'
|
||||
'--allow-reinstall'
|
||||
'--allow-older'
|
||||
'--allow-branch-switch'
|
||||
'--force'
|
||||
'--assume-yes'
|
||||
'--no-history'
|
||||
@ -46,10 +50,11 @@ _fwupdmgr_opts=(
|
||||
'--no-metadata-check'
|
||||
'--no-reboot-check'
|
||||
'--no-safety-check'
|
||||
'--show-all-devices'
|
||||
'--show-all'
|
||||
'--sign'
|
||||
'--filter'
|
||||
'--disable-ssl-strict'
|
||||
'--ignore-power'
|
||||
)
|
||||
|
||||
_show_filters()
|
||||
@ -97,7 +102,7 @@ _fwupdmgr()
|
||||
esac
|
||||
|
||||
case $command in
|
||||
activate|clear-results|downgrade|get-releases|get-results|unlock|verify|verify-update)
|
||||
activate|clear-results|downgrade|get-releases|get-results|unlock|verify|verify-update|get-updates|switch-branch)
|
||||
if [[ "$prev" = "$command" ]]; then
|
||||
_show_device_ids
|
||||
else
|
||||
|
||||
@ -4,7 +4,9 @@ _fwupdtool_cmd_list=(
|
||||
'esp-list'
|
||||
'esp-mount'
|
||||
'esp-unmount'
|
||||
'firmware-build'
|
||||
'firmware-convert'
|
||||
'firmware-extract'
|
||||
'firmware-parse'
|
||||
'get-updates'
|
||||
'get-upgrades'
|
||||
@ -23,14 +25,18 @@ _fwupdtool_cmd_list=(
|
||||
'install-blob'
|
||||
'monitor'
|
||||
'reinstall'
|
||||
'security'
|
||||
'switch-branch'
|
||||
'self-sign'
|
||||
'smbios-dump'
|
||||
'attach'
|
||||
'detach'
|
||||
'firmware-read'
|
||||
'firmware-dump'
|
||||
'refresh'
|
||||
'verify-update'
|
||||
'watch'
|
||||
'unbind-driver'
|
||||
'bind-driver'
|
||||
)
|
||||
|
||||
_fwupdtool_opts=(
|
||||
@ -39,13 +45,16 @@ _fwupdtool_opts=(
|
||||
'--allow-reinstall'
|
||||
'--allow-older'
|
||||
'--force'
|
||||
'--show-all-devices'
|
||||
'--plugin-whitelist'
|
||||
'--show-all'
|
||||
'--plugins'
|
||||
'--prepare'
|
||||
'--cleanup'
|
||||
'--filter'
|
||||
'--disable-ssl-strict'
|
||||
'--no-safety-check'
|
||||
'--ignore-checksum'
|
||||
'--ignore-vid-pid'
|
||||
'--ignore-power'
|
||||
)
|
||||
|
||||
_show_filters()
|
||||
@ -84,7 +93,7 @@ _fwupdtool()
|
||||
command=${COMP_WORDS[1]}
|
||||
|
||||
case $prev in
|
||||
--plugin-whitelist)
|
||||
--plugins)
|
||||
_show_plugins
|
||||
return 0
|
||||
;;
|
||||
@ -95,7 +104,7 @@ _fwupdtool()
|
||||
esac
|
||||
|
||||
case $command in
|
||||
get-details|install|install-blob|firmware-read)
|
||||
get-details|install|install-blob|firmware-dump)
|
||||
#find files
|
||||
if [[ "$prev" = "$command" ]]; then
|
||||
_filedir
|
||||
@ -104,7 +113,7 @@ _fwupdtool()
|
||||
_show_modifiers
|
||||
fi
|
||||
;;
|
||||
attach|detach|activate|verify-update|reinstall)
|
||||
attach|detach|activate|verify-update|reinstall|get-updates)
|
||||
if [[ "$prev" = "$command" ]]; then
|
||||
_show_device_ids
|
||||
#modifiers
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
[fwupd]
|
||||
|
||||
# Allow blacklisting specific devices by their GUID
|
||||
# Allow blocking specific devices by their GUID
|
||||
# Uses semicolons as delimiter
|
||||
BlacklistDevices=
|
||||
DisabledDevices=
|
||||
|
||||
# Allow blacklisting specific plugins
|
||||
# Allow blocking specific plugins
|
||||
# Uses semicolons as delimiter
|
||||
BlacklistPlugins=test;invalid
|
||||
DisabledPlugins=test;invalid
|
||||
|
||||
# Maximum archive size that can be loaded in Mb, with 0 for the default
|
||||
ArchiveSizeMax=0
|
||||
|
||||
12
data/device-tests/devices/broadcom-bcm5719.json
Normal file
12
data/device-tests/devices/broadcom-bcm5719.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "NetXtreme BCM5719",
|
||||
"guids": [
|
||||
"ec5b8a9e-973b-58cc-935b-8322fabaebe9"
|
||||
],
|
||||
"releases": [
|
||||
{
|
||||
"version": "0.4.44",
|
||||
"file": "dfbb6529d3f7051497cc7e736848b5b6e276ff93b39bc765948663606dc87c25-bcm5719-0.4.44.cab"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
data/device-tests/devices/lenovo-40au0065-vli-tier1.json
Normal file
16
data/device-tests/devices/lenovo-40au0065-vli-tier1.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Lenovo USB-C Mini Dock [VL817]",
|
||||
"guids": [
|
||||
"f281c1df-c3d5-5f8a-984d-e9548ffc95fe"
|
||||
],
|
||||
"releases": [
|
||||
{
|
||||
"version": "4.154",
|
||||
"file": "c782946a9cf743abc37edefe35dec1b8b2d2a88b29f7058091b0a7ae3fa38e49-Lenovo-Mini_Dock_New.cab"
|
||||
},
|
||||
{
|
||||
"version": "4.94",
|
||||
"file": "39da9917934ce162baefa3a67adfccd338bfd054933d6c40c0c887ab0d48e83f-Lenovo-Mini_Dock_Old.cab"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
data/device-tests/devices/lenovo-40au0065-vli-tier2.json
Normal file
16
data/device-tests/devices/lenovo-40au0065-vli-tier2.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Lenovo USB-C Mini Dock [VL211]",
|
||||
"guids": [
|
||||
"d636c717-44c4-5fcf-9d7f-b96f9c5f6608"
|
||||
],
|
||||
"releases": [
|
||||
{
|
||||
"version": "4.43",
|
||||
"file": "c782946a9cf743abc37edefe35dec1b8b2d2a88b29f7058091b0a7ae3fa38e49-Lenovo-Mini_Dock_New.cab"
|
||||
},
|
||||
{
|
||||
"version": "4.33",
|
||||
"file": "39da9917934ce162baefa3a67adfccd338bfd054933d6c40c0c887ab0d48e83f-Lenovo-Mini_Dock_Old.cab"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
data/device-tests/devices/lenovo-40au0065-vli-tier3.json
Normal file
16
data/device-tests/devices/lenovo-40au0065-vli-tier3.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Lenovo USB-C Mini Dock [VL103]",
|
||||
"guids": [
|
||||
"3ae6610b-5c33-5714-96e3-05735eb9b2a5"
|
||||
],
|
||||
"releases": [
|
||||
{
|
||||
"version": "138.4.24.38",
|
||||
"file": "c782946a9cf743abc37edefe35dec1b8b2d2a88b29f7058091b0a7ae3fa38e49-Lenovo-Mini_Dock_New.cab"
|
||||
},
|
||||
{
|
||||
"version": "138.4.23.38",
|
||||
"file": "39da9917934ce162baefa3a67adfccd338bfd054933d6c40c0c887ab0d48e83f-Lenovo-Mini_Dock_Old.cab"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -18,7 +18,8 @@ complete -c fwupdmgr -l version -d 'Show client and daemon versions'
|
||||
complete -c fwupdmgr -l offline -d 'Schedule installation for next reboot when possible'
|
||||
complete -c fwupdmgr -l allow-reinstall -d 'Allow reinstalling existing firmware versions'
|
||||
complete -c fwupdmgr -l allow-older -d 'Allow downgrading firmware versions'
|
||||
complete -c fwupdmgr -l force -d 'Override warnings and force the action'
|
||||
complete -c fwupdmgr -l allow-branch-switch -d 'Allow switching firmware branch'
|
||||
complete -c fwupdmgr -l force -d 'Force the action by relaxing some runtime checks'
|
||||
complete -c fwupdmgr -s y -l assume-yes -d 'Answer yes to all questions'
|
||||
complete -c fwupdmgr -l sign -d 'Sign the uploaded data with the client certificate'
|
||||
complete -c fwupdmgr -l no-unreported-check -d 'Do not check for unreported history'
|
||||
@ -26,12 +27,14 @@ complete -c fwupdmgr -l no-metadata-check -d 'Do not check for old metadata'
|
||||
complete -c fwupdmgr -l no-reboot-check -d 'Do not check for reboot after update'
|
||||
complete -c fwupdmgr -l no-safety-check -d 'Do not perform device safety checks'
|
||||
complete -c fwupdmgr -l no-history -d 'Do not write to the history database'
|
||||
complete -c fwupdmgr -l show-all-devices -d 'Show devices that are not updatable'
|
||||
complete -c fwupdmgr -l disable-ssl-strict -d 'Ignore SSL strict checks when downloading files'
|
||||
complete -c fwupdmgr -l show-all -d 'Show all results'
|
||||
complete -c fwupdmgr -l disable-ssl-strict -d 'Ignore SSL strict checks when downloading'
|
||||
complete -c fwupdmgr -l filter -d 'Filter with a set of device flags'
|
||||
complete -c fwupdmgr -l ignore-power -d 'Ignore requirement of external power source'
|
||||
|
||||
# complete subcommands
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a activate -d 'Activate devices'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a block-firmware -d 'Blocks a specific firmware from being installed'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a clear-history -d 'Erase all firmware update history'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a clear-offline -d 'Clears any updates scheduled to be updated offline'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a clear-results -d 'Clears the results from the last update'
|
||||
@ -39,6 +42,7 @@ complete -c fwupdmgr -n '__fish_use_subcommand' -x -a disable-remote -d 'Disable
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a downgrade -d 'Downgrades the firmware on a device'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a enable-remote -d 'Enables a given remote'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-approved-firmware -d 'Gets the list of approved firmware'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-blocked-firmware -d 'Gets the list of blocked firmware'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-details -d 'Gets details about a firmware file'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-devices -d 'Get all devices that support firmware updates'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-history -d 'Show history of firmware updates'
|
||||
@ -47,19 +51,22 @@ complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-remotes -d 'Gets the c
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-results -d 'Gets the results from the last update'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a get-updates -d 'Gets the list of updates for connected hardware'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a install -d 'Install a firmware file on this hardware'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a modify-config -d 'Modifies a daemon configuration value.'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a modify-config -d 'Modifies a daemon configuration value'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a modify-remote -d 'Modifies a given remote'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a refresh -d 'Refresh metadata from remote server'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a reinstall -d 'Reinstall current firmware on the device.'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a reinstall -d 'Reinstall current firmware on the device'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a report-history -d 'Share firmware history with the developers'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a set-approved-firmware -d 'Sets the list of approved firmware.'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a security -d 'Gets the host security attributes'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a set-approved-firmware -d 'Sets the list of approved firmware'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a switch-branch -d 'Switch the firmware branch on the device'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a unblock-firmware -d 'Unblocks a specific firmware from being installed'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a unlock -d 'Unlocks the device for firmware access'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a update -d 'Updates all firmware to latest versions available'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a verify -d 'Checks cryptographic hash matches firmware'
|
||||
complete -c fwupdmgr -n '__fish_use_subcommand' -x -a verify-update -d 'Update the stored cryptographic hash with current ROM contents'
|
||||
|
||||
# commands exclusively consuming device IDs
|
||||
set -l deviceid_consumers activate clear-results downgrade get-releases get-results reinstall unlock update verify verify-update
|
||||
set -l deviceid_consumers activate clear-results downgrade get-releases get-results get-updates reinstall switch-branch unlock update verify verify-update
|
||||
# complete device IDs
|
||||
complete -c fwupdmgr -n "__fish_seen_subcommand_from $deviceid_consumers" -x -a "(__fish_fwupdmgr_devices)"
|
||||
# complete files and device IDs
|
||||
|
||||
@ -4,4 +4,8 @@
|
||||
[ -f @localstatedir@/lib/fwupd/pending.db ] || exit 0
|
||||
|
||||
# activate firmware when we have a read-only filesysten
|
||||
@bindir@/fwupdtool activate
|
||||
if !@bindir@/fwupdtool activate; then
|
||||
ret=$?
|
||||
[ "$ret" -eq "2" ] && exit 0
|
||||
exit $ret
|
||||
fi
|
||||
|
||||
@ -9,7 +9,7 @@ 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`
|
||||
1. Modify `/etc/fwupd/daemon.conf` to remove the `test` plugin from `DisabledPlugins`
|
||||
```
|
||||
# sed "s,^Enabled=false,Enabled=true," -i /etc/fwupd/remotes.d/fwupd-tests.conf
|
||||
```
|
||||
|
||||
@ -1 +1 @@
|
||||
fakedevice123 -n
|
||||
0x1020003
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v2.0.14 (GNU/Linux)
|
||||
Version: GnuPG v2.0.22 (GNU/Linux)
|
||||
|
||||
iQEcBAABAgAGBQJZQqynAAoJEEim2A5FOLrCVcsH/3Vn56wSeRCol0rOeXvoupg2
|
||||
qpTAmqUvlubv2vX1IDbcL/lHIIEAHAlN/4LRHUh+Om0T7bMKX1uSfmcgCyUTBxl0
|
||||
fm3TfXRhybi9VtZ5ZpwWxGsFsCNC9eOU0i8tB1zp9e9KjDPiYnluFkTRQ+Aw3u1u
|
||||
tKBMTk6Z+VQlIUFrsveFYmPMGDkvn8AWbJCz6E4jc8can/lP/9djSi91mCqtEq/j
|
||||
YTBz4OwfU80MRrSgoxykHgcB1RiT43ywfKlpHQzcO+rqCV7rv7LkXIEzBdWRZstk
|
||||
XmboCnEKuMxtr+vXlGqU4n+upQkYur3Vs+07ut1OewQnJT3eeZbAH0mr42MVf7c=
|
||||
=MQJe
|
||||
iQEcBAABAgAGBQJfey1HAAoJEEim2A5FOLrCn2MIAK6BnVojGYSwHVpZm58b05Xs
|
||||
rNqozg5pvfDfB0Bde1S0T/4TlDEnJNUku0Gz5IFNbR3ENT5VnJgBkE5xa8Rmv6cy
|
||||
Gm30CmX+UE1E8qK4BVhUdbNN8bEmeMtzUMK2KfpwMXlIqcpSjpln76PQIxMHj+3P
|
||||
600bkcppkLEKhiOo+THNhiHxPYJ+wjSSPm3paeMmUuApIvP4YFH8uQ5qkKLdLDVI
|
||||
V5QOx3O5P3avmHu936GILG9EwV3TkR1eNOe33OqtrGvpoMTcsxUF0Wc/qmUD066d
|
||||
c9hkTe01paQoN0HW/RMgrIaMnLFwK2mBcwySOo6TU9MIyQfDmLGN3u12nCrmRH8=
|
||||
=Rq70
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright 2017 Richard Hughes <richard@hughsie.com> -->
|
||||
<component type="firmware">
|
||||
<id>fakedevice.firmware</id>
|
||||
<name>FakeDevice Firmware</name>
|
||||
<id>org.fwupd.fakedevice.firmware</id>
|
||||
<name>FakeDevice</name>
|
||||
<summary>Firmware for the ACME Corp Integrated Webcam</summary>
|
||||
<description>
|
||||
<p>
|
||||
|
||||
@ -1 +1 @@
|
||||
fakedevice124 -n
|
||||
0x1020004
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v2.0.14 (GNU/Linux)
|
||||
Version: GnuPG v2.0.22 (GNU/Linux)
|
||||
|
||||
iQEcBAABAgAGBQJZQqy9AAoJEEim2A5FOLrCRLEH/27k0IfUtfGS8T5CPTvwW8kF
|
||||
Cf6EIzw+2HgjbxLdeMNHwiHCBdIR58z44O1I9Xy6gY1vF3H4kKft6oBAUFDH0Ja5
|
||||
YpQHXMZVSNdnwdg57cyC67kLOycHTSDlLXKB74tU3R4J8xntA1cY+DSYmCs2uAjq
|
||||
3T3ExfjrX6PGbRhbNr8vBUQckCxcGvEZNOws2081mTosEQNpIxFyJ2tbbKLR60d0
|
||||
5O/UDjNEYfUFCGy7MycXePEIOR+rO6KuEQ3vjJnv80UKE8msFxJTM1iKwct+B2HI
|
||||
JNecCsx14BGDXCiE0Xc0heunfWiBHmNS2lymrHsU2Z82VrFqP0obD2cm64PBf0Y=
|
||||
=Wsq/
|
||||
iQEcBAABAgAGBQJfey2FAAoJEEim2A5FOLrCl88IAKCggwAz3qBrBfrc91sYHCq5
|
||||
OthMyftOUTQ4JpfISY38k20pwFEhsSHKdKAYDKEVO2jopw+Cr9oTyFycWK20R2lz
|
||||
tUn4e1EF8zQ29OLxGbvgGlP5/4vPJ2Cv5ujkub6LtNBrOMkNJ6+bB6G8nJZRTElU
|
||||
e3wi9+E9oKPBgP40A/y79pzPiFMxXl1piYjU3JNeofd3nbtmyRqb6VAs9exQ94+p
|
||||
CMWWZaJ9igxSAsQiE/NxZpO8qgG3KEmsW7yXRiaIe6xHxb49+JQdjxqS8Oc/C9sX
|
||||
FSiVHDPzlUegZtcRWZy2zeSNTqmu8vzNSei0xEaLCaQ6PO+pQibxS2VZI/jDLdQ=
|
||||
=Gha4
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright 2017 Richard Hughes <richard@hughsie.com> -->
|
||||
<component type="firmware">
|
||||
<id>fakedevice.firmware</id>
|
||||
<name>FakeDevice Firmware</name>
|
||||
<id>org.fwupd.fakedevice.firmware</id>
|
||||
<name>FakeDevice</name>
|
||||
<summary>Firmware for the ACME Corp Integrated Webcam</summary>
|
||||
<description>
|
||||
<p>
|
||||
|
||||
27
data/installed-tests/fwupd.sh
Executable file
27
data/installed-tests/fwupd.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
exec 2>&1
|
||||
dirname=`dirname $0`
|
||||
|
||||
run_test()
|
||||
{
|
||||
$dirname/$1
|
||||
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
|
||||
}
|
||||
|
||||
run_test acpi-dmar-self-test
|
||||
run_test acpi-facp-self-test
|
||||
run_test ata-self-test
|
||||
run_test nitrokey-self-test
|
||||
run_test linux-swap-self-test
|
||||
run_test nvme-self-test
|
||||
run_test wacom-usb-self-test
|
||||
run_test redfish-self-test
|
||||
run_test optionrom-self-test
|
||||
run_test vli-self-test
|
||||
run_test uefi-dbx-self-test
|
||||
run_test synaptics-prometheus-self-test
|
||||
run_test dfu-self-test
|
||||
|
||||
# success!
|
||||
exit 0
|
||||
3
data/installed-tests/fwupd.test.in
Normal file
3
data/installed-tests/fwupd.test.in
Normal file
@ -0,0 +1,3 @@
|
||||
[Test]
|
||||
Type=session
|
||||
Exec=sh -c "@installedtestsbindir@/fwupd.sh"
|
||||
@ -43,7 +43,7 @@ rc=$?; if [[ $rc != 0 ]]; then error $rc; fi
|
||||
|
||||
# ---
|
||||
echo "Installing test firmware..."
|
||||
fwupdmgr install ${dirname}/fakedevice124.cab
|
||||
fwupdmgr update $device -y
|
||||
rc=$?; if [[ $rc != 0 ]]; then error $rc; fi
|
||||
|
||||
# ---
|
||||
@ -58,7 +58,7 @@ rc=$?; if [[ $rc != 0 ]]; then error $rc; fi
|
||||
|
||||
# ---
|
||||
echo "Downgrading to older release (requires network access)"
|
||||
fwupdmgr downgrade $device
|
||||
fwupdmgr downgrade $device -y
|
||||
rc=$?; if [[ $rc != 0 ]]; then error $rc; fi
|
||||
|
||||
# ---
|
||||
@ -68,7 +68,7 @@ rc=$?; if [[ $rc != 2 ]]; then error $rc; fi
|
||||
|
||||
# ---
|
||||
echo "Updating all devices to latest release (requires network access)"
|
||||
fwupdmgr --no-unreported-check --no-metadata-check --no-reboot-check update
|
||||
fwupdmgr --no-unreported-check --no-metadata-check --no-reboot-check update -y
|
||||
rc=$?; if [[ $rc != 0 ]]; then error $rc; fi
|
||||
|
||||
# ---
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
installed_test_datadir = join_paths(datadir, 'installed-tests', 'fwupd')
|
||||
|
||||
con2 = configuration_data()
|
||||
con2.set('installedtestsdir', installed_test_datadir)
|
||||
con2.set('installedtestsbindir', installed_test_bindir)
|
||||
con2.set('bindir', bindir)
|
||||
|
||||
configure_file(
|
||||
@ -12,6 +11,14 @@ configure_file(
|
||||
install_dir: installed_test_datadir,
|
||||
)
|
||||
|
||||
configure_file(
|
||||
input : 'fwupd.test.in',
|
||||
output : 'fwupd.test',
|
||||
configuration : con2,
|
||||
install: true,
|
||||
install_dir: installed_test_datadir,
|
||||
)
|
||||
|
||||
install_data([
|
||||
'fwupdmgr.sh',
|
||||
'fwupd-tests.xml',
|
||||
@ -19,6 +26,12 @@ install_data([
|
||||
install_dir : installed_test_datadir,
|
||||
)
|
||||
|
||||
install_data([
|
||||
'fwupd.sh',
|
||||
],
|
||||
install_dir : installed_test_bindir,
|
||||
)
|
||||
|
||||
custom_target('installed-cab123',
|
||||
input : [
|
||||
'fakedevice123.bin',
|
||||
|
||||
@ -30,97 +30,82 @@
|
||||
</content_rating>
|
||||
<provides>
|
||||
<binary>fwupdmgr</binary>
|
||||
<binary>fwupdtool</binary>
|
||||
<binary>fwupdtpmevlog</binary>
|
||||
<binary>fwupdagent</binary>
|
||||
</provides>
|
||||
<releases>
|
||||
<release version="1.4.6" date="2020-09-07">
|
||||
<release version="1.5.1" date="2020-11-02">
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
<ul>
|
||||
<li>Add a re-implementation of the rhboot dbxtool</li>
|
||||
<li>Add commands to fwupdtool for interacting with the ESP</li>
|
||||
<li>Add support for the LabTop Mk IV</li>
|
||||
<li>Add support for the Realtek RTD21XX I²C protocol</li>
|
||||
<li>Add X-Configuration category to use for dbx updates</li>
|
||||
<li>Allow blocking specific firmware releases by checksum</li>
|
||||
<li>Allow plugins to set remove delay only on the child</li>
|
||||
<li>Allow updating the dbx, validating it is safe to apply</li>
|
||||
<li>Support download of large DFU firmware</li>
|
||||
<li>Support polling the status from device in dfuManifest state</li>
|
||||
<li>Include the amount of NVRAM size in use in the LVFS failure report</li>
|
||||
</ul>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
<ul>
|
||||
<li>Add missing Synaptics Prometheus GUIDs for ConfigId</li>
|
||||
<li>Allow DFU device to attach to runtime without a bus reset</li>
|
||||
<li>Be more careful doing multiple writes to the same device</li>
|
||||
<li>Cancel the file monitor before disposal to avoid a potential deadlock</li>
|
||||
<li>Correctly label the vebdor for more NVMe devices</li>
|
||||
<li>Specify a remove delay for Poly USB Cameras</li>
|
||||
<li>Use newer libxmlb features to properly display more AppStream markup</li>
|
||||
<li>Delete unused EFI variables when deploying firmware</li>
|
||||
<li>Fix probe warning for the Logitech Unifying device</li>
|
||||
<li>Make bcm57xx hotplug more reliable</li>
|
||||
<li>Recognize authorized thunderbolt value of 2</li>
|
||||
<li>Remove the duplicate parent-child data in FwupdDevice and FuDevice</li>
|
||||
<li>Show a less scary fwupdate output for devices without info</li>
|
||||
<li>Show a link to discover more information about a specific plugin failure</li>
|
||||
<li>Use a different Device ID for the OptionROM devices</li>
|
||||
<li>Use UDisks to find out if swap devices are encrypted</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.4.5" date="2020-07-30">
|
||||
<release version="1.5.0" date="2020-10-26">
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
<ul>
|
||||
<li>Add dual-image feature for VL103 backup firmware</li>
|
||||
<li>Add more CCGX hybrid dock support</li>
|
||||
<li>Add a compatible re-implementation of the rhboot dbxtool</li>
|
||||
<li>Add async versions of the library for GUI tools</li>
|
||||
<li>Add commands for interacting with the ESP to fwupdtool</li>
|
||||
<li>Add firmware-extract subcommand to fwupdtool</li>
|
||||
<li>Add FwupdPlugin so we can convey enumerated system errors to the end user</li>
|
||||
<li>Add plugin for Goodix fingerprint sensors</li>
|
||||
<li>Add plugin that can update the BCM5719 network adapter</li>
|
||||
<li>Add plugin to update Elan Touchpads using HID</li>
|
||||
<li>Add support for a delayed activation flow for Thunderbolt</li>
|
||||
<li>Add support for ChromeOS Quiche and Gingerbread</li>
|
||||
<li>Add support for Hyper hardware</li>
|
||||
<li>Add support for the Host Security ID</li>
|
||||
<li>Add support for ThunderBolt retimers</li>
|
||||
<li>Add switch-branch command to fwupdtool and fwupdmgr</li>
|
||||
<li>Allow blocking specific firmware releases by checksum</li>
|
||||
<li>Allow constructing a firmware with multiple images</li>
|
||||
<li>Allow firmware to require specific features from front-end clients</li>
|
||||
<li>Modernize the thunderbolt plugin for future hardware</li>
|
||||
<li>Support LVFS::UpdateImage in GUI clients</li>
|
||||
<li>Allow updating the dbx using the LVFS, validating it is safe to apply</li>
|
||||
<li>Include the HSI results and attributes in the uploaded report</li>
|
||||
<li>Support loading DMI data from DT systems</li>
|
||||
<li>Support LVFS::UpdateImage for GUI clients</li>
|
||||
</ul>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
<ul>
|
||||
<li>Be more defensive when remotes are missing required keys</li>
|
||||
<li>Check all AppStream components when verifying</li>
|
||||
<li>Check for free space after cleaning up ESP</li>
|
||||
<li>Fix TPM PCR0 calculation</li>
|
||||
<li>Only show UpdateMessage when state is success</li>
|
||||
<li>Read the modem vendor ID correctly</li>
|
||||
<li>Set the runtime version to 0.0.0 for pre-1.0.0 Thelio Io firmware</li>
|
||||
<li>Support compiling libqmi-glib 1.26.0 and later</li>
|
||||
<li>Use the GPIOB reset for the MiniDock VL103</li>
|
||||
<li>Wait for the root device to be replugged when updating the MSP430</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.4.4" date="2020-06-10">
|
||||
<description>
|
||||
<p>This release fixes the following regression:</p>
|
||||
<ul>
|
||||
<li>Fix refreshing when checking for downgraded metadata</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.4.3" date="2020-06-09">
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
<ul>
|
||||
<li>Add support for HP DMC dock devices</li>
|
||||
</ul>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
<ul>
|
||||
<li>Always enforce the metadata signature has a valid timestamp</li>
|
||||
<li>Capture the dock SKU in metadata</li>
|
||||
<li>Check the device requirements when returning from GetDetails</li>
|
||||
<li>Force the prometheus minor version from 0x02 to 0x01</li>
|
||||
<li>Prevent Dell dock updates to occur via synaptics-mst plugin</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.4.2" date="2020-05-18">
|
||||
<description>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
<ul>
|
||||
<li>Add several more ATA OUI quirks</li>
|
||||
<li>Avoid communicating with DFU devices when bitManifestationTolerant is off</li>
|
||||
<li>Correct the display of final calculated PCRs</li>
|
||||
<li>Delay activation for Dell Thunderbolt updates</li>
|
||||
<li>Do not use synaptics-rmi on the Dell K12A</li>
|
||||
<li>Fix switching wacom-raw to bootloader mode</li>
|
||||
<li>Switch the default of EnumerateAllDevices to false</li>
|
||||
<li>Use GPIOB to reset the VL817 found in two Lenovo products</li>
|
||||
<li>Allow compiling the daemon without polkit support</li>
|
||||
<li>Always look at all TPM eventlog supported algorithms</li>
|
||||
<li>Change all instances of master/slave to initiator/target</li>
|
||||
<li>Correctly order devices when using logical parents</li>
|
||||
<li>Do not dedupe NVMe or VLI PD devices</li>
|
||||
<li>Do not expose the VLI shared-SPI devices on the USB2 recovery device</li>
|
||||
<li>Do not fix up the version on post-update mismatch</li>
|
||||
<li>Download the metadata first when using 'fwupdtool refresh'</li>
|
||||
<li>Drop efivar dependency</li>
|
||||
<li>Drop support for ThunderBolt force power due to hardware issues</li>
|
||||
<li>Fix setting BootNext correctly when multiple updates are scheduled</li>
|
||||
<li>Fix the topology of the audio device on the Lenovo TR dock</li>
|
||||
<li>Make return code different for get-updates with no updates</li>
|
||||
<li>Make specific authorizations also imply others</li>
|
||||
<li>Make TPM support more optional</li>
|
||||
<li>Parse the HEX version before comparing for equality</li>
|
||||
<li>Prevent dell-dock updates to occur via synaptics-mst plugin</li>
|
||||
<li>Record the UEFI failure in more cases</li>
|
||||
<li>Retry the HID SetReport to fix flashing the TB3 dock</li>
|
||||
<li>Show an error when a plugin is missing dependencies</li>
|
||||
<li>Use libxmlb bound parameters to speed up the device verification</li>
|
||||
<li>Use pkttyagent to request user passwords if running without GUI</li>
|
||||
<li>Use the JCat file to select the metadata file</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
@ -195,6 +180,32 @@
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.3.9" date="2020-03-04">
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
<ul>
|
||||
<li>Added completion script for fish shell</li>
|
||||
<li>Inihbit all power management actions using logind when updating</li>
|
||||
</ul>
|
||||
<p>This release fixes the following bugs:</p>
|
||||
<ul>
|
||||
<li>Always check for PLAIN when doing vercmp() operations</li>
|
||||
<li>Always return AppStream markup for remote agreements</li>
|
||||
<li>Apply UEFI capsule update even with single valid capsule</li>
|
||||
<li>Check the device protocol before de-duping devices</li>
|
||||
<li>Copy the version and format from donor device in get-details</li>
|
||||
<li>Correctly append the release to devices in `fwupdtool get-details`</li>
|
||||
<li>Decrease minimum battery requirement to 10%</li>
|
||||
<li>Discard the reason upgrades aren't available</li>
|
||||
<li>Do not fail loading in /etc/machine-id is not available</li>
|
||||
<li>Fix a critical warning when installing some firmware</li>
|
||||
<li>For the `get-details` command make sure to always show devices</li>
|
||||
<li>Set the MSP430 version format to pair</li>
|
||||
<li>Switch off the ATA verbose logging by default</li>
|
||||
<li>Use unknown for version format by default on get-details</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="1.3.8" date="2020-02-13">
|
||||
<description>
|
||||
<p>This release adds the following features:</p>
|
||||
@ -513,7 +524,7 @@
|
||||
<li>Do not fail to start the daemon if tpm2_pcrlist hangs</li>
|
||||
<li>Do not fail when scheduling more than one update to be run offline</li>
|
||||
<li>Do not let failing to find DBus prevent fwuptool from starting</li>
|
||||
<li>Do not schedule an update on battery power if it requires AC power</li>
|
||||
<li>Do not schedule an update on battery power if it requires an external power source</li>
|
||||
<li>Include all device checksums in the LVFS report</li>
|
||||
<li>Rename the shimx64.efi binary for known broken firmware</li>
|
||||
<li>Upload the UPDATE_INFO entry for the UEFI UX capsule</li>
|
||||
|
||||
@ -5,6 +5,8 @@ Enabled=true
|
||||
Title=Linux Vendor Firmware Service
|
||||
MetadataURI=https://cdn.fwupd.org/downloads/firmware.xml.gz
|
||||
ReportURI=https://fwupd.org/lvfs/firmware/report
|
||||
SecurityReportURI=https://fwupd.org/lvfs/hsireports/upload
|
||||
OrderBefore=fwupd
|
||||
AutomaticReports=false
|
||||
AutomaticSecurityReports=false
|
||||
ApprovalRequired=false
|
||||
|
||||
1
data/tests/devicetree/base/ibm,firmware-versions/version
Normal file
1
data/tests/devicetree/base/ibm,firmware-versions/version
Normal file
@ -0,0 +1 @@
|
||||
1.2.3-4
|
||||
1
data/tests/devicetree/base/model
Normal file
1
data/tests/devicetree/base/model
Normal file
@ -0,0 +1 @@
|
||||
ColorHug
|
||||
1
data/tests/devicetree/base/model-name
Normal file
1
data/tests/devicetree/base/model-name
Normal file
@ -0,0 +1 @@
|
||||
To Be Filled By O.E.M.
|
||||
BIN
data/tests/devicetree/base/name
Normal file
BIN
data/tests/devicetree/base/name
Normal file
Binary file not shown.
1
data/tests/devicetree/base/vendor
Normal file
1
data/tests/devicetree/base/vendor
Normal file
@ -0,0 +1 @@
|
||||
Hughski Limited
|
||||
BIN
data/tests/devicetree/base/vpd/name
Normal file
BIN
data/tests/devicetree/base/vpd/name
Normal file
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
PCB-CH001
|
||||
@ -0,0 +1 @@
|
||||
Richard Hughes
|
||||
Binary file not shown.
BIN
data/tests/devicetree/base/vpd/root-node-vpd@a000/name
Normal file
BIN
data/tests/devicetree/base/vpd/root-node-vpd@a000/name
Normal file
Binary file not shown.
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
||||
fwupd (1.5.1-1) UNRELEASED; urgency=medium
|
||||
|
||||
* New upstream version (1.5.1)
|
||||
|
||||
-- Mario Limonciello <mario.limonciello@dell.com> Fri, 13 Nov 2020 09:42:10 -0600
|
||||
|
||||
fwupd (1.4.6-2) unstable; urgency=medium
|
||||
|
||||
* Add udisks2 to recommends
|
||||
|
||||
1
debian/control.in
vendored
1
debian/control.in
vendored
@ -49,6 +49,7 @@ Depends: ${misc:Depends},
|
||||
shared-mime-info
|
||||
Recommends: python3,
|
||||
bolt,
|
||||
secureboot-db,
|
||||
udisks2,
|
||||
fwupd-signed
|
||||
Provides: fwupdate
|
||||
|
||||
2
debian/fwupd-tests.install
vendored
2
debian/fwupd-tests.install
vendored
@ -3,6 +3,8 @@
|
||||
#find them. for more information see:
|
||||
#https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872458
|
||||
usr/share/installed-tests/*
|
||||
usr/libexec/installed-tests/fwupd/fwupd.sh
|
||||
usr/libexec/installed-tests/fwupd/*-self-test
|
||||
usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so
|
||||
usr/lib/*/fwupd-plugins-3/libfu_plugin_invalid.so
|
||||
debian/lintian/fwupd-tests usr/share/lintian/overrides
|
||||
|
||||
2
debian/fwupd-tests.postinst
vendored
2
debian/fwupd-tests.postinst
vendored
@ -7,7 +7,7 @@ set -e
|
||||
if [ "$1" = configure ] && [ -z "$2" ]; then
|
||||
if [ -f /etc/fwupd/daemon.conf ]; then
|
||||
if [ "$CI" = "true" ]; then
|
||||
sed "s,^BlacklistPlugins=test;invalid,BlacklistPlugins=," -i /etc/fwupd/daemon.conf
|
||||
sed "s,^DisabledPlugins=test;invalid,DisabledPlugins=," -i /etc/fwupd/daemon.conf
|
||||
else
|
||||
echo "To enable test suite, modify /etc/fwupd/daemon.conf"
|
||||
fi
|
||||
|
||||
2
debian/fwupd-tests.postrm
vendored
2
debian/fwupd-tests.postrm
vendored
@ -6,7 +6,7 @@ set -e
|
||||
if [ "$1" = remove -o "$1" = purge ]; then
|
||||
if [ -f /etc/fwupd/daemon.conf ]; then
|
||||
if [ "$CI" = "true" ]; then
|
||||
sed "s,^BlacklistPlugins=,BlacklistPlugins=test;invalid," -i /etc/fwupd/daemon.conf
|
||||
sed "s,^DisabledPlugins=,DisabledPlugins=test;invalid," -i /etc/fwupd/daemon.conf
|
||||
else
|
||||
echo "To disable test suite, modify /etc/fwupd/daemon.conf"
|
||||
fi
|
||||
|
||||
1
debian/fwupd.install
vendored
1
debian/fwupd.install
vendored
@ -9,6 +9,7 @@ usr/share/polkit-1/*
|
||||
usr/share/locale
|
||||
usr/share/metainfo/*
|
||||
usr/libexec/fwupd/fwupd
|
||||
usr/libexec/fwupd/fwupd-detect-cet
|
||||
usr/libexec/fwupd/fwupdoffline
|
||||
usr/share/man/man1/*
|
||||
lib/systemd/system/*
|
||||
|
||||
4
debian/lintian/fwupd
vendored
4
debian/lintian/fwupd
vendored
@ -9,3 +9,7 @@ fwupd: library-not-linked-against-libc usr/lib/*/fwupd-plugins-3/libfu_plugin_ue
|
||||
fwupd: executable-not-elf-or-script usr/libexec/fwupd/efi/*.efi
|
||||
fwupd: portable-executable-missing-security-features usr/libexec/fwupd/efi/*.efi SafeSEH
|
||||
fwupd: library-not-linked-against-libc usr/lib/*/fwupd-plugins-3/libfu_plugin_modem_manager.so
|
||||
fwupd: library-not-linked-against-libc usr/lib/*/fwupd-plugins-3/libfu_plugin_pci_bcr.so
|
||||
fwupd: library-not-linked-against-libc usr/lib/*/fwupd-plugins-3/libfu_plugin_pci_mei.so
|
||||
fwupd: library-not-linked-against-libc usr/lib/*/fwupd-plugins-3/libfu_plugin_iommu.so
|
||||
fwupd: library-not-linked-against-libc usr/lib/*/fwupd-plugins-3/libfu_plugin_msr.so
|
||||
|
||||
11
debian/rules
vendored
11
debian/rules
vendored
@ -14,9 +14,6 @@ ifneq ($(CI),)
|
||||
export CI=--werror --wrap-mode=default
|
||||
endif
|
||||
|
||||
regenerate_control:
|
||||
OS=debian-x86_64 ./contrib/ci/generate_debian.py
|
||||
|
||||
SB_STYLE := debian
|
||||
deb_version := $(shell dpkg-parsechangelog --show-field Version)
|
||||
export FLASHROM=-Dplugin_flashrom=false
|
||||
@ -47,9 +44,9 @@ override_dh_auto_configure:
|
||||
export DELL="-Dplugin_dell=false"; \
|
||||
fi; \
|
||||
if pkg-config --exists efivar; then \
|
||||
export UEFI="-Dplugin_uefi=true -Dplugin_redfish=true -Dplugin_nvme=true"; \
|
||||
export UEFI="-Dplugin_uefi=true -Dplugin_redfish=true -Dplugin_nvme=true -Dplugin_msr=true"; \
|
||||
else \
|
||||
export UEFI="-Dplugin_uefi=false -Dplugin_redfish=false -Dplugin_nvme=false"; \
|
||||
export UEFI="-Dplugin_uefi=false -Dplugin_redfish=false -Dplugin_nvme=false -Dplugin_msr=false"; \
|
||||
fi; \
|
||||
dh_auto_configure -- $$UEFI $$DELL $$FLASHROM $$CI -Dplugin_dummy=true -Dgtkdoc=true
|
||||
|
||||
@ -61,9 +58,7 @@ override_dh_install:
|
||||
if [ -d debian/tmp/usr/libexec/fwupd/efi/ ]; then \
|
||||
dh_install -pfwupd usr/libexec/fwupd/efi ;\
|
||||
fi
|
||||
if [ -z "$$CI" ]; then \
|
||||
dh_missing -a --fail-missing; \
|
||||
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
|
||||
|
||||
6
debian/tests/ci
vendored
6
debian/tests/ci
vendored
@ -1,5 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
sed "s,^BlacklistPlugins=.*,BlacklistPlugins=," -i /etc/fwupd/daemon.conf
|
||||
sed "s,^DisabledPlugins=.*,DisabledPlugins=," -i /etc/fwupd/daemon.conf
|
||||
sed "s,^VerboseDomains=.*,VerboseDomains=*," -i /etc/fwupd/daemon.conf
|
||||
gnome-desktop-testing-runner fwupd
|
||||
git clone https://github.com/fwupd/fwupd-test-firmware
|
||||
export G_TEST_SRCDIR=`pwd`/fwupd-test-firmware/installed-tests
|
||||
CI_NETWORK=true gnome-desktop-testing-runner fwupd
|
||||
|
||||
@ -26,8 +26,10 @@
|
||||
</para>
|
||||
</partintro>
|
||||
<xi:include href="xml/fwupd-client.xml"/>
|
||||
<xi:include href="xml/fwupd-client-sync.xml"/>
|
||||
<xi:include href="xml/fwupd-device.xml"/>
|
||||
<xi:include href="xml/fwupd-release.xml"/>
|
||||
<xi:include href="xml/fwupd-plugin.xml"/>
|
||||
<xi:include href="xml/fwupd-remote.xml"/>
|
||||
<xi:include href="xml/fwupd-error.xml"/>
|
||||
<xi:include href="xml/fwupd-enums.xml"/>
|
||||
@ -67,405 +69,10 @@
|
||||
<xi:include href="xml/fu-usb-device.xml"/>
|
||||
</reference>
|
||||
|
||||
<reference id="tutorial">
|
||||
<title>Plugin Tutorial</title>
|
||||
<partintro>
|
||||
<section>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
At the heart of fwupd is a plugin loader that gets run at startup,
|
||||
when devices get hotplugged and when updates are done.
|
||||
The idea is we have lots of small plugins that each do one thing, and
|
||||
are ordered by dependencies against each other at runtime.
|
||||
Using plugins we can add support for new hardware or new policies
|
||||
without making big changes all over the source tree.
|
||||
</para>
|
||||
<para>
|
||||
There are broadly 3 types of plugin methods:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">Mechanism</emphasis>: Upload binary data
|
||||
into a specific hardware device.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">Policy</emphasis>: Control the system when
|
||||
updates are happening, e.g. preventing the user from powering-off.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">Helpers</emphasis>: Providing more
|
||||
metadata about devices, for instance handling device quirks.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
In general, building things out-of-tree isn't something that we think is
|
||||
a very good idea; the API and ABI <emphasis>internal</emphasis> to fwupd is still
|
||||
changing and there's a huge benefit to getting plugins upstream where
|
||||
they can undergo review and be ported as the API adapts.
|
||||
For this reason we don't install the plugin headers onto the system,
|
||||
although you can of course just install the <code>.so</code> binary file
|
||||
manually.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A plugin only needs to define the vfuncs that are required, and the
|
||||
plugin name is taken automatically from the suffix of the
|
||||
<filename>.so</filename> file.
|
||||
</para>
|
||||
<example>
|
||||
<title>A sample plugin</title>
|
||||
<programlisting>
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes
|
||||
*/
|
||||
|
||||
#include <fu-plugin.h>
|
||||
#include <fu-plugin-vfuncs.h>
|
||||
|
||||
struct FuPluginData {
|
||||
gpointer proxy;
|
||||
};
|
||||
|
||||
void
|
||||
fu_plugin_initialize (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_BEFORE, "dfu");
|
||||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_destroy (FuPlugin *plugin)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
destroy_proxy (data->proxy);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
data->proxy = create_proxy ();
|
||||
if (data->proxy == NULL) {
|
||||
g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"failed to create proxy");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
We have to define when our plugin is run in reference to other plugins,
|
||||
in this case, making sure we run before the <code>dfu</code> plugin.
|
||||
For most plugins it does not matter in what order they are run and
|
||||
this information is not required.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Creating an abstract device</title>
|
||||
<para>
|
||||
This section shows how you would create a device which is exported
|
||||
to the daemon and thus can be queried and updated by the client software.
|
||||
The example here is all hardcoded, and a true plugin would have to
|
||||
derive the details about the <code>FuDevice</code> from the hardware,
|
||||
for example reading data from <code>sysfs</code> or <code>/dev</code>.
|
||||
</para>
|
||||
<example>
|
||||
<title>Example adding a custom device</title>
|
||||
<programlisting>
|
||||
#include <fu-plugin.h>
|
||||
|
||||
gboolean
|
||||
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
g_autoptr(FuDevice) dev = NULL;
|
||||
fu_device_set_id (dev, "dummy-1:2:3");
|
||||
fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e");
|
||||
fu_device_set_version (dev, "1.2.3");
|
||||
fu_device_get_version_lowest (dev, "1.2.2");
|
||||
fu_device_get_version_bootloader (dev, "0.1.2");
|
||||
fu_device_add_icon (dev, "computer");
|
||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_plugin_device_add (plugin, dev);
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
This shows a lot of the plugin architecture in action. Some notable points:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The device ID (<code>dummy-1:2:3</code>) has to be unique on the
|
||||
system between all plugins, so including the plugin name as a
|
||||
prefix is probably a good idea.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The GUID value can be generated automatically using
|
||||
<code>fu_device_add_guid(dev,"some-identifier")</code> but is quoted
|
||||
here explicitly.
|
||||
The GUID value has to match the <code>provides</code> value in the
|
||||
<code>.metainfo.xml</code> file for the firmware update to succeed.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Setting a display name and an icon is a good idea in case the
|
||||
GUI software needs to display the device to the user.
|
||||
Icons can be specified using a full path, although icon theme names
|
||||
should be preferred for most devices.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <code>FWUPD_DEVICE_FLAG_UPDATABLE</code> flag tells the client
|
||||
code that the device is in a state where it can be updated.
|
||||
If the device needs to be in a special mode (e.g. a bootloader) then
|
||||
the <code>FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER</code> flag can also be
|
||||
used.
|
||||
If the update should only be allowed when there is AC power available
|
||||
to the computer (i.e. not on battery) then
|
||||
<code>FWUPD_DEVICE_FLAG_REQUIRE_AC</code> should be used as well.
|
||||
There are other flags and the API documentation should be used when
|
||||
choosing what flags to use for each kind of device.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Setting the lowest allows client software to refuse downgrading
|
||||
the device to specific versions.
|
||||
This is required in case the upgrade migrates some kind of data-store
|
||||
so as to be incompatible with previous versions.
|
||||
Similarly, setting the version of the bootloader (if known) allows
|
||||
the firmware to depend on a specific bootloader version, for instance
|
||||
allowing signed firmware to only be installable on hardware with
|
||||
a bootloader new enough to deploy it
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Mechanism Plugins</title>
|
||||
<para>
|
||||
Although it would be a wonderful world if we could update all hardware
|
||||
using a standard shared protocol this is not the universe we live in.
|
||||
Using a mechanism like DFU or UpdateCapsule means that fwupd will just
|
||||
work without requiring any special code, but for the real world we need
|
||||
to support vendor-specific update protocols with layers of backwards
|
||||
compatibility.
|
||||
</para>
|
||||
<para>
|
||||
When a plugin has created a device that is <code>FWUPD_DEVICE_FLAG_UPDATABLE</code>
|
||||
we can ask the daemon to update the device with a suitable
|
||||
<code>.cab</code> file.
|
||||
When this is done the daemon checks the update for compatibility with
|
||||
the device, and then calls the vfuncs to update the device.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Updating a device</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update (FuPlugin *plugin,
|
||||
FuDevice *dev,
|
||||
GBytes *blob_fw,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
gsize sz = 0;
|
||||
guint8 *buf = g_bytes_get_data (blob_fw, &sz);
|
||||
/* write 'buf' of size 'sz' to the hardware */
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
It's important to note that the <code>blob_fw</code> is the binary
|
||||
firmware file (e.g. <code>.dfu</code>) and <emphasis role="strong">not</emphasis>
|
||||
the <code>.cab</code> binary data.
|
||||
</para>
|
||||
<para>
|
||||
If <code>FWUPD_INSTALL_FLAG_FORCE</code> is used then the usual checks
|
||||
done by the flashing process can be relaxed (e.g. checking for quirks),
|
||||
but please don't brick the users hardware even if they ask you to.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Policy Helpers</title>
|
||||
<para>
|
||||
For some hardware, we might want to do an action before or after
|
||||
the actual firmware is squirted into the device.
|
||||
This could be something as simple as checking the system battery
|
||||
level is over a certain threshold, or it could be as complicated as
|
||||
ensuring a vendor-specific GPIO is asserted when specific types
|
||||
of hardware are updated.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Running before a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_prepare (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC && !on_ac_power ()) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_AC_POWER_REQUIRED,
|
||||
"Cannot install update "
|
||||
"when not on AC power");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Running after a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_cleanup (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
return g_file_set_contents ("/var/lib/fwupd/something",
|
||||
fu_device_get_id (device), -1, error);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Detaching to bootloader mode</title>
|
||||
<para>
|
||||
Some hardware can only be updated in a special bootloader mode, which
|
||||
for most devices can be switched to automatically.
|
||||
In some cases the user to do something manually, for instance
|
||||
re-inserting the hardware with a secret button pressed.
|
||||
</para>
|
||||
<para>
|
||||
Before the device update is performed the fwupd daemon runs an optional
|
||||
<code>update_detach()</code> vfunc which switches the device to
|
||||
bootloader mode.
|
||||
After the update (or if the update fails) an the daemon runs an
|
||||
optional <code>update_attach()</code> vfunc which should switch the
|
||||
hardware back to runtime mode.
|
||||
Finally an optional <code>update_reload()</code> vfunc is run to
|
||||
get the new firmware version from the hardware.
|
||||
</para>
|
||||
<para>
|
||||
The optional vfuncs are <emphasis role="strong">only</emphasis> run
|
||||
on the plugin currently registered to handle the device ID, although
|
||||
the registered plugin can change during the attach and detach phases.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Running before a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
if (hardware_in_bootloader)
|
||||
return TRUE;
|
||||
return _device_detach(device, error);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Running after a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
if (!hardware_in_bootloader)
|
||||
return TRUE;
|
||||
return _device_attach(device, error);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Running after a device update on success</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_reload (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
g_autofree gchar *version = _get_version(plugin, device, error);
|
||||
if (version == NULL)
|
||||
return FALSE;
|
||||
fu_device_set_version(device, version);
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>The Plugin Object Cache</title>
|
||||
<para>
|
||||
The fwupd daemon provides a per-plugin cache which allows objects
|
||||
to be added, removed and queried using a specified key.
|
||||
Objects added to the cache must be <code>GObject</code>s to enable the
|
||||
cache objects to be properly refcounted.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Debugging a Plugin</title>
|
||||
<para>
|
||||
If the fwupd daemon is started with <code>--plugin-verbose=$plugin</code>
|
||||
then the environment variable <code>FWUPD_$PLUGIN_VERBOSE</code> is
|
||||
set process-wide.
|
||||
This allows plugins to detect when they should output detailed debugging
|
||||
information that would normally be too verbose to keep in the journal.
|
||||
For example, using <code>--plugin-verbose=logitech_hidpp</code> would set
|
||||
<code>FWUPD_LOGITECH_HID_VERBOSE=1</code>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Using existing code to develop a plugin</title>
|
||||
<para>
|
||||
It is not usually possible to <em>share</em> a plugin codebase with
|
||||
firmware update programs designed for other operating systems.
|
||||
Matching the same rationale as the Linux kernel, trying to use one
|
||||
code base between projects with a compatibility shim layer in-between
|
||||
is real headache to maintain.
|
||||
</para>
|
||||
<para>
|
||||
The general consensus is that trying to use a abstraction layer for
|
||||
hardware is a very bad idea as you're not able to take advantage of the
|
||||
platform specific helpers -- for instance quirk files and the custom
|
||||
GType device creation.
|
||||
The time the <em>vendor</em> saves by creating a shim layer and
|
||||
importing existing source code into fwupd will be overtaken 100x by
|
||||
<em>upstream</em> maintenance costs longer term, which isn't fair.
|
||||
</para>
|
||||
<para>
|
||||
In a similar way, using C++ rather than GObject C means expanding the
|
||||
test matrix to include clang in C++ mode and GNU g++ too.
|
||||
It's also doubled the runtime requirements to now include both the C
|
||||
standard library as well as the C++ standard library and increases the
|
||||
dependency surface.
|
||||
</para>
|
||||
<para>
|
||||
Most rewritten fwupd plugins at up to x10 smaller than the standalone
|
||||
code as they can take advantage of helpers provided by fwupd rather
|
||||
than re-implementing error handling, device quirking and data chunking.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</partintro>
|
||||
</reference>
|
||||
<xi:include href="tutorial.xml"/>
|
||||
<!--
|
||||
<xi:include href="hsi.xml"/>
|
||||
-->
|
||||
|
||||
<index id="api-index-full">
|
||||
<title>API Index</title>
|
||||
|
||||
877
docs/hsi.xml
Normal file
877
docs/hsi.xml
Normal file
@ -0,0 +1,877 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||||
<reference id="hsi">
|
||||
<title>Host Security ID Specification</title>
|
||||
<warning>
|
||||
<para>
|
||||
This specification is still in active development: it is incomplete,
|
||||
subject to change, and may have errors; use this at your own risk.
|
||||
It is based on publicly available information.
|
||||
</para>
|
||||
</warning>
|
||||
|
||||
<!-- only show when document has been verified by all the below people
|
||||
<info>
|
||||
<authorgroup>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Richard</firstname>
|
||||
<surname>Hughes</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<orgname>Red Hat</orgname>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Mario</firstname>
|
||||
<surname>Limonciello</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<orgname>Dell</orgname>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Alex</firstname>
|
||||
<surname>Bazhaniuk</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<orgname>Eclypsium</orgname>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<personname>
|
||||
<firstname>Alex</firstname>
|
||||
<surname>Matrosov</surname>
|
||||
</personname>
|
||||
<affiliation>
|
||||
<orgname>Nvidia</orgname>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</info>
|
||||
-->
|
||||
|
||||
<partintro>
|
||||
|
||||
<refsect1 id="introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
Not all system vendors prioritize building a secure platform.
|
||||
The truth is that <emphasis role="strong">security costs money</emphasis>.
|
||||
Vendors have to choose between saving a few cents on a bill-of-materials
|
||||
by sharing a SPI chip, or correctly implementing BootGuard.
|
||||
Discovering security vulnerabilities often takes an external researcher
|
||||
filing a disclosure.
|
||||
These disclosures are often technical in nature and difficult for an
|
||||
average consumer to decipher.
|
||||
</para>
|
||||
<para>
|
||||
The Linux Vendor Firmware Service (LVFS) could provide some
|
||||
<emphasis role="strong">easy-to-understand</emphasis> information to
|
||||
people buying hardware.
|
||||
The service already knows a huge amount of information about machines
|
||||
from signed reports uploaded to the LVFS and from analyzing firmware binaries.
|
||||
However this information alone does not explain firmware security to the
|
||||
user in a way they can actually interpret.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect2 id="other-tools">
|
||||
<title>Other Tools</title>
|
||||
<para>
|
||||
Traditionally, figuring out the true security of your hardware and firmware
|
||||
requires sifting through the marketing documentation provided by the
|
||||
OEM and in many cases just “trusting” they did it right.
|
||||
Tools such as Chipsec can check the hardware configuration, but they do
|
||||
not work out of the box and use technical jargon that an average user
|
||||
cannot interpret.
|
||||
Unfortunately, running a tool like Chipsec requires that you actively
|
||||
turn off some security layers such as UEFI Secure Boot, and allow 3rd
|
||||
party unsigned kernel modules to be loaded.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect1 id="verifying">
|
||||
<title>Verifying Host Firmware Security</title>
|
||||
<para>
|
||||
To start out some core protections must be assigned a relative importance.
|
||||
Then an evaluation must be done to determine how each vendor is conforming
|
||||
to the model.
|
||||
For instance, a user might say that for home use any hardware the bare
|
||||
minimum security level (<code>HSI:1</code>) is <emphasis>good enough</emphasis>.
|
||||
For a work laptop the company IT department might restrict the choice of
|
||||
models to anything meeting the criteria of level <code>HSI:2</code> or
|
||||
above.
|
||||
A journalist or a security researcher would only buy level <code>HSI:3</code>
|
||||
and above.
|
||||
The reality is that <code>HSI:4</code> is going to be more expensive
|
||||
than some unbranded hardware that is rated <code>HSI:0</code>.
|
||||
</para>
|
||||
<para>
|
||||
To be trusted, this rating information should be distributed in a
|
||||
centralized agnostic database such as the LVFS.
|
||||
</para>
|
||||
<para>
|
||||
Of course, tools need to detect implementation errors, and to verify that
|
||||
the model that is measured does indeed match the HSI level advertised by
|
||||
the LVFS.
|
||||
Some existing compliance solutions place the burden on the OEM to define
|
||||
what firmware security has been implemented, which is easy to get wrong
|
||||
and in some cases impossible to verify.
|
||||
</para>
|
||||
<para>
|
||||
For this reason HSI will only measure security protections that can be
|
||||
verified by the end user without requiring any extra hardware to be
|
||||
connected, additional software to be installed, or disabling any existing
|
||||
security layers to measure.
|
||||
</para>
|
||||
<para>
|
||||
The HSI specification is primarily designed for laptop and desktop
|
||||
hardware, although some tests <emphasis>may</emphasis> still make sense
|
||||
on server or embedded hardware.
|
||||
It is not expected that non-consumer hardware will publish an HSI number.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect2 id="runtime-behaviour">
|
||||
<title>Runtime Behavior</title>
|
||||
<para>
|
||||
Orthogonal to the security features provided by the firmware there are
|
||||
other security considerations related to the firmware which may require
|
||||
internet access to discover or that runtime OS changes directly affect
|
||||
the security of the firmware.
|
||||
It would not make sense to have <emphasis>have updates on the LVFS</emphasis>
|
||||
as a requirement for a specific security level as this would mean
|
||||
offline the platform might be a higher level initially but as soon as
|
||||
it is brought online it is downgraded which would be really confusing to
|
||||
users.
|
||||
The <emphasis>core</emphasis> security level will not change at
|
||||
Operating System runtime, but the suffix may.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="hsi-level0">
|
||||
<title>HSI:0 (Insecure)</title>
|
||||
<para>
|
||||
The lowest security level with little or no detected firmware protections.
|
||||
This is the default security level if no tests can be run or some tests
|
||||
in the next security level have failed.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="hsi-level1">
|
||||
<title>HSI:1 (Critical)</title>
|
||||
<para>
|
||||
This security level corresponds to the most basic of security protections
|
||||
considered essential by security professionals.
|
||||
Any failures at this level would have critical security impact and could
|
||||
likely be used to compromise the system firmware without physical access.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="hsi-level2">
|
||||
<title>HSI:3 (Theoretical)</title>
|
||||
<para>
|
||||
This security level corresponds to firmware security issues that pose a
|
||||
theoretical concern or where any exploit would be difficult or
|
||||
impractical to use.
|
||||
At this level various technologies may be employed to protect the boot
|
||||
process from modification by an attacker with local access to the machine.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="hsi-level4">
|
||||
<title>HSI:4 (System Protection)</title>
|
||||
<para>
|
||||
This security level corresponds to out-of-band protection of the system
|
||||
firmware perhaps including recovery.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="hsi-level5">
|
||||
<title>HSI:5 (System Attestation)</title>
|
||||
<para>
|
||||
This security level corresponds to out-of-band attestation of the system
|
||||
firmware.
|
||||
There are currently no tests implemented for HSI:5 and so this security
|
||||
level cannot yet be obtained.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Fwupd.Updates">
|
||||
<title>HSI Runtime Suffix <code>U</code></title>
|
||||
<para>
|
||||
Updates available on the <ulink url="https://fwupd.org/">
|
||||
Linux Vendor Firmware Service </ulink> which are less than 12 months old.
|
||||
</para>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Fwupd.Attestation">
|
||||
<title>HSI Runtime Suffix <code>A</code></title>
|
||||
<para>
|
||||
Attestation data is available to verify the current system firmware.
|
||||
For most UEFI platforms, this is usually the Trusted Platform Module (TPM)
|
||||
PCR0 hash, but other attestation checksums could be used.
|
||||
</para>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="runtime-bang">
|
||||
<title>HSI Runtime Suffix <code>!</code></title>
|
||||
<para>
|
||||
A runtime security issue detected.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem id="org.fwupd.hsi.Uefi.SecureBoot">
|
||||
<para>
|
||||
UEFI <ulink url="https://wiki.ubuntu.com/UEFI/SecureBoot">
|
||||
Secure Boot</ulink> has been turned off. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="org.fwupd.hsi.Kernel.Tainted">
|
||||
<para>
|
||||
The kernel is <ulink url="https://www.kernel.org/doc/html/latest/admin-guide/tainted-kernels.html">
|
||||
tainted</ulink> due to a non-free module or critical firmware issue. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="org.fwupd.hsi.Kernel.Lockdown">
|
||||
<para>
|
||||
The kernel is not <ulink url="https://mjg59.dreamwidth.org/50577.html">
|
||||
locked down</ulink>. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="org.fwupd.hsi.Kernel.Swap">
|
||||
<para>
|
||||
Unencrypted <ulink url="https://wiki.archlinux.org/index.php/Dm-crypt/Swap_encryption">
|
||||
swap partition</ulink>. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="org.fwupd.hsi.Fwupd.Plugins">
|
||||
<para>
|
||||
The installed fwupd is running with <ulink url="https://github.com/fwupd/fwupd/tree/master/plugins">
|
||||
custom or modified plugins</ulink>. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</refsect3>
|
||||
|
||||
<refsect2 id="tests">
|
||||
<title>Tests included in fwupd</title>
|
||||
<para>
|
||||
The set of tests is currently x86 UEFI-centric, but will be expanded
|
||||
in the future for various ARM or RISC-V firmware protections as required.
|
||||
Where the requirement is architecture or processor specific it has been noted.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Uefi.SecureBoot">
|
||||
<title>UEFI SecureBoot</title>
|
||||
<para>
|
||||
UEFI Secure boot is a verification mechanism for ensuring that code
|
||||
launched by firmware is trusted.
|
||||
</para>
|
||||
<para>
|
||||
Secure Boot requires that each binary loaded at boot is validated
|
||||
against trusted certifictes.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 SecureBoot must be available for use on UEFI systems.
|
||||
<emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://wiki.ubuntu.com/UEFI/SecureBoot">
|
||||
UEFI Wiki Entry
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Spi.Bioswe">
|
||||
<title>BIOS Write Enable (BWE)</title>
|
||||
<para>
|
||||
Intel hardware provides this mechanism to protect the SPI ROM chip
|
||||
located on the motherboard from being overwritten by the operating system.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 the ``BIOSWE`` bit must be unset. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="http://www.intel.com/content/www/us/en/chipsets/6-chipset-c200-chipset-datasheet.html">
|
||||
Intel C200 Datasheet
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Spi.Ble">
|
||||
<title>BIOS Lock Enable (BLE)</title>
|
||||
<para>
|
||||
If the lock bit is set then System Management Interrupts (SMIs) are
|
||||
raised when setting BIOS Write Enable.
|
||||
The <code>BLE</code>` bit must be enabled in the PCH otherwise
|
||||
<code>BIOSWE</code> can easily be unset.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should be set. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="http://www.intel.com/content/www/us/en/chipsets/6-chipset-c200-chipset-datasheet.html">
|
||||
Intel C200 Datasheet
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Spi.SmmBwp">
|
||||
<title>SMM Bios Write Protect (SMM_BWP)</title>
|
||||
<para>
|
||||
This bit set defines when the BIOS region can be written by the host.
|
||||
The <code>SMM_BWP</code> bit must be set to make the BIOS region
|
||||
non-writable unless all processors are in system management mode.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should be set <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="http://www.intel.com/content/www/us/en/chipsets/6-chipset-c200-chipset-datasheet.html">
|
||||
Intel C200 Datasheet
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Tpm.Version20">
|
||||
<title>TPM 2.0 Present</title>
|
||||
<para>
|
||||
A TPM securely stores platform specific secrets that can only be divulged
|
||||
to trusted consumers in a secure environment.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should be available for use by the OS or applications <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://en.wikipedia.org/wiki/Trusted_Platform_Module">
|
||||
Wikipedia TPM Article
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Mei.ManufacturingMode">
|
||||
<title>ME not in manufacturing mode</title>
|
||||
<para>
|
||||
There have been some unfortunate cases of the ME being distributed in
|
||||
manufacturing mode.
|
||||
In manufacturing mode many features from the ME can be interacted with
|
||||
that decrease the platform’s security.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should be unset <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="http://blog.ptsecurity.com/2018/10/intel-me-manufacturing-mode-macbook.html">
|
||||
ME Manufacturing Mode: obscured dangers
|
||||
</ulink>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<ulink url="https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00086.html">
|
||||
Intel security advisory SA-00086
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Mei.OverrideStrap">
|
||||
<title>ME Flash Descriptor Override</title>
|
||||
<para>
|
||||
The Flash Descriptor Security Override Strap is not accessible to end
|
||||
users on consumer boards and Intel stresses that this is for debugging only.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should be unset <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://chromium.googlesource.com/chromiumos/third_party/flashrom/+/master/Documentation/mysteries_intel.txt">
|
||||
Chromium documentation for Intel ME
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Mei.Version">
|
||||
<title>CSME Version</title>
|
||||
<para>
|
||||
Converged Security and Manageability Engine is a standalone management
|
||||
module that can manage and control some local devices without the host
|
||||
CPU involvement.
|
||||
The CSME lives in the PCH and can only be updated by the OEM vendor.
|
||||
The version of the CSME module can be checked to detect the most common
|
||||
and serious vulnerabilities.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should not be vulnerable to CVE-2017-5705, CVE-2017-5708,
|
||||
CVE-2017-5711, CVE-2017-5712, CVE-2017-5711, CVE-2017-5712, CVE-2017-5706,
|
||||
CVE-2017-5709, CVE-2017-5707 or CVE-2017-5710 <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00086.html">
|
||||
Intel CSME Security Review Cumulative Update
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.IntelDci">
|
||||
<title>Intel DCI</title>
|
||||
<para>
|
||||
Newer Intel CPUs support debugging over USB3 via a proprietary Direct
|
||||
Connection Interface (DCI) with the use of off-the-shelf hardware.
|
||||
DCI should always be disabled and locked on production hardware.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 this should be disabled. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-2 this should be locked. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://www.intel.co.uk/content/www/uk/en/support/articles/000029393/processors.html">
|
||||
Intel Direct Connect Interface
|
||||
</ulink>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<ulink url="https://github.com/chipsec/chipsec/blob/master/chipsec/cfg/8086/pch_4xxlp.xml#L270">
|
||||
Chipsec 4xxlp register definitions
|
||||
</ulink>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<ulink url="https://github.com/riscv/riscv-edk2-platforms/blob/85a50de1b459d1d6644a402081120770aa6dd8c7/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsDci.h">
|
||||
RISC-V EDK PCH register definitions
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Tpm.ReconstructionPcr0">
|
||||
<title>PCR0 TPM Event Log Reconstruction</title>
|
||||
<para>
|
||||
The TPM event log records which events are registered for the PCR0 hash.
|
||||
When reconstructed the event log values should always match the TPM PCR0.
|
||||
If extra events are included in the event log, or some are missing,
|
||||
the reconstitution will fail.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-2 this should match the TPM-provided PCR0 <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://www.kernel.org/doc/html/latest/security/tpm/tpm_event_log.html">
|
||||
Linux Kernel TPM Documentation
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
<refsect3 id="org.fwupd.hsi.AcpiDmar">
|
||||
<title>Pre-boot DMA protection</title>
|
||||
<para>
|
||||
The IOMMU on modern systems is used to mitigate against DMA attacks.
|
||||
All I/O for devices capable of DMA is mapped into a private virtual
|
||||
memory region.
|
||||
The ACPI DMAR table is used to set up pre-boot DMA protection which
|
||||
eliminates some firmware attacks.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-2 this should be available <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit">
|
||||
Wikipedia IOMMU article
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.IntelBootguard">
|
||||
<title>Intel BootGuard</title>
|
||||
<para>
|
||||
BootGuard is a processor feature that prevents the machine from running
|
||||
firmware images not released by the system manufacturer.
|
||||
It forms a root-of-trust by fusing in cryptographic keys into the processor
|
||||
itself that are used to verify the Authenticated Code Modules found in
|
||||
the SPI flash.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-1 verified boot must be enabled with ACM protection. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-2 the error enforcement policy must be set to “immediate shutdown”. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://github.com/coreboot/coreboot/blob/master/src/soc/intel/jasperlake/include/soc/me.h">
|
||||
Coreboot documentation
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.SuspendToRam">
|
||||
<title>Suspend to RAM disabled</title>
|
||||
<para>
|
||||
Suspend to Ram (S3) keeps the raw contents of the DRAM refreshed when
|
||||
the system is asleep.
|
||||
This means that the memory modules can be physically removed and the
|
||||
contents recovered, or a cold boot attack can be performed with a USB device.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-3 the firmware should be configured to prefer using suspend
|
||||
to idle instead of suspend to ram or to not offer suspend to
|
||||
RAM. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://en.wikipedia.org/wiki/Cold_boot_attack">
|
||||
Wikipedia article on cold boot attacks
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.IntelCet">
|
||||
<title>Intel CET Available</title>
|
||||
<para>
|
||||
Control enforcement technology is available on new Intel platforms and
|
||||
prevents exploits from hijacking the control-flow transfer instructions
|
||||
for both forward-edge (indirect call/jmp) and back-edge transfer (ret).
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-3 this should be available and enabled <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf">
|
||||
Intel CET Technology Preview
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.EncryptedRam">
|
||||
<title>DRAM total memory encryption (TME)</title>
|
||||
<para>
|
||||
Total memory encryption technology is used by the firmware on supported
|
||||
SOCs to encrypt all data on external memory buses.
|
||||
It mitigates against an attacker being able to capture memory data while
|
||||
the system is running or to capture memory by removing a DRAM chip.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-4 this should be supported and enabled <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://software.intel.com/content/www/us/en/develop/blogs/intel-releases-new-technology-specification-for-memory-encryption.html">
|
||||
Intel TME Press Release
|
||||
</ulink>
|
||||
</listitem>0
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
<refsect3 id="org.fwupd.hsi.IntelSmap">
|
||||
<title>Supervisor Mode Access Prevention</title>
|
||||
<para>
|
||||
Without Supervisor Mode Access Prevention, the supervisor code usually
|
||||
has full read and write access to user-space memory mappings.
|
||||
This can make exploits easier to write, as it allows the kernel to
|
||||
access user-space memory when it did not intend to.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-4 the SMAP and SMEP features should be available on the CPU. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention">
|
||||
Wikipedia SMAP Article
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.Iommu">
|
||||
<title>Kernel DMA protection</title>
|
||||
<para>
|
||||
The IOMMU on modern systems is used to mitigate against DMA attacks.
|
||||
All I/O for devices capable of DMA is mapped into a private virtual
|
||||
memory region.
|
||||
Common implementations are Intel VT-d and AMD-Vi.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-2 this should be available for use. <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<note>
|
||||
<para>
|
||||
See also:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<ulink url="https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit">
|
||||
Wikipedia IOMMU article
|
||||
</ulink>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</note>
|
||||
</refsect3>
|
||||
|
||||
<refsect3 id="org.fwupd.hsi.SuspendToIdle">
|
||||
<title>Suspend-to-Idle</title>
|
||||
<para>
|
||||
The platform should be set up with Suspend-to-Idle as the default S3
|
||||
sleep state.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
For HSI-3 this should be set <emphasis>v1.5.0</emphasis>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</refsect3>
|
||||
|
||||
<refsect1 id="conclusions">
|
||||
<title>Conclusion</title>
|
||||
<para>
|
||||
Any system with a Host Security ID of <code>0</code> can easily be
|
||||
modified from userspace.
|
||||
PCs with confidential documents should have a <code>HSI:3</code> or
|
||||
higher level of protection.
|
||||
In a graphical tool that would show details about the computer (such as
|
||||
GNOME Control Center’s details tab) the OS could display a field
|
||||
indicating Host Security ID.
|
||||
The ID should be shown with an alert color if the security is not at
|
||||
least <code>HSI:1</code> or the suffix is <code>!</code>.
|
||||
</para>
|
||||
<para>
|
||||
On Linux <code>fwupd</code> is used to enumerate and update firmware.
|
||||
It exports a property <code>HostSecurityId</code> and a
|
||||
<code>GetHostSecurityAttrs()</code> method.
|
||||
The attributes are supposed to represent the <emphasis>system as a whole</emphasis>
|
||||
but individual (internal) devices are able to make a claim that they
|
||||
worsened the state of the security of the system.
|
||||
Certain attributes can “obsolete” other attributes.
|
||||
An example is BIOSGuard will set obsoletes to <code>org.intel.prx</code>.
|
||||
</para>
|
||||
<para>
|
||||
A plugin method gets called on each plugin which adds attributes directly
|
||||
from the hardware or kernel.
|
||||
Several attributes may be dependent upon the kernel performing measurements
|
||||
and it will take time for these to be upstreamed.
|
||||
In some cases security level measurements will only be possible on systems
|
||||
with a newer kernel.
|
||||
</para>
|
||||
<para>
|
||||
The long term goal is to increase the <code>HSI:x</code> level of systems
|
||||
being sold to consumers.
|
||||
By making some of the <code>HSI:x</code> attributes part of the LVFS
|
||||
uploaded report we can allow users to compare vendors and models before
|
||||
purchasing hardware.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect2 id="ommissions">
|
||||
<title>Intentional Omissions</title>
|
||||
</refsect2>
|
||||
<refsect3 id="intel-sgx">
|
||||
<title>Intel SGX</title>
|
||||
<para>
|
||||
This is not widely used as it has several high severity security issues.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="intel-mpx">
|
||||
<title>Intel MPX</title>
|
||||
<para>
|
||||
MPX support was removed from GCC and the Linux kernel in 2019 and it is
|
||||
now considered obsolete.
|
||||
</para>
|
||||
</refsect3>
|
||||
|
||||
<refsect1 id="further-work">
|
||||
<title>Further Work</title>
|
||||
<para>
|
||||
More internal and external devices should be factored into the security
|
||||
equation.
|
||||
For now the focus for further tests should be around internal device
|
||||
firmware as it is what can be most directly controlled by fwupd and the
|
||||
hardware manufacturer.
|
||||
</para>
|
||||
<para>
|
||||
Security conscious manufacturers are actively participating in the
|
||||
development of future initiatives in the Trusted Computing Group (TCG).
|
||||
As those become ratified standards that are available in hardware,
|
||||
there are opportunities for synergy with this specification.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</partintro>
|
||||
</reference>
|
||||
@ -5,6 +5,11 @@ gnome.gtkdoc(
|
||||
join_paths(meson.source_root(), 'libfwupdplugin'),
|
||||
join_paths(meson.build_root(), 'libfwupd'),
|
||||
join_paths(meson.build_root(), 'libfwupdplugin'),
|
||||
join_paths(meson.current_source_dir()),
|
||||
],
|
||||
content_files : [
|
||||
'tutorial.xml',
|
||||
'hsi.xml',
|
||||
],
|
||||
main_xml : 'fwupd-docs.xml',
|
||||
install : true
|
||||
|
||||
402
docs/tutorial.xml
Normal file
402
docs/tutorial.xml
Normal file
@ -0,0 +1,402 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||||
<reference id="tutorial">
|
||||
<title>Plugin Tutorial</title>
|
||||
<partintro>
|
||||
<section>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
At the heart of fwupd is a plugin loader that gets run at startup,
|
||||
when devices get hotplugged and when updates are done.
|
||||
The idea is we have lots of small plugins that each do one thing, and
|
||||
are ordered by dependencies against each other at runtime.
|
||||
Using plugins we can add support for new hardware or new policies
|
||||
without making big changes all over the source tree.
|
||||
</para>
|
||||
<para>
|
||||
There are broadly 3 types of plugin methods:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">Mechanism</emphasis>: Upload binary data
|
||||
into a specific hardware device.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">Policy</emphasis>: Control the system when
|
||||
updates are happening, e.g. preventing the user from powering-off.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<emphasis role="strong">Helpers</emphasis>: Providing more
|
||||
metadata about devices, for instance handling device quirks.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
In general, building things out-of-tree isn't something that we think is
|
||||
a very good idea; the API and ABI <emphasis>internal</emphasis> to fwupd is still
|
||||
changing and there's a huge benefit to getting plugins upstream where
|
||||
they can undergo review and be ported as the API adapts.
|
||||
For this reason we don't install the plugin headers onto the system,
|
||||
although you can of course just install the <code>.so</code> binary file
|
||||
manually.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A plugin only needs to define the vfuncs that are required, and the
|
||||
plugin name is taken automatically from the suffix of the
|
||||
<filename>.so</filename> file.
|
||||
</para>
|
||||
<example>
|
||||
<title>A sample plugin</title>
|
||||
<programlisting>
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes
|
||||
*/
|
||||
|
||||
#include <fu-plugin.h>
|
||||
#include <fu-plugin-vfuncs.h>
|
||||
|
||||
struct FuPluginData {
|
||||
gpointer proxy;
|
||||
};
|
||||
|
||||
void
|
||||
fu_plugin_initialize (FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_BEFORE, "dfu");
|
||||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_destroy (FuPlugin *plugin)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
destroy_proxy (data->proxy);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
data->proxy = create_proxy ();
|
||||
if (data->proxy == NULL) {
|
||||
g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"failed to create proxy");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para>
|
||||
We have to define when our plugin is run in reference to other plugins,
|
||||
in this case, making sure we run before the <code>dfu</code> plugin.
|
||||
For most plugins it does not matter in what order they are run and
|
||||
this information is not required.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Creating an abstract device</title>
|
||||
<para>
|
||||
This section shows how you would create a device which is exported
|
||||
to the daemon and thus can be queried and updated by the client software.
|
||||
The example here is all hardcoded, and a true plugin would have to
|
||||
derive the details about the <code>FuDevice</code> from the hardware,
|
||||
for example reading data from <code>sysfs</code> or <code>/dev</code>.
|
||||
</para>
|
||||
<example>
|
||||
<title>Example adding a custom device</title>
|
||||
<programlisting>
|
||||
#include <fu-plugin.h>
|
||||
|
||||
gboolean
|
||||
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
|
||||
{
|
||||
g_autoptr(FuDevice) dev = NULL;
|
||||
fu_device_set_id (dev, "dummy-1:2:3");
|
||||
fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e");
|
||||
fu_device_set_version (dev, "1.2.3");
|
||||
fu_device_get_version_lowest (dev, "1.2.2");
|
||||
fu_device_get_version_bootloader (dev, "0.1.2");
|
||||
fu_device_add_icon (dev, "computer");
|
||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_plugin_device_add (plugin, dev);
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
This shows a lot of the plugin architecture in action. Some notable points:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The device ID (<code>dummy-1:2:3</code>) has to be unique on the
|
||||
system between all plugins, so including the plugin name as a
|
||||
prefix is probably a good idea.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The GUID value can be generated automatically using
|
||||
<code>fu_device_add_guid(dev,"some-identifier")</code> but is quoted
|
||||
here explicitly.
|
||||
The GUID value has to match the <code>provides</code> value in the
|
||||
<code>.metainfo.xml</code> file for the firmware update to succeed.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Setting a display name and an icon is a good idea in case the
|
||||
GUI software needs to display the device to the user.
|
||||
Icons can be specified using a full path, although icon theme names
|
||||
should be preferred for most devices.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
The <code>FWUPD_DEVICE_FLAG_UPDATABLE</code> flag tells the client
|
||||
code that the device is in a state where it can be updated.
|
||||
If the device needs to be in a special mode (e.g. a bootloader) then
|
||||
the <code>FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER</code> flag can also be
|
||||
used.
|
||||
If the update should only be allowed when there is AC power available
|
||||
to the computer (i.e. not on battery) then
|
||||
<code>FWUPD_DEVICE_FLAG_REQUIRE_AC</code> should be used as well.
|
||||
There are other flags and the API documentation should be used when
|
||||
choosing what flags to use for each kind of device.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Setting the lowest allows client software to refuse downgrading
|
||||
the device to specific versions.
|
||||
This is required in case the upgrade migrates some kind of data-store
|
||||
so as to be incompatible with previous versions.
|
||||
Similarly, setting the version of the bootloader (if known) allows
|
||||
the firmware to depend on a specific bootloader version, for instance
|
||||
allowing signed firmware to only be installable on hardware with
|
||||
a bootloader new enough to deploy it
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Mechanism Plugins</title>
|
||||
<para>
|
||||
Although it would be a wonderful world if we could update all hardware
|
||||
using a standard shared protocol this is not the universe we live in.
|
||||
Using a mechanism like DFU or UpdateCapsule means that fwupd will just
|
||||
work without requiring any special code, but for the real world we need
|
||||
to support vendor-specific update protocols with layers of backwards
|
||||
compatibility.
|
||||
</para>
|
||||
<para>
|
||||
When a plugin has created a device that is <code>FWUPD_DEVICE_FLAG_UPDATABLE</code>
|
||||
we can ask the daemon to update the device with a suitable
|
||||
<code>.cab</code> file.
|
||||
When this is done the daemon checks the update for compatibility with
|
||||
the device, and then calls the vfuncs to update the device.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Updating a device</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update (FuPlugin *plugin,
|
||||
FuDevice *dev,
|
||||
GBytes *blob_fw,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
gsize sz = 0;
|
||||
guint8 *buf = g_bytes_get_data (blob_fw, &sz);
|
||||
/* write 'buf' of size 'sz' to the hardware */
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<para>
|
||||
It's important to note that the <code>blob_fw</code> is the binary
|
||||
firmware file (e.g. <code>.dfu</code>) and <emphasis role="strong">not</emphasis>
|
||||
the <code>.cab</code> binary data.
|
||||
</para>
|
||||
<para>
|
||||
If <code>FWUPD_INSTALL_FLAG_FORCE</code> is used then the usual checks
|
||||
done by the flashing process can be relaxed (e.g. checking for quirks),
|
||||
but please don't brick the users hardware even if they ask you to.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Policy Helpers</title>
|
||||
<para>
|
||||
For some hardware, we might want to do an action before or after
|
||||
the actual firmware is squirted into the device.
|
||||
This could be something as simple as checking the system battery
|
||||
level is over a certain threshold, or it could be as complicated as
|
||||
ensuring a vendor-specific GPIO is asserted when specific types
|
||||
of hardware are updated.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Running before a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_prepare (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC && !on_ac_power ()) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_AC_POWER_REQUIRED,
|
||||
"Cannot install update "
|
||||
"when not on AC power");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Running after a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_cleanup (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
return g_file_set_contents ("/var/lib/fwupd/something",
|
||||
fu_device_get_id (device), -1, error);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Detaching to bootloader mode</title>
|
||||
<para>
|
||||
Some hardware can only be updated in a special bootloader mode, which
|
||||
for most devices can be switched to automatically.
|
||||
In some cases the user to do something manually, for instance
|
||||
re-inserting the hardware with a secret button pressed.
|
||||
</para>
|
||||
<para>
|
||||
Before the device update is performed the fwupd daemon runs an optional
|
||||
<code>update_detach()</code> vfunc which switches the device to
|
||||
bootloader mode.
|
||||
After the update (or if the update fails) an the daemon runs an
|
||||
optional <code>update_attach()</code> vfunc which should switch the
|
||||
hardware back to runtime mode.
|
||||
Finally an optional <code>update_reload()</code> vfunc is run to
|
||||
get the new firmware version from the hardware.
|
||||
</para>
|
||||
<para>
|
||||
The optional vfuncs are <emphasis role="strong">only</emphasis> run
|
||||
on the plugin currently registered to handle the device ID, although
|
||||
the registered plugin can change during the attach and detach phases.
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>Running before a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
if (hardware_in_bootloader)
|
||||
return TRUE;
|
||||
return _device_detach(device, error);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Running after a device update</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
if (!hardware_in_bootloader)
|
||||
return TRUE;
|
||||
return _device_attach(device, error);
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>Running after a device update on success</title>
|
||||
<programlisting>
|
||||
gboolean
|
||||
fu_plugin_update_reload (FuPlugin *plugin, FuDevice *device, GError **error)
|
||||
{
|
||||
g_autofree gchar *version = _get_version(plugin, device, error);
|
||||
if (version == NULL)
|
||||
return FALSE;
|
||||
fu_device_set_version(device, version);
|
||||
return TRUE;
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>The Plugin Object Cache</title>
|
||||
<para>
|
||||
The fwupd daemon provides a per-plugin cache which allows objects
|
||||
to be added, removed and queried using a specified key.
|
||||
Objects added to the cache must be <code>GObject</code>s to enable the
|
||||
cache objects to be properly refcounted.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Debugging a Plugin</title>
|
||||
<para>
|
||||
If the fwupd daemon is started with <code>--plugin-verbose=$plugin</code>
|
||||
then the environment variable <code>FWUPD_$PLUGIN_VERBOSE</code> is
|
||||
set process-wide.
|
||||
This allows plugins to detect when they should output detailed debugging
|
||||
information that would normally be too verbose to keep in the journal.
|
||||
For example, using <code>--plugin-verbose=logitech_hidpp</code> would set
|
||||
<code>FWUPD_LOGITECH_HID_VERBOSE=1</code>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Using existing code to develop a plugin</title>
|
||||
<para>
|
||||
It is not usually possible to <em>share</em> a plugin codebase with
|
||||
firmware update programs designed for other operating systems.
|
||||
Matching the same rationale as the Linux kernel, trying to use one
|
||||
code base between projects with a compatibility shim layer in-between
|
||||
is real headache to maintain.
|
||||
</para>
|
||||
<para>
|
||||
The general consensus is that trying to use a abstraction layer for
|
||||
hardware is a very bad idea as you're not able to take advantage of the
|
||||
platform specific helpers -- for instance quirk files and the custom
|
||||
GType device creation.
|
||||
The time the <em>vendor</em> saves by creating a shim layer and
|
||||
importing existing source code into fwupd will be overtaken 100x by
|
||||
<em>upstream</em> maintenance costs longer term, which isn't fair.
|
||||
</para>
|
||||
<para>
|
||||
In a similar way, using C++ rather than GObject C means expanding the
|
||||
test matrix to include clang in C++ mode and GNU g++ too.
|
||||
It's also doubled the runtime requirements to now include both the C
|
||||
standard library as well as the C++ standard library and increases the
|
||||
dependency surface.
|
||||
</para>
|
||||
<para>
|
||||
Most rewritten fwupd plugins at up to x10 smaller than the standalone
|
||||
code as they can take advantage of helpers provided by fwupd rather
|
||||
than re-implementing error handling, device quirking and data chunking.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</partintro>
|
||||
</reference>
|
||||
36
libfwupd/fwupd-client-private.h
Normal file
36
libfwupd/fwupd-client-private.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fwupd-client.h"
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
#include <gio/gunixinputstream.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
void fwupd_client_get_details_stream_async (FwupdClient *self,
|
||||
GUnixInputStream *istr,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
void fwupd_client_install_stream_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GUnixInputStream *istr,
|
||||
const gchar *filename_hint,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
void fwupd_client_update_metadata_stream_async(FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
GUnixInputStream *istr,
|
||||
GUnixInputStream *istr_sig,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
#endif
|
||||
2054
libfwupd/fwupd-client-sync.c
Normal file
2054
libfwupd/fwupd-client-sync.c
Normal file
File diff suppressed because it is too large
Load Diff
173
libfwupd/fwupd-client-sync.h
Normal file
173
libfwupd/fwupd-client-sync.h
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fwupd-client.h"
|
||||
|
||||
gboolean fwupd_client_connect (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_devices (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_plugins (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_history (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_releases (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_downgrades (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_upgrades (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_details (FwupdClient *self,
|
||||
const gchar *filename,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_details_bytes (FwupdClient *self,
|
||||
GBytes *bytes,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_verify (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_verify_update (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_unlock (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_config (FwupdClient *self,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_activate (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
const gchar *device_id,
|
||||
GError **error);
|
||||
gboolean fwupd_client_clear_results (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FwupdDevice *fwupd_client_get_results (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_host_security_attrs (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FwupdDevice *fwupd_client_get_device_by_id (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_devices_by_guid (FwupdClient *self,
|
||||
const gchar *guid,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
const gchar *filename,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install_bytes (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GBytes *bytes,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install_release (FwupdClient *self,
|
||||
FwupdDevice *device,
|
||||
FwupdRelease *release,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_update_metadata (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
const gchar *metadata_fn,
|
||||
const gchar *signature_fn,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_update_metadata_bytes (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
GBytes *metadata,
|
||||
GBytes *signature,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_refresh_remote (FwupdClient *self,
|
||||
FwupdRemote *remote,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_remote (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_device (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GHashTable *fwupd_client_get_report_metadata (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_remotes (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FwupdRemote *fwupd_client_get_remote_by_id (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gchar **fwupd_client_get_approved_firmware (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_set_approved_firmware (FwupdClient *self,
|
||||
gchar **checksums,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gchar **fwupd_client_get_blocked_firmware (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_set_blocked_firmware (FwupdClient *self,
|
||||
gchar **checksums,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gchar *fwupd_client_self_sign (FwupdClient *self,
|
||||
const gchar *value,
|
||||
FwupdSelfSignFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_set_feature_flags (FwupdClient *self,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GBytes *fwupd_client_download_bytes (FwupdClient *self,
|
||||
const gchar *url,
|
||||
FwupdClientDownloadFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GBytes *fwupd_client_upload_bytes (FwupdClient *self,
|
||||
const gchar *url,
|
||||
const gchar *payload,
|
||||
const gchar *signature,
|
||||
FwupdClientUploadFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
||||
|
||||
#include "fwupd-enums.h"
|
||||
#include "fwupd-device.h"
|
||||
#include "fwupd-plugin.h"
|
||||
#include "fwupd-remote.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -67,171 +68,319 @@ typedef enum {
|
||||
} FwupdClientUploadFlags;
|
||||
|
||||
FwupdClient *fwupd_client_new (void);
|
||||
gboolean fwupd_client_connect (FwupdClient *client,
|
||||
void fwupd_client_connect_async (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_connect_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_devices (FwupdClient *client,
|
||||
void fwupd_client_get_devices_async (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_devices_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_history (FwupdClient *client,
|
||||
void fwupd_client_get_plugins_async (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_plugins_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_releases (FwupdClient *client,
|
||||
void fwupd_client_get_history_async (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_history_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void fwupd_client_get_releases_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_releases_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_downgrades (FwupdClient *client,
|
||||
void fwupd_client_get_downgrades_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_downgrades_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_upgrades (FwupdClient *client,
|
||||
void fwupd_client_get_upgrades_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_upgrades_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_details (FwupdClient *client,
|
||||
const gchar *filename,
|
||||
void fwupd_client_get_details_bytes_async (FwupdClient *self,
|
||||
GBytes *bytes,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_details_bytes_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_verify (FwupdClient *client,
|
||||
void fwupd_client_verify_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_verify_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_verify_update (FwupdClient *client,
|
||||
void fwupd_client_verify_update_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_verify_update_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_unlock (FwupdClient *client,
|
||||
void fwupd_client_unlock_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_unlock_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_config (FwupdClient *client,
|
||||
void fwupd_client_modify_config_async (FwupdClient *self,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_modify_config_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_activate (FwupdClient *client,
|
||||
GCancellable *cancellable,
|
||||
const gchar *device_id,
|
||||
GError **error);
|
||||
gboolean fwupd_client_clear_results (FwupdClient *client,
|
||||
void fwupd_client_activate_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_activate_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
FwupdDevice *fwupd_client_get_results (FwupdClient *client,
|
||||
void fwupd_client_clear_results_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_clear_results_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
FwupdDevice *fwupd_client_get_device_by_id (FwupdClient *client,
|
||||
void fwupd_client_get_results_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
FwupdDevice *fwupd_client_get_results_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GPtrArray *fwupd_client_get_devices_by_guid (FwupdClient *client,
|
||||
void fwupd_client_get_host_security_attrs_async(FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_host_security_attrs_finish(FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void fwupd_client_get_device_by_id_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
FwupdDevice *fwupd_client_get_device_by_id_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void fwupd_client_get_devices_by_guid_async (FwupdClient *self,
|
||||
const gchar *guid,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_devices_by_guid_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install (FwupdClient *client,
|
||||
void fwupd_client_install_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
const gchar *filename,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_install_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install_bytes (FwupdClient *client,
|
||||
void fwupd_client_install_bytes_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
GBytes *bytes,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_install_bytes_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_install_release (FwupdClient *client,
|
||||
void fwupd_client_install_release_async (FwupdClient *self,
|
||||
FwupdDevice *device,
|
||||
FwupdRelease *release,
|
||||
FwupdInstallFlags install_flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_install_release_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_update_metadata (FwupdClient *client,
|
||||
const gchar *remote_id,
|
||||
const gchar *metadata_fn,
|
||||
const gchar *signature_fn,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean fwupd_client_update_metadata_bytes (FwupdClient *client,
|
||||
void fwupd_client_update_metadata_bytes_async (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
GBytes *metadata,
|
||||
GBytes *signature,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_update_metadata_bytes_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_refresh_remote (FwupdClient *client,
|
||||
void fwupd_client_refresh_remote_async (FwupdClient *self,
|
||||
FwupdRemote *remote,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_refresh_remote_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_remote (FwupdClient *client,
|
||||
void fwupd_client_modify_remote_async (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_modify_remote_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_modify_device (FwupdClient *client,
|
||||
void fwupd_client_modify_device_async (FwupdClient *self,
|
||||
const gchar *device_id,
|
||||
const gchar *key,
|
||||
const gchar *value,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_modify_device_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
FwupdStatus fwupd_client_get_status (FwupdClient *client);
|
||||
gboolean fwupd_client_get_tainted (FwupdClient *client);
|
||||
gboolean fwupd_client_get_daemon_interactive (FwupdClient *client);
|
||||
guint fwupd_client_get_percentage (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_daemon_version (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_host_product (FwupdClient *client);
|
||||
const gchar *fwupd_client_get_host_machine_id (FwupdClient *client);
|
||||
|
||||
GPtrArray *fwupd_client_get_remotes (FwupdClient *client,
|
||||
void fwupd_client_get_report_metadata_async (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GHashTable *fwupd_client_get_report_metadata_finish(FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
FwupdRemote *fwupd_client_get_remote_by_id (FwupdClient *client,
|
||||
|
||||
FwupdStatus fwupd_client_get_status (FwupdClient *self);
|
||||
gboolean fwupd_client_get_tainted (FwupdClient *self);
|
||||
gboolean fwupd_client_get_daemon_interactive (FwupdClient *self);
|
||||
guint fwupd_client_get_percentage (FwupdClient *self);
|
||||
const gchar *fwupd_client_get_daemon_version (FwupdClient *self);
|
||||
const gchar *fwupd_client_get_host_product (FwupdClient *self);
|
||||
const gchar *fwupd_client_get_host_machine_id (FwupdClient *self);
|
||||
const gchar *fwupd_client_get_host_security_id (FwupdClient *self);
|
||||
|
||||
void fwupd_client_get_remotes_async (FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_remotes_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void fwupd_client_get_remote_by_id_async (FwupdClient *self,
|
||||
const gchar *remote_id,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
FwupdRemote *fwupd_client_get_remote_by_id_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
gchar **fwupd_client_get_approved_firmware (FwupdClient *client,
|
||||
void fwupd_client_get_approved_firmware_async(FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_approved_firmware_finish(FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_set_approved_firmware (FwupdClient *client,
|
||||
gchar **checksums,
|
||||
void fwupd_client_set_approved_firmware_async (FwupdClient *self,
|
||||
GPtrArray *checksums,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_set_approved_firmware_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gchar **fwupd_client_get_blocked_firmware (FwupdClient *client,
|
||||
void fwupd_client_get_blocked_firmware_async(FwupdClient *self,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GPtrArray *fwupd_client_get_blocked_firmware_finish(FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_set_blocked_firmware (FwupdClient *client,
|
||||
gchar **checksums,
|
||||
void fwupd_client_set_blocked_firmware_async (FwupdClient *self,
|
||||
GPtrArray *checksums,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_set_blocked_firmware_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gchar *fwupd_client_self_sign (FwupdClient *client,
|
||||
void fwupd_client_self_sign_async (FwupdClient *self,
|
||||
const gchar *value,
|
||||
FwupdSelfSignFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gchar *fwupd_client_self_sign_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_set_feature_flags (FwupdClient *client,
|
||||
void fwupd_client_set_feature_flags_async (FwupdClient *self,
|
||||
FwupdFeatureFlags feature_flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
gboolean fwupd_client_set_feature_flags_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
void fwupd_client_set_user_agent (FwupdClient *client,
|
||||
void fwupd_client_set_user_agent (FwupdClient *self,
|
||||
const gchar *user_agent);
|
||||
void fwupd_client_set_user_agent_for_package(FwupdClient *client,
|
||||
void fwupd_client_set_user_agent_for_package(FwupdClient *self,
|
||||
const gchar *package_name,
|
||||
const gchar *package_version);
|
||||
GBytes *fwupd_client_download_bytes (FwupdClient *client,
|
||||
void fwupd_client_download_bytes_async (FwupdClient *self,
|
||||
const gchar *url,
|
||||
FwupdClientDownloadFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GBytes *fwupd_client_download_bytes_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
GBytes *fwupd_client_upload_bytes (FwupdClient *client,
|
||||
void fwupd_client_upload_bytes_async (FwupdClient *self,
|
||||
const gchar *url,
|
||||
const gchar *payload,
|
||||
const gchar *signature,
|
||||
FwupdClientUploadFlags flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GBytes *fwupd_client_upload_bytes_finish (FwupdClient *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
gboolean fwupd_client_ensure_networking (FwupdClient *client,
|
||||
gboolean fwupd_client_ensure_networking (FwupdClient *self,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
#include <gio/gunixinputstream.h>
|
||||
@ -21,6 +21,14 @@ GVariant *fwupd_hash_kv_to_variant (GHashTable *hash);
|
||||
GHashTable *fwupd_variant_to_hash_kv (GVariant *dict);
|
||||
gchar *fwupd_build_user_agent_system (void);
|
||||
|
||||
void fwupd_input_stream_read_bytes_async (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data);
|
||||
GBytes *fwupd_input_stream_read_bytes_finish (GInputStream *stream,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
GUnixInputStream *fwupd_unix_input_stream_from_bytes (GBytes *bytes,
|
||||
GError **error);
|
||||
|
||||
@ -169,7 +169,6 @@ fwupd_get_os_release (GError **error)
|
||||
|
||||
/* find the correct file */
|
||||
for (guint i = 0; paths[i] != NULL; i++) {
|
||||
g_debug ("looking for os-release at %s", paths[i]);
|
||||
if (g_file_test (paths[i], G_FILE_TEST_EXISTS)) {
|
||||
filename = paths[i];
|
||||
break;
|
||||
@ -941,6 +940,96 @@ fwupd_variant_to_hash_kv (GVariant *dict)
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_input_stream_read_bytes_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GByteArray *bufarr;
|
||||
GInputStream *stream = G_INPUT_STREAM (source);
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GTask) task = G_TASK (user_data);
|
||||
#if GLIB_CHECK_VERSION(2, 64, 0)
|
||||
guint8 *buf;
|
||||
gsize bufsz = 0;
|
||||
#endif
|
||||
|
||||
/* read buf */
|
||||
bytes = g_input_stream_read_bytes_finish (stream, res, &error);
|
||||
if (bytes == NULL) {
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
/* add bytes to buffer */
|
||||
bufarr = g_task_get_task_data (task);
|
||||
if (g_bytes_get_size (bytes) > 0) {
|
||||
GCancellable *cancellable = g_task_get_cancellable (task);
|
||||
g_debug ("add %u", (guint) g_bytes_get_size (bytes));
|
||||
g_byte_array_append (bufarr,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes));
|
||||
g_input_stream_read_bytes_async (g_steal_pointer (&stream),
|
||||
256 * 1024, /* bigger chunk */
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
fwupd_input_stream_read_bytes_cb,
|
||||
g_steal_pointer (&task));
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
#if GLIB_CHECK_VERSION(2, 64, 0)
|
||||
buf = g_byte_array_steal (bufarr, &bufsz);
|
||||
g_task_return_pointer (task,
|
||||
g_bytes_new_take (buf, bufsz),
|
||||
(GDestroyNotify) g_bytes_unref);
|
||||
#else
|
||||
g_task_return_pointer (task,
|
||||
g_bytes_new (bufarr->data, bufarr->len),
|
||||
(GDestroyNotify) g_bytes_unref);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_input_stream_read_bytes_async: (skip):
|
||||
**/
|
||||
void
|
||||
fwupd_input_stream_read_bytes_async (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
g_autoptr(GTask) task = NULL;
|
||||
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
task = g_task_new (stream, cancellable, callback, callback_data);
|
||||
g_task_set_task_data (task, g_byte_array_new (), (GDestroyNotify) g_byte_array_unref);
|
||||
g_input_stream_read_bytes_async (stream,
|
||||
64 * 1024, /* small */
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
fwupd_input_stream_read_bytes_cb,
|
||||
g_steal_pointer (&task));
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_input_stream_read_bytes_finish: (skip):
|
||||
**/
|
||||
GBytes *
|
||||
fwupd_input_stream_read_bytes_finish (GInputStream *stream,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
|
||||
g_return_val_if_fail (g_task_is_valid (res, stream), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
return g_task_propagate_pointer (G_TASK(res), error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
/**
|
||||
* fwupd_unix_input_stream_from_bytes: (skip):
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2015-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
@ -39,6 +39,7 @@ typedef struct {
|
||||
gchar *name;
|
||||
gchar *serial;
|
||||
gchar *summary;
|
||||
gchar *branch;
|
||||
gchar *description;
|
||||
gchar *vendor;
|
||||
gchar *vendor_id;
|
||||
@ -62,7 +63,7 @@ typedef struct {
|
||||
gchar *update_image;
|
||||
FwupdStatus status;
|
||||
GPtrArray *releases;
|
||||
FwupdDevice *parent;
|
||||
FwupdDevice *parent; /* noref */
|
||||
} FwupdDevicePrivate;
|
||||
|
||||
enum {
|
||||
@ -71,6 +72,7 @@ enum {
|
||||
PROP_FLAGS,
|
||||
PROP_PROTOCOL,
|
||||
PROP_STATUS,
|
||||
PROP_PARENT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -172,6 +174,42 @@ fwupd_device_set_summary (FwupdDevice *device, const gchar *summary)
|
||||
priv->summary = g_strdup (summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_device_get_branch:
|
||||
* @device: A #FwupdDevice
|
||||
*
|
||||
* Gets the current device branch.
|
||||
*
|
||||
* Returns: the device branch, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_device_get_branch (FwupdDevice *device)
|
||||
{
|
||||
FwupdDevicePrivate *priv = GET_PRIVATE (device);
|
||||
g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
|
||||
return priv->branch;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_device_set_branch:
|
||||
* @device: A #FwupdDevice
|
||||
* @branch: the device one line branch
|
||||
*
|
||||
* Sets the current device branch.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_device_set_branch (FwupdDevice *device, const gchar *branch)
|
||||
{
|
||||
FwupdDevicePrivate *priv = GET_PRIVATE (device);
|
||||
g_return_if_fail (FWUPD_IS_DEVICE (device));
|
||||
g_free (priv->branch);
|
||||
priv->branch = g_strdup (branch);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_device_get_serial:
|
||||
* @device: A #FwupdDevice
|
||||
@ -311,10 +349,40 @@ void
|
||||
fwupd_device_set_parent (FwupdDevice *device, FwupdDevice *parent)
|
||||
{
|
||||
FwupdDevicePrivate *priv = GET_PRIVATE (device);
|
||||
FwupdDevicePrivate *priv_parent = GET_PRIVATE (parent);
|
||||
g_return_if_fail (FWUPD_IS_DEVICE (device));
|
||||
g_set_object (&priv->parent, parent);
|
||||
g_ptr_array_add (priv_parent->children, g_object_ref (device));
|
||||
|
||||
if (priv->parent != NULL)
|
||||
g_object_remove_weak_pointer (G_OBJECT (priv->parent), (gpointer *) &priv->parent);
|
||||
if (parent != NULL)
|
||||
g_object_add_weak_pointer (G_OBJECT (parent), (gpointer *) &priv->parent);
|
||||
priv->parent = parent;
|
||||
|
||||
/* this is what goes over D-Bus */
|
||||
fwupd_device_set_parent_id (device, parent != NULL ? fwupd_device_get_id (parent) : NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_device_add_child:
|
||||
* @self: A #FwupdDevice
|
||||
* @child: Another #FwupdDevice
|
||||
*
|
||||
* Adds a child device. An child device is logically linked to the primary
|
||||
* device in some way.
|
||||
*
|
||||
* Since: 1.5.1
|
||||
**/
|
||||
void
|
||||
fwupd_device_add_child (FwupdDevice *device, FwupdDevice *child)
|
||||
{
|
||||
FwupdDevicePrivate *priv = GET_PRIVATE (device);
|
||||
|
||||
/* add if the child does not already exist */
|
||||
for (guint i = 0; i < priv->children->len; i++) {
|
||||
FwupdDevice *devtmp = g_ptr_array_index (priv->children, i);
|
||||
if (devtmp == child)
|
||||
return;
|
||||
}
|
||||
g_ptr_array_add (priv->children, g_object_ref (child));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1098,7 +1166,6 @@ fwupd_device_get_created (FwupdDevice *device)
|
||||
return priv->created;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fwupd_device_set_created:
|
||||
* @device: A #FwupdDevice
|
||||
@ -1190,6 +1257,8 @@ fwupd_device_incorporate (FwupdDevice *self, FwupdDevice *donor)
|
||||
fwupd_device_set_serial (self, priv_donor->serial);
|
||||
if (priv->summary == NULL)
|
||||
fwupd_device_set_summary (self, priv_donor->summary);
|
||||
if (priv->branch == NULL)
|
||||
fwupd_device_set_branch (self, priv_donor->branch);
|
||||
if (priv->vendor == NULL)
|
||||
fwupd_device_set_vendor (self, priv_donor->vendor);
|
||||
if (priv->vendor_id == NULL)
|
||||
@ -1325,6 +1394,11 @@ fwupd_device_to_variant_full (FwupdDevice *device, FwupdDeviceFlags flags)
|
||||
FWUPD_RESULT_KEY_SUMMARY,
|
||||
g_variant_new_string (priv->summary));
|
||||
}
|
||||
if (priv->branch != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_BRANCH,
|
||||
g_variant_new_string (priv->branch));
|
||||
}
|
||||
if (priv->checksums->len > 0) {
|
||||
g_autoptr(GString) str = g_string_new ("");
|
||||
for (guint i = 0; i < priv->checksums->len; i++) {
|
||||
@ -1537,6 +1611,10 @@ fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *va
|
||||
fwupd_device_set_summary (device, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_BRANCH) == 0) {
|
||||
fwupd_device_set_branch (device, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) {
|
||||
fwupd_device_set_description (device, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
@ -2037,6 +2115,7 @@ fwupd_device_to_json (FwupdDevice *device, JsonBuilder *builder)
|
||||
fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_SERIAL, priv->serial);
|
||||
fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_SUMMARY, priv->summary);
|
||||
fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
|
||||
fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_BRANCH, priv->branch);
|
||||
fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
|
||||
fwupd_device_json_add_string (builder, FWUPD_RESULT_KEY_PROTOCOL, priv->protocol);
|
||||
if (priv->flags != FWUPD_DEVICE_FLAG_NONE) {
|
||||
@ -2173,6 +2252,7 @@ fwupd_device_to_string (FwupdDevice *device)
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SERIAL, priv->serial);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SUMMARY, priv->summary);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_BRANCH, priv->branch);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PROTOCOL, priv->protocol);
|
||||
fwupd_pad_kv_dfl (str, FWUPD_RESULT_KEY_FLAGS, priv->flags);
|
||||
@ -2248,6 +2328,9 @@ fwupd_device_get_property (GObject *object, guint prop_id,
|
||||
case PROP_STATUS:
|
||||
g_value_set_uint (value, priv->status);
|
||||
break;
|
||||
case PROP_PARENT:
|
||||
g_value_set_object (value, priv->parent);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -2272,6 +2355,9 @@ fwupd_device_set_property (GObject *object, guint prop_id,
|
||||
case PROP_STATUS:
|
||||
fwupd_device_set_status (self, g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_PARENT:
|
||||
fwupd_device_set_parent (self, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -2316,6 +2402,13 @@ fwupd_device_class_init (FwupdDeviceClass *klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_STATUS, pspec);
|
||||
|
||||
pspec = g_param_spec_object ("parent", NULL, NULL,
|
||||
FWUPD_TYPE_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_PARENT, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2337,13 +2430,14 @@ fwupd_device_finalize (GObject *object)
|
||||
FwupdDevicePrivate *priv = GET_PRIVATE (device);
|
||||
|
||||
if (priv->parent != NULL)
|
||||
g_object_unref (priv->parent);
|
||||
g_object_remove_weak_pointer (G_OBJECT (priv->parent), (gpointer *) &priv->parent);
|
||||
g_free (priv->description);
|
||||
g_free (priv->id);
|
||||
g_free (priv->parent_id);
|
||||
g_free (priv->name);
|
||||
g_free (priv->serial);
|
||||
g_free (priv->summary);
|
||||
g_free (priv->branch);
|
||||
g_free (priv->vendor);
|
||||
g_free (priv->vendor_id);
|
||||
g_free (priv->plugin);
|
||||
@ -2439,8 +2533,10 @@ fwupd_device_array_ensure_parents (GPtrArray *devices)
|
||||
if (parent_id != NULL) {
|
||||
FwupdDevice *dev_tmp;
|
||||
dev_tmp = g_hash_table_lookup (devices_by_id, parent_id);
|
||||
if (dev_tmp != NULL)
|
||||
if (dev_tmp != NULL) {
|
||||
fwupd_device_add_child (dev_tmp, dev);
|
||||
fwupd_device_set_parent (dev, dev_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2015-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
@ -41,6 +41,8 @@ void fwupd_device_set_parent_id (FwupdDevice *device,
|
||||
FwupdDevice *fwupd_device_get_parent (FwupdDevice *device);
|
||||
void fwupd_device_set_parent (FwupdDevice *device,
|
||||
FwupdDevice *parent);
|
||||
void fwupd_device_add_child (FwupdDevice *device,
|
||||
FwupdDevice *child);
|
||||
GPtrArray *fwupd_device_get_children (FwupdDevice *device);
|
||||
const gchar *fwupd_device_get_name (FwupdDevice *device);
|
||||
void fwupd_device_set_name (FwupdDevice *device,
|
||||
@ -51,6 +53,9 @@ void fwupd_device_set_serial (FwupdDevice *device,
|
||||
const gchar *fwupd_device_get_summary (FwupdDevice *device);
|
||||
void fwupd_device_set_summary (FwupdDevice *device,
|
||||
const gchar *summary);
|
||||
const gchar *fwupd_device_get_branch (FwupdDevice *device);
|
||||
void fwupd_device_set_branch (FwupdDevice *device,
|
||||
const gchar *branch);
|
||||
const gchar *fwupd_device_get_description (FwupdDevice *device);
|
||||
void fwupd_device_set_description (FwupdDevice *device,
|
||||
const gchar *description);
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2018 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2016-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FWUPD_RESULT_KEY_APPSTREAM_ID "AppstreamId" /* s */
|
||||
@ -23,6 +25,8 @@ G_BEGIN_DECLS
|
||||
#define FWUPD_RESULT_KEY_FLAGS "Flags" /* t */
|
||||
#define FWUPD_RESULT_KEY_FLASHES_LEFT "FlashesLeft" /* u */
|
||||
#define FWUPD_RESULT_KEY_URGENCY "Urgency" /* u */
|
||||
#define FWUPD_RESULT_KEY_HSI_LEVEL "HsiLevel" /* u */
|
||||
#define FWUPD_RESULT_KEY_HSI_RESULT "HsiResult" /* u */
|
||||
#define FWUPD_RESULT_KEY_INSTALL_DURATION "InstallDuration" /* u */
|
||||
#define FWUPD_RESULT_KEY_GUID "Guid" /* as */
|
||||
#define FWUPD_RESULT_KEY_INSTANCE_IDS "InstanceIds" /* as */
|
||||
@ -43,6 +47,7 @@ G_BEGIN_DECLS
|
||||
#define FWUPD_RESULT_KEY_SIZE "Size" /* t */
|
||||
#define FWUPD_RESULT_KEY_STATUS "Status" /* u */
|
||||
#define FWUPD_RESULT_KEY_SUMMARY "Summary" /* s */
|
||||
#define FWUPD_RESULT_KEY_BRANCH "Branch" /* s */
|
||||
#define FWUPD_RESULT_KEY_TRUST_FLAGS "TrustFlags" /* t */
|
||||
#define FWUPD_RESULT_KEY_UPDATE_MESSAGE "UpdateMessage" /* s */
|
||||
#define FWUPD_RESULT_KEY_UPDATE_IMAGE "UpdateImage" /* s */
|
||||
|
||||
@ -197,6 +197,10 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag)
|
||||
return "updatable-hidden";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_SKIPS_RESTART)
|
||||
return "skips-restart";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES)
|
||||
return "has-multiple-branches";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL)
|
||||
return "backup-before-install";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
|
||||
return "unknown";
|
||||
return NULL;
|
||||
@ -295,6 +299,88 @@ fwupd_device_flag_from_string (const gchar *device_flag)
|
||||
return FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN;
|
||||
if (g_strcmp0 (device_flag, "skips-restart") == 0)
|
||||
return FWUPD_DEVICE_FLAG_SKIPS_RESTART;
|
||||
if (g_strcmp0 (device_flag, "has-multiple-branches") == 0)
|
||||
return FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES;
|
||||
if (g_strcmp0 (device_flag, "backup-before-install") == 0)
|
||||
return FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL;
|
||||
return FWUPD_DEVICE_FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_flag_to_string:
|
||||
* @plugin_flag: A #FwupdPluginFlags, e.g. %FWUPD_DEVICE_FLAG_REQUIRE_AC
|
||||
*
|
||||
* Converts a #FwupdDeviceFlags to a string.
|
||||
*
|
||||
* Return value: identifier string
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_plugin_flag_to_string (FwupdPluginFlags plugin_flag)
|
||||
{
|
||||
if (plugin_flag == FWUPD_DEVICE_FLAG_NONE)
|
||||
return "none";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_DISABLED)
|
||||
return "disabled";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_USER_WARNING)
|
||||
return "user-warning";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_CLEAR_UPDATABLE)
|
||||
return "clear-updatable";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_NO_HARDWARE)
|
||||
return "no-hardware";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_CAPSULES_UNSUPPORTED)
|
||||
return "capsules-unsupported";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_UNLOCK_REQUIRED)
|
||||
return "unlock-required";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_EFIVAR_NOT_MOUNTED)
|
||||
return "efivar-not-mounted";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND)
|
||||
return "esp-not-found";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_LEGACY_BIOS)
|
||||
return "legacy-bios";
|
||||
if (plugin_flag == FWUPD_PLUGIN_FLAG_FAILED_OPEN)
|
||||
return "failed-open";
|
||||
if (plugin_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
|
||||
return "unknown";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_flag_from_string:
|
||||
* @plugin_flag: A string, e.g. `require-ac`
|
||||
*
|
||||
* Converts a string to a #FwupdPluginFlags.
|
||||
*
|
||||
* Return value: enumerated value
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdPluginFlags
|
||||
fwupd_plugin_flag_from_string (const gchar *plugin_flag)
|
||||
{
|
||||
if (g_strcmp0 (plugin_flag, "none") == 0)
|
||||
return FWUPD_DEVICE_FLAG_NONE;
|
||||
if (g_strcmp0 (plugin_flag, "disabled") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_DISABLED;
|
||||
if (g_strcmp0 (plugin_flag, "user-warning") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_USER_WARNING;
|
||||
if (g_strcmp0 (plugin_flag, "clear-updatable") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_CLEAR_UPDATABLE;
|
||||
if (g_strcmp0 (plugin_flag, "no-hardware") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_NO_HARDWARE;
|
||||
if (g_strcmp0 (plugin_flag, "capsules-unsupported") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_CAPSULES_UNSUPPORTED;
|
||||
if (g_strcmp0 (plugin_flag, "unlock-required") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_UNLOCK_REQUIRED;
|
||||
if (g_strcmp0 (plugin_flag, "efivar-not-mounted") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_EFIVAR_NOT_MOUNTED;
|
||||
if (g_strcmp0 (plugin_flag, "esp-not-found") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND;
|
||||
if (g_strcmp0 (plugin_flag, "legacy-bios") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_LEGACY_BIOS;
|
||||
if (g_strcmp0 (plugin_flag, "failed-open") == 0)
|
||||
return FWUPD_PLUGIN_FLAG_FAILED_OPEN;
|
||||
return FWUPD_DEVICE_FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -419,6 +505,8 @@ fwupd_feature_flag_to_string (FwupdFeatureFlags feature_flag)
|
||||
return "detach-action";
|
||||
if (feature_flag == FWUPD_FEATURE_FLAG_UPDATE_ACTION)
|
||||
return "update-action";
|
||||
if (feature_flag == FWUPD_FEATURE_FLAG_SWITCH_BRANCH)
|
||||
return "switch-branch";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -443,6 +531,8 @@ fwupd_feature_flag_from_string (const gchar *feature_flag)
|
||||
return FWUPD_FEATURE_FLAG_DETACH_ACTION;
|
||||
if (g_strcmp0 (feature_flag, "update-action") == 0)
|
||||
return FWUPD_FEATURE_FLAG_UPDATE_ACTION;
|
||||
if (g_strcmp0 (feature_flag, "switch-branch") == 0)
|
||||
return FWUPD_FEATURE_FLAG_SWITCH_BRANCH;
|
||||
return FWUPD_FEATURE_FLAG_LAST;
|
||||
}
|
||||
|
||||
@ -521,6 +611,8 @@ fwupd_release_flag_to_string (FwupdReleaseFlags release_flag)
|
||||
return "blocked-version";
|
||||
if (release_flag == FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL)
|
||||
return "blocked-approval";
|
||||
if (release_flag == FWUPD_RELEASE_FLAG_IS_ALTERNATE_BRANCH)
|
||||
return "is-alternate-branch";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -549,6 +641,8 @@ fwupd_release_flag_from_string (const gchar *release_flag)
|
||||
return FWUPD_RELEASE_FLAG_BLOCKED_VERSION;
|
||||
if (g_strcmp0 (release_flag, "blocked-approval") == 0)
|
||||
return FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL;
|
||||
if (g_strcmp0 (release_flag, "is-alternate-branch") == 0)
|
||||
return FWUPD_RELEASE_FLAG_IS_ALTERNATE_BRANCH;
|
||||
return FWUPD_RELEASE_FLAG_NONE;
|
||||
}
|
||||
|
||||
@ -578,7 +672,7 @@ fwupd_release_urgency_to_string (FwupdReleaseUrgency release_urgency)
|
||||
|
||||
/**
|
||||
* fwupd_release_urgency_from_string:
|
||||
* @release_urgency: A string, e.g. `trusted-payload`
|
||||
* @release_urgency: A string, e.g. `low`
|
||||
*
|
||||
* Converts a string to an enumerated value.
|
||||
*
|
||||
|
||||
@ -70,6 +70,7 @@ typedef enum {
|
||||
* @FWUPD_FEATURE_FLAG_CAN_REPORT: Can upload a report of the update back to the server
|
||||
* @FWUPD_FEATURE_FLAG_DETACH_ACTION: Can perform detach action, typically showing text
|
||||
* @FWUPD_FEATURE_FLAG_UPDATE_ACTION: Can perform update action, typically showing text
|
||||
* @FWUPD_FEATURE_FLAG_SWITCH_BRANCH: Can switch the firmware branch
|
||||
*
|
||||
* The flags to the feature capabilities of the front-end client.
|
||||
**/
|
||||
@ -78,6 +79,7 @@ typedef enum {
|
||||
FWUPD_FEATURE_FLAG_CAN_REPORT = 1 << 0, /* Since: 1.4.5 */
|
||||
FWUPD_FEATURE_FLAG_DETACH_ACTION = 1 << 1, /* Since: 1.4.5 */
|
||||
FWUPD_FEATURE_FLAG_UPDATE_ACTION = 1 << 2, /* Since: 1.4.5 */
|
||||
FWUPD_FEATURE_FLAG_SWITCH_BRANCH = 1 << 3, /* Since: 1.5.0 */
|
||||
/*< private >*/
|
||||
FWUPD_FEATURE_FLAG_LAST
|
||||
} FwupdFeatureFlags;
|
||||
@ -88,7 +90,7 @@ typedef enum {
|
||||
* @FWUPD_DEVICE_FLAG_INTERNAL: Device cannot be removed easily
|
||||
* @FWUPD_DEVICE_FLAG_UPDATABLE: Device is updatable in this or any other mode
|
||||
* @FWUPD_DEVICE_FLAG_ONLY_OFFLINE: Update can only be done from offline mode
|
||||
* @FWUPD_DEVICE_FLAG_REQUIRE_AC: Requires AC power
|
||||
* @FWUPD_DEVICE_FLAG_REQUIRE_AC: System requires external power source
|
||||
* @FWUPD_DEVICE_FLAG_LOCKED: Is locked and can be unlocked
|
||||
* @FWUPD_DEVICE_FLAG_SUPPORTED: Is found in current metadata
|
||||
* @FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER: Requires a bootloader mode to be manually enabled by the user
|
||||
@ -124,6 +126,8 @@ typedef enum {
|
||||
* @FWUPD_DEVICE_FLAG_NO_GUID_MATCHING: Force an explicit ID match when adding devices to the device list
|
||||
* @FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN: Device is updatable but should not be called by the client
|
||||
* @FWUPD_DEVICE_FLAG_SKIPS_RESTART: Device relies upon activation or power cycle to load firmware
|
||||
* @FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES: Device supports switching to a different stream of firmware
|
||||
* @FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL: Device firmware should be saved before installing firmware
|
||||
*
|
||||
* The device flags.
|
||||
**/
|
||||
@ -166,7 +170,9 @@ typedef enum {
|
||||
#define FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS (1llu << 35) /* Since: 1.4.0 */
|
||||
#define FWUPD_DEVICE_FLAG_NO_GUID_MATCHING (1llu << 36) /* Since: 1.4.1 */
|
||||
#define FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN (1llu << 37) /* Since: 1.4.1 */
|
||||
#define FWUPD_DEVICE_FLAG_SKIPS_RESTART (1llu << 38) /* Since: 1.4.5 */
|
||||
#define FWUPD_DEVICE_FLAG_SKIPS_RESTART (1llu << 38) /* Since: 1.5.0 */
|
||||
#define FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES (1llu << 39) /* Since: 1.5.0 */
|
||||
#define FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL (1llu << 40) /* Since: 1.5.0 */
|
||||
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
|
||||
typedef guint64 FwupdDeviceFlags;
|
||||
|
||||
@ -179,6 +185,7 @@ typedef guint64 FwupdDeviceFlags;
|
||||
* @FWUPD_RELEASE_FLAG_IS_DOWNGRADE: Is older than the device version
|
||||
* @FWUPD_RELEASE_FLAG_BLOCKED_VERSION: Blocked as below device version-lowest
|
||||
* @FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL: Blocked as release not approved
|
||||
* @FWUPD_RELEASE_FLAG_IS_ALTERNATE_BRANCH: Is an alternate branch of firmware
|
||||
*
|
||||
* The release flags.
|
||||
**/
|
||||
@ -189,6 +196,7 @@ typedef guint64 FwupdDeviceFlags;
|
||||
#define FWUPD_RELEASE_FLAG_IS_DOWNGRADE (1u << 3) /* Since: 1.2.6 */
|
||||
#define FWUPD_RELEASE_FLAG_BLOCKED_VERSION (1u << 4) /* Since: 1.2.6 */
|
||||
#define FWUPD_RELEASE_FLAG_BLOCKED_APPROVAL (1u << 5) /* Since: 1.2.6 */
|
||||
#define FWUPD_RELEASE_FLAG_IS_ALTERNATE_BRANCH (1u << 6) /* Since: 1.5.0 */
|
||||
#define FWUPD_RELEASE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 1.2.6 */
|
||||
typedef guint64 FwupdReleaseFlags;
|
||||
|
||||
@ -212,6 +220,36 @@ typedef enum {
|
||||
FWUPD_RELEASE_URGENCY_LAST
|
||||
} FwupdReleaseUrgency;
|
||||
|
||||
/**
|
||||
* FwupdPluginFlags:
|
||||
* @FWUPD_PLUGIN_FLAG_NONE: No flags set
|
||||
* @FWUPD_PLUGIN_FLAG_DISABLED: Disabled
|
||||
* @FWUPD_PLUGIN_FLAG_USER_WARNING: Show the user a warning
|
||||
* @FWUPD_PLUGIN_FLAG_CLEAR_UPDATABLE: Clear the UPDATABLE flag from devices
|
||||
* @FWUPD_PLUGIN_FLAG_NO_HARDWARE: No hardware is found
|
||||
* @FWUPD_PLUGIN_FLAG_CAPSULES_UNSUPPORTED: UEFI UpdateCapsule are unsupported
|
||||
* @FWUPD_PLUGIN_FLAG_UNLOCK_REQUIRED: Hardware unlock is required
|
||||
* @FWUPD_PLUGIN_FLAG_EFIVAR_NOT_MOUNTED: The efivar filesystem is not found
|
||||
* @FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND: The EFI ESP not found
|
||||
* @FWUPD_PLUGIN_FLAG_LEGACY_BIOS: System running in legacy CSM mode
|
||||
* @FWUPD_PLUGIN_FLAG_FAILED_OPEN: Failed to open plugin (missing dependency)
|
||||
*
|
||||
* The plugin flags.
|
||||
**/
|
||||
#define FWUPD_PLUGIN_FLAG_NONE (0u) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_DISABLED (1u << 0) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_USER_WARNING (1u << 1) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_CLEAR_UPDATABLE (1u << 2) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_NO_HARDWARE (1u << 3) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_CAPSULES_UNSUPPORTED (1u << 4) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_UNLOCK_REQUIRED (1u << 5) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_EFIVAR_NOT_MOUNTED (1u << 6) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND (1u << 7) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_LEGACY_BIOS (1u << 8) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_FAILED_OPEN (1u << 9) /* Since: 1.5.0 */
|
||||
#define FWUPD_PLUGIN_FLAG_UNKNOWN G_MAXUINT64 /* Since: 1.5.0 */
|
||||
typedef guint64 FwupdPluginFlags;
|
||||
|
||||
/**
|
||||
* FwupdInstallFlags:
|
||||
* @FWUPD_INSTALL_FLAG_NONE: No flags set
|
||||
@ -220,8 +258,12 @@ typedef enum {
|
||||
* @FWUPD_INSTALL_FLAG_ALLOW_OLDER: Allow downgrading firmware
|
||||
* @FWUPD_INSTALL_FLAG_FORCE: Force the update even if not a good idea
|
||||
* @FWUPD_INSTALL_FLAG_NO_HISTORY: Do not write to the history database
|
||||
* @FWUPD_INSTALL_FLAG_ALLOW_BRANCH_SWITCH: Allow firmware branch switching
|
||||
* @FWUPD_INSTALL_FLAG_IGNORE_CHECKSUM: Ignore firmware CRCs and checksums
|
||||
* @FWUPD_INSTALL_FLAG_IGNORE_VID_PID: Ignore firmware vendor and project checks
|
||||
* @FWUPD_INSTALL_FLAG_IGNORE_POWER: Ignore requirement of external power source
|
||||
*
|
||||
* Flags to set when performing the firwmare update or install.
|
||||
* Flags to set when performing the firmware update or install.
|
||||
**/
|
||||
typedef enum {
|
||||
FWUPD_INSTALL_FLAG_NONE = 0, /* Since: 0.7.0 */
|
||||
@ -230,6 +272,10 @@ typedef enum {
|
||||
FWUPD_INSTALL_FLAG_ALLOW_OLDER = 1 << 2, /* Since: 0.7.0 */
|
||||
FWUPD_INSTALL_FLAG_FORCE = 1 << 3, /* Since: 0.7.1 */
|
||||
FWUPD_INSTALL_FLAG_NO_HISTORY = 1 << 4, /* Since: 1.0.8 */
|
||||
FWUPD_INSTALL_FLAG_ALLOW_BRANCH_SWITCH = 1 << 5, /* Since: 1.5.0 */
|
||||
FWUPD_INSTALL_FLAG_IGNORE_CHECKSUM = 1 << 6, /* Since: 1.5.0 */
|
||||
FWUPD_INSTALL_FLAG_IGNORE_VID_PID = 1 << 7, /* Since: 1.5.0 */
|
||||
FWUPD_INSTALL_FLAG_IGNORE_POWER = 1 << 8, /* Since: 1.5.0 */
|
||||
/*< private >*/
|
||||
FWUPD_INSTALL_FLAG_LAST
|
||||
} FwupdInstallFlags;
|
||||
@ -240,7 +286,7 @@ typedef enum {
|
||||
* @FWUPD_SELF_SIGN_FLAG_ADD_TIMESTAMP: Add the timestamp to the detached signature
|
||||
* @FWUPD_SELF_SIGN_FLAG_ADD_CERT: Add the certificate to the detached signature
|
||||
*
|
||||
* Flags to set when performing the firwmare update or install.
|
||||
* Flags to set when performing the firmware update or install.
|
||||
**/
|
||||
typedef enum {
|
||||
FWUPD_SELF_SIGN_FLAG_NONE = 0, /* Since: 1.2.6 */
|
||||
@ -335,6 +381,8 @@ const gchar *fwupd_status_to_string (FwupdStatus status);
|
||||
FwupdStatus fwupd_status_from_string (const gchar *status);
|
||||
const gchar *fwupd_device_flag_to_string (FwupdDeviceFlags device_flag);
|
||||
FwupdDeviceFlags fwupd_device_flag_from_string (const gchar *device_flag);
|
||||
const gchar *fwupd_plugin_flag_to_string (FwupdPluginFlags plugin_flag);
|
||||
FwupdPluginFlags fwupd_plugin_flag_from_string (const gchar *plugin_flag);
|
||||
const gchar *fwupd_release_flag_to_string (FwupdReleaseFlags release_flag);
|
||||
FwupdReleaseFlags fwupd_release_flag_from_string (const gchar *release_flag);
|
||||
const gchar *fwupd_release_urgency_to_string (FwupdReleaseUrgency release_urgency);
|
||||
|
||||
20
libfwupd/fwupd-plugin-private.h
Normal file
20
libfwupd/fwupd-plugin-private.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#include "fwupd-plugin.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GVariant *fwupd_plugin_to_variant (FwupdPlugin *plugin);
|
||||
void fwupd_plugin_to_json (FwupdPlugin *plugin,
|
||||
JsonBuilder *builder);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
484
libfwupd/fwupd-plugin.c
Normal file
484
libfwupd/fwupd-plugin.c
Normal file
@ -0,0 +1,484 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fwupd-enums-private.h"
|
||||
#include "fwupd-plugin-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:fwupd-plugin
|
||||
* @short_description: a hardware plugin
|
||||
*
|
||||
* An object that represents a fwupd plugin.
|
||||
*
|
||||
* See also: #FwupdRelease
|
||||
*/
|
||||
|
||||
static void fwupd_plugin_finalize (GObject *object);
|
||||
|
||||
typedef struct {
|
||||
gchar *name;
|
||||
guint64 flags;
|
||||
} FwupdPluginPrivate;
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_FLAGS,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (FwupdPlugin, fwupd_plugin, G_TYPE_OBJECT)
|
||||
#define GET_PRIVATE(o) (fwupd_plugin_get_instance_private (o))
|
||||
|
||||
/**
|
||||
* fwupd_plugin_get_name:
|
||||
* @plugin: A #FwupdPlugin
|
||||
*
|
||||
* Gets the plugin name.
|
||||
*
|
||||
* Returns: the plugin name, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_plugin_get_name (FwupdPlugin *plugin)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_val_if_fail (FWUPD_IS_PLUGIN (plugin), NULL);
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_set_name:
|
||||
* @plugin: A #FwupdPlugin
|
||||
* @name: the plugin name, e.g. `bios`
|
||||
*
|
||||
* Sets the plugin name.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_plugin_set_name (FwupdPlugin *plugin, const gchar *name)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_if_fail (FWUPD_IS_PLUGIN (plugin));
|
||||
g_return_if_fail (name != NULL);
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
g_object_notify (G_OBJECT (plugin), "name");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_get_flags:
|
||||
* @plugin: A #FwupdPlugin
|
||||
*
|
||||
* Gets the plugin flags.
|
||||
*
|
||||
* Returns: the plugin flags, or 0 if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
guint64
|
||||
fwupd_plugin_get_flags (FwupdPlugin *plugin)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_val_if_fail (FWUPD_IS_PLUGIN (plugin), 0);
|
||||
return priv->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_set_flags:
|
||||
* @plugin: A #FwupdPlugin
|
||||
* @flags: the plugin flags, e.g. %FWUPD_PLUGIN_FLAG_CAPSULES_UNSUPPORTED
|
||||
*
|
||||
* Sets the plugin flags.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_plugin_set_flags (FwupdPlugin *plugin, guint64 flags)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_if_fail (FWUPD_IS_PLUGIN (plugin));
|
||||
if (priv->flags == flags)
|
||||
return;
|
||||
priv->flags = flags;
|
||||
g_object_notify (G_OBJECT (plugin), "flags");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_add_flag:
|
||||
* @plugin: A #FwupdPlugin
|
||||
* @flag: the #FwupdPluginFlags
|
||||
*
|
||||
* Adds a specific plugin flag to the plugin.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_plugin_add_flag (FwupdPlugin *plugin, FwupdPluginFlags flag)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_if_fail (FWUPD_IS_PLUGIN (plugin));
|
||||
if (flag == 0)
|
||||
return;
|
||||
if ((priv->flags & flag) > 0)
|
||||
return;
|
||||
priv->flags |= flag;
|
||||
g_object_notify (G_OBJECT (plugin), "flags");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_remove_flag:
|
||||
* @plugin: A #FwupdPlugin
|
||||
* @flag: the #FwupdPluginFlags
|
||||
*
|
||||
* Removes a specific plugin flag from the plugin.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_plugin_remove_flag (FwupdPlugin *plugin, FwupdPluginFlags flag)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_if_fail (FWUPD_IS_PLUGIN (plugin));
|
||||
if (flag == 0)
|
||||
return;
|
||||
if ((priv->flags & flag) == 0)
|
||||
return;
|
||||
priv->flags &= ~flag;
|
||||
g_object_notify (G_OBJECT (plugin), "flags");
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_has_flag:
|
||||
* @plugin: A #FwupdPlugin
|
||||
* @flag: the #FwupdPluginFlags
|
||||
*
|
||||
* Finds if the plugin has a specific plugin flag.
|
||||
*
|
||||
* Returns: %TRUE if the flag is set
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fwupd_plugin_has_flag (FwupdPlugin *plugin, FwupdPluginFlags flag)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_return_val_if_fail (FWUPD_IS_PLUGIN (plugin), FALSE);
|
||||
return (priv->flags & flag) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_to_variant:
|
||||
* @plugin: A #FwupdPlugin
|
||||
*
|
||||
* Creates a GVariant from the plugin data omitting sensitive fields
|
||||
*
|
||||
* Returns: the GVariant, or %NULL for error
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GVariant *
|
||||
fwupd_plugin_to_variant (FwupdPlugin *plugin)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_PLUGIN (plugin), NULL);
|
||||
|
||||
/* create an array with all the metadata in */
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
if (priv->name != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_NAME,
|
||||
g_variant_new_string (priv->name));
|
||||
}
|
||||
if (priv->flags > 0) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_FLAGS,
|
||||
g_variant_new_uint64 (priv->flags));
|
||||
}
|
||||
return g_variant_new ("a{sv}", &builder);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_from_key_value (FwupdPlugin *plugin, const gchar *key, GVariant *value)
|
||||
{
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME) == 0) {
|
||||
fwupd_plugin_set_name (plugin, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_FLAGS) == 0) {
|
||||
fwupd_plugin_set_flags (plugin, g_variant_get_uint64 (value));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value)
|
||||
{
|
||||
/* ignore */
|
||||
if (key == NULL || value == NULL)
|
||||
return;
|
||||
g_string_append_printf (str, " %s: ", key);
|
||||
for (gsize i = strlen (key); i < 20; i++)
|
||||
g_string_append (str, " ");
|
||||
g_string_append_printf (str, "%s\n", value);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_pad_kv_dfl (GString *str, const gchar *key, guint64 plugin_flags)
|
||||
{
|
||||
g_autoptr(GString) tmp = g_string_new ("");
|
||||
for (guint i = 0; i < 64; i++) {
|
||||
if ((plugin_flags & ((guint64) 1 << i)) == 0)
|
||||
continue;
|
||||
g_string_append_printf (tmp, "%s|",
|
||||
fwupd_plugin_flag_to_string ((guint64) 1 << i));
|
||||
}
|
||||
if (tmp->len == 0) {
|
||||
g_string_append (tmp, fwupd_plugin_flag_to_string (0));
|
||||
} else {
|
||||
g_string_truncate (tmp, tmp->len - 1);
|
||||
}
|
||||
fwupd_pad_kv_str (str, key, tmp->str);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_json_add_string (JsonBuilder *builder, const gchar *key, const gchar *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return;
|
||||
json_builder_set_member_name (builder, key);
|
||||
json_builder_add_string_value (builder, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_to_json:
|
||||
* @plugin: A #FwupdPlugin
|
||||
* @builder: A #JsonBuilder
|
||||
*
|
||||
* Adds a fwupd plugin to a JSON builder
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_plugin_to_json (FwupdPlugin *plugin, JsonBuilder *builder)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
|
||||
g_return_if_fail (FWUPD_IS_PLUGIN (plugin));
|
||||
g_return_if_fail (builder != NULL);
|
||||
|
||||
fwupd_plugin_json_add_string (builder, FWUPD_RESULT_KEY_NAME, priv->name);
|
||||
if (priv->flags != FWUPD_PLUGIN_FLAG_NONE) {
|
||||
json_builder_set_member_name (builder, FWUPD_RESULT_KEY_FLAGS);
|
||||
json_builder_begin_array (builder);
|
||||
for (guint i = 0; i < 64; i++) {
|
||||
const gchar *tmp;
|
||||
if ((priv->flags & ((guint64) 1 << i)) == 0)
|
||||
continue;
|
||||
tmp = fwupd_plugin_flag_to_string ((guint64) 1 << i);
|
||||
json_builder_add_string_value (builder, tmp);
|
||||
}
|
||||
json_builder_end_array (builder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_to_string:
|
||||
* @plugin: A #FwupdPlugin
|
||||
*
|
||||
* Builds a text representation of the object.
|
||||
*
|
||||
* Returns: text, or %NULL for invalid
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gchar *
|
||||
fwupd_plugin_to_string (FwupdPlugin *plugin)
|
||||
{
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
GString *str;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_PLUGIN (plugin), NULL);
|
||||
|
||||
str = g_string_new (NULL);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_NAME, priv->name);
|
||||
fwupd_pad_kv_dfl (str, FWUPD_RESULT_KEY_FLAGS, priv->flags);
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
FwupdPlugin *self = FWUPD_PLUGIN (object);
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (self);
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
g_value_set_uint64 (value, priv->flags);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
FwupdPlugin *self = FWUPD_PLUGIN (object);
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
fwupd_plugin_set_name (self, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
fwupd_plugin_set_flags (self, g_value_get_uint64 (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_class_init (FwupdPluginClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = fwupd_plugin_finalize;
|
||||
object_class->get_property = fwupd_plugin_get_property;
|
||||
object_class->set_property = fwupd_plugin_set_property;
|
||||
|
||||
pspec = g_param_spec_string ("name", NULL, NULL, NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_uint64 ("flags", NULL, NULL,
|
||||
FWUPD_PLUGIN_FLAG_NONE,
|
||||
FWUPD_PLUGIN_FLAG_UNKNOWN,
|
||||
FWUPD_PLUGIN_FLAG_NONE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_FLAGS, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_init (FwupdPlugin *plugin)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_finalize (GObject *object)
|
||||
{
|
||||
FwupdPlugin *plugin = FWUPD_PLUGIN (object);
|
||||
FwupdPluginPrivate *priv = GET_PRIVATE (plugin);
|
||||
g_free (priv->name);
|
||||
G_OBJECT_CLASS (fwupd_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_plugin_set_from_variant_iter (FwupdPlugin *plugin, GVariantIter *iter)
|
||||
{
|
||||
GVariant *value;
|
||||
const gchar *key;
|
||||
while (g_variant_iter_next (iter, "{&sv}", &key, &value)) {
|
||||
fwupd_plugin_from_key_value (plugin, key, value);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_from_variant:
|
||||
* @value: a #GVariant
|
||||
*
|
||||
* Creates a new plugin using packed data.
|
||||
*
|
||||
* Returns: (transfer full): a new #FwupdPlugin, or %NULL if @value was invalid
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdPlugin *
|
||||
fwupd_plugin_from_variant (GVariant *value)
|
||||
{
|
||||
FwupdPlugin *plugin = NULL;
|
||||
const gchar *type_string;
|
||||
g_autoptr(GVariantIter) iter = NULL;
|
||||
|
||||
/* format from GetDetails */
|
||||
type_string = g_variant_get_type_string (value);
|
||||
if (g_strcmp0 (type_string, "(a{sv})") == 0) {
|
||||
plugin = fwupd_plugin_new ();
|
||||
g_variant_get (value, "(a{sv})", &iter);
|
||||
fwupd_plugin_set_from_variant_iter (plugin, iter);
|
||||
} else if (g_strcmp0 (type_string, "a{sv}") == 0) {
|
||||
plugin = fwupd_plugin_new ();
|
||||
g_variant_get (value, "a{sv}", &iter);
|
||||
fwupd_plugin_set_from_variant_iter (plugin, iter);
|
||||
} else {
|
||||
g_warning ("type %s not known", type_string);
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_array_from_variant:
|
||||
* @value: a #GVariant
|
||||
*
|
||||
* Creates an array of new plugins using packed data.
|
||||
*
|
||||
* Returns: (transfer container) (element-type FwupdPlugin): plugins, or %NULL if @value was invalid
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GPtrArray *
|
||||
fwupd_plugin_array_from_variant (GVariant *value)
|
||||
{
|
||||
GPtrArray *array = NULL;
|
||||
gsize sz;
|
||||
g_autoptr(GVariant) untuple = NULL;
|
||||
|
||||
array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
untuple = g_variant_get_child_value (value, 0);
|
||||
sz = g_variant_n_children (untuple);
|
||||
for (guint i = 0; i < sz; i++) {
|
||||
FwupdPlugin *plugin;
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
data = g_variant_get_child_value (untuple, i);
|
||||
plugin = fwupd_plugin_from_variant (data);
|
||||
if (plugin == NULL)
|
||||
continue;
|
||||
g_ptr_array_add (array, plugin);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_plugin_new:
|
||||
*
|
||||
* Creates a new plugin.
|
||||
*
|
||||
* Returns: a new #FwupdPlugin
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdPlugin *
|
||||
fwupd_plugin_new (void)
|
||||
{
|
||||
FwupdPlugin *plugin;
|
||||
plugin = g_object_new (FWUPD_TYPE_PLUGIN, NULL);
|
||||
return FWUPD_PLUGIN (plugin);
|
||||
}
|
||||
50
libfwupd/fwupd-plugin.h
Normal file
50
libfwupd/fwupd-plugin.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "fwupd-enums.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FWUPD_TYPE_PLUGIN (fwupd_plugin_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (FwupdPlugin, fwupd_plugin, FWUPD, PLUGIN, GObject)
|
||||
|
||||
struct _FwupdPluginClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
/*< private >*/
|
||||
void (*_fwupd_reserved1) (void);
|
||||
void (*_fwupd_reserved2) (void);
|
||||
void (*_fwupd_reserved3) (void);
|
||||
void (*_fwupd_reserved4) (void);
|
||||
void (*_fwupd_reserved5) (void);
|
||||
void (*_fwupd_reserved6) (void);
|
||||
void (*_fwupd_reserved7) (void);
|
||||
};
|
||||
|
||||
FwupdPlugin *fwupd_plugin_new (void);
|
||||
gchar *fwupd_plugin_to_string (FwupdPlugin *plugin);
|
||||
|
||||
const gchar *fwupd_plugin_get_name (FwupdPlugin *plugin);
|
||||
void fwupd_plugin_set_name (FwupdPlugin *plugin,
|
||||
const gchar *name);
|
||||
guint64 fwupd_plugin_get_flags (FwupdPlugin *plugin);
|
||||
void fwupd_plugin_set_flags (FwupdPlugin *plugin,
|
||||
guint64 flags);
|
||||
void fwupd_plugin_add_flag (FwupdPlugin *plugin,
|
||||
FwupdPluginFlags flag);
|
||||
void fwupd_plugin_remove_flag (FwupdPlugin *plugin,
|
||||
FwupdPluginFlags flag);
|
||||
gboolean fwupd_plugin_has_flag (FwupdPlugin *plugin,
|
||||
FwupdPluginFlags flag);
|
||||
|
||||
FwupdPlugin *fwupd_plugin_from_variant (GVariant *value);
|
||||
GPtrArray *fwupd_plugin_array_from_variant (GVariant *value);
|
||||
|
||||
G_END_DECLS
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2015-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
@ -46,6 +46,7 @@ typedef struct {
|
||||
gchar *name;
|
||||
gchar *name_variant_suffix;
|
||||
gchar *summary;
|
||||
gchar *branch;
|
||||
gchar *uri;
|
||||
gchar *vendor;
|
||||
gchar *version;
|
||||
@ -934,6 +935,42 @@ fwupd_release_set_summary (FwupdRelease *release, const gchar *summary)
|
||||
priv->summary = g_strdup (summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_release_get_branch:
|
||||
* @release: A #FwupdRelease
|
||||
*
|
||||
* Gets the update branch.
|
||||
*
|
||||
* Returns: the alternate branch, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_release_get_branch (FwupdRelease *release)
|
||||
{
|
||||
FwupdReleasePrivate *priv = GET_PRIVATE (release);
|
||||
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
|
||||
return priv->branch;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_release_set_branch:
|
||||
* @release: A #FwupdRelease
|
||||
* @branch: the update one line branch
|
||||
*
|
||||
* Sets the alternate branch.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_release_set_branch (FwupdRelease *release, const gchar *branch)
|
||||
{
|
||||
FwupdReleasePrivate *priv = GET_PRIVATE (release);
|
||||
g_return_if_fail (FWUPD_IS_RELEASE (release));
|
||||
g_free (priv->branch);
|
||||
priv->branch = g_strdup (branch);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_release_get_vendor:
|
||||
* @release: A #FwupdRelease
|
||||
@ -1354,6 +1391,11 @@ fwupd_release_to_variant (FwupdRelease *release)
|
||||
FWUPD_RESULT_KEY_SUMMARY,
|
||||
g_variant_new_string (priv->summary));
|
||||
}
|
||||
if (priv->branch != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_BRANCH,
|
||||
g_variant_new_string (priv->branch));
|
||||
}
|
||||
if (priv->description != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_DESCRIPTION,
|
||||
@ -1492,6 +1534,10 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
|
||||
fwupd_release_set_summary (release, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_BRANCH) == 0) {
|
||||
fwupd_release_set_branch (release, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) {
|
||||
fwupd_release_set_description (release, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
@ -1675,6 +1721,7 @@ fwupd_release_to_json (FwupdRelease *release, JsonBuilder *builder)
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_REMOTE_ID, priv->remote_id);
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_SUMMARY, priv->summary);
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_BRANCH, priv->branch);
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_VERSION, priv->version);
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_FILENAME, priv->filename);
|
||||
fwupd_release_json_add_string (builder, FWUPD_RESULT_KEY_PROTOCOL, priv->protocol);
|
||||
@ -1764,6 +1811,7 @@ fwupd_release_to_string (FwupdRelease *release)
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_REMOTE_ID, priv->remote_id);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SUMMARY, priv->summary);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_BRANCH, priv->branch);
|
||||
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);
|
||||
@ -1844,6 +1892,7 @@ fwupd_release_finalize (GObject *object)
|
||||
g_free (priv->name);
|
||||
g_free (priv->name_variant_suffix);
|
||||
g_free (priv->summary);
|
||||
g_free (priv->branch);
|
||||
g_free (priv->uri);
|
||||
g_free (priv->homepage);
|
||||
g_free (priv->details_url);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2018 Richard Hughes <richard@hughsie.com>
|
||||
* Copyright (C) 2015-2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
@ -90,6 +90,9 @@ void fwupd_release_set_name_variant_suffix (FwupdRelease *release,
|
||||
const gchar *fwupd_release_get_summary (FwupdRelease *release);
|
||||
void fwupd_release_set_summary (FwupdRelease *release,
|
||||
const gchar *summary);
|
||||
const gchar *fwupd_release_get_branch (FwupdRelease *release);
|
||||
void fwupd_release_set_branch (FwupdRelease *release,
|
||||
const gchar *branch);
|
||||
const gchar *fwupd_release_get_description (FwupdRelease *release);
|
||||
void fwupd_release_set_description (FwupdRelease *release,
|
||||
const gchar *description);
|
||||
|
||||
@ -32,6 +32,7 @@ typedef struct {
|
||||
gchar *id;
|
||||
gchar *firmware_base_uri;
|
||||
gchar *report_uri;
|
||||
gchar *security_report_uri;
|
||||
gchar *metadata_uri;
|
||||
gchar *metadata_uri_sig;
|
||||
gchar *username;
|
||||
@ -50,6 +51,7 @@ typedef struct {
|
||||
gchar **order_before;
|
||||
gchar *remotes_dir;
|
||||
gboolean automatic_reports;
|
||||
gboolean automatic_security_reports;
|
||||
} FwupdRemotePrivate;
|
||||
|
||||
enum {
|
||||
@ -58,6 +60,7 @@ enum {
|
||||
PROP_ENABLED,
|
||||
PROP_APPROVAL_REQUIRED,
|
||||
PROP_AUTOMATIC_REPORTS,
|
||||
PROP_AUTOMATIC_SECURITY_REPORTS,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@ -252,6 +255,13 @@ fwupd_remote_set_report_uri (FwupdRemote *self, const gchar *report_uri)
|
||||
priv->report_uri = g_strdup (report_uri);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_remote_set_security_report_uri (FwupdRemote *self, const gchar *security_report_uri)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
priv->security_report_uri = g_strdup (security_report_uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_kind_from_string:
|
||||
* @kind: a string, e.g. `download`
|
||||
@ -343,6 +353,7 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
g_autofree gchar *order_after = NULL;
|
||||
g_autofree gchar *order_before = NULL;
|
||||
g_autofree gchar *report_uri = NULL;
|
||||
g_autofree gchar *security_report_uri = NULL;
|
||||
g_autoptr(GKeyFile) kf = NULL;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE);
|
||||
@ -415,8 +426,14 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
|
||||
if (report_uri != NULL && report_uri[0] != '\0')
|
||||
fwupd_remote_set_report_uri (self, report_uri);
|
||||
|
||||
/* security reporting is optional */
|
||||
security_report_uri = g_key_file_get_string (kf, group, "SecurityReportURI", NULL);
|
||||
if (security_report_uri != NULL && security_report_uri[0] != '\0')
|
||||
fwupd_remote_set_security_report_uri (self, security_report_uri);
|
||||
|
||||
/* automatic report uploading */
|
||||
priv->automatic_reports = g_key_file_get_boolean (kf, group, "AutomaticReports", NULL);
|
||||
priv->automatic_security_reports = g_key_file_get_boolean (kf, group, "AutomaticSecurityReports", NULL);
|
||||
|
||||
/* DOWNLOAD-type remotes */
|
||||
if (priv->kind == FWUPD_REMOTE_KIND_DOWNLOAD) {
|
||||
@ -879,6 +896,24 @@ fwupd_remote_get_report_uri (FwupdRemote *self)
|
||||
return priv->report_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_get_security_report_uri:
|
||||
* @self: A #FwupdRemote
|
||||
*
|
||||
* Gets the URI for the security report.
|
||||
*
|
||||
* Returns: (transfer none): a URI, or %NULL for invalid.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_remote_get_security_report_uri (FwupdRemote *self)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
|
||||
return priv->security_report_uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_get_metadata_uri:
|
||||
* @self: A #FwupdRemote
|
||||
@ -1069,6 +1104,24 @@ fwupd_remote_get_automatic_reports (FwupdRemote *self)
|
||||
return priv->automatic_reports;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_get_automatic_security_reports:
|
||||
* @self: A #FwupdRemote
|
||||
*
|
||||
* Gets if security reports should be automatically uploaded to this remote
|
||||
*
|
||||
* Returns: a #TRUE if the remote should have reports uploaded automatically
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fwupd_remote_get_automatic_security_reports (FwupdRemote *self)
|
||||
{
|
||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE);
|
||||
return priv->automatic_security_reports;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_remote_get_approval_required:
|
||||
* @self: A #FwupdRemote
|
||||
@ -1133,6 +1186,8 @@ fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
|
||||
fwupd_remote_set_filename_source (self, g_variant_get_string (value, NULL));
|
||||
if (g_strcmp0 (key, "ReportUri") == 0)
|
||||
fwupd_remote_set_report_uri (self, g_variant_get_string (value, NULL));
|
||||
if (g_strcmp0 (key, "SecurityReportUri") == 0)
|
||||
fwupd_remote_set_security_report_uri (self, g_variant_get_string (value, NULL));
|
||||
}
|
||||
while (g_variant_iter_loop (iter3, "{sv}", &key, &value)) {
|
||||
if (g_strcmp0 (key, "Username") == 0) {
|
||||
@ -1157,6 +1212,8 @@ fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
|
||||
fwupd_remote_set_firmware_base_uri (self, g_variant_get_string (value, NULL));
|
||||
} else if (g_strcmp0 (key, "AutomaticReports") == 0) {
|
||||
priv->automatic_reports = g_variant_get_boolean (value);
|
||||
} else if (g_strcmp0 (key, "AutomaticSecurityReports") == 0) {
|
||||
priv->automatic_security_reports = g_variant_get_boolean (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1213,6 +1270,10 @@ fwupd_remote_to_variant (FwupdRemote *self)
|
||||
g_variant_builder_add (&builder, "{sv}", "ReportUri",
|
||||
g_variant_new_string (priv->report_uri));
|
||||
}
|
||||
if (priv->security_report_uri != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}", "SecurityReportUri",
|
||||
g_variant_new_string (priv->security_report_uri));
|
||||
}
|
||||
if (priv->firmware_base_uri != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}", "FirmwareBaseUri",
|
||||
g_variant_new_string (priv->firmware_base_uri));
|
||||
@ -1251,6 +1312,8 @@ fwupd_remote_to_variant (FwupdRemote *self)
|
||||
g_variant_new_boolean (priv->approval_required));
|
||||
g_variant_builder_add (&builder, "{sv}", "AutomaticReports",
|
||||
g_variant_new_boolean (priv->automatic_reports));
|
||||
g_variant_builder_add (&builder, "{sv}", "AutomaticSecurityReports",
|
||||
g_variant_new_boolean (priv->automatic_security_reports));
|
||||
return g_variant_new ("a{sv}", &builder);
|
||||
}
|
||||
|
||||
@ -1274,6 +1337,9 @@ fwupd_remote_get_property (GObject *obj, guint prop_id,
|
||||
case PROP_AUTOMATIC_REPORTS:
|
||||
g_value_set_boolean (value, priv->automatic_reports);
|
||||
break;
|
||||
case PROP_AUTOMATIC_SECURITY_REPORTS:
|
||||
g_value_set_boolean (value, priv->automatic_security_reports);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
|
||||
break;
|
||||
@ -1300,6 +1366,9 @@ fwupd_remote_set_property (GObject *obj, guint prop_id,
|
||||
case PROP_AUTOMATIC_REPORTS:
|
||||
priv->automatic_reports = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_AUTOMATIC_SECURITY_REPORTS:
|
||||
priv->automatic_security_reports = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
|
||||
break;
|
||||
@ -1360,6 +1429,17 @@ fwupd_remote_class_init (FwupdRemoteClass *klass)
|
||||
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_AUTOMATIC_REPORTS, pspec);
|
||||
|
||||
/**
|
||||
* FwupdRemote:automatic-security-reports:
|
||||
*
|
||||
* The behavior for auto-uploading security reports.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("automatic-security-reports", NULL, NULL,
|
||||
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
||||
g_object_class_install_property (object_class, PROP_AUTOMATIC_SECURITY_REPORTS, pspec);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1378,6 +1458,7 @@ fwupd_remote_finalize (GObject *obj)
|
||||
g_free (priv->metadata_uri_sig);
|
||||
g_free (priv->firmware_base_uri);
|
||||
g_free (priv->report_uri);
|
||||
g_free (priv->security_report_uri);
|
||||
g_free (priv->username);
|
||||
g_free (priv->password);
|
||||
g_free (priv->title);
|
||||
|
||||
@ -60,11 +60,13 @@ const gchar *fwupd_remote_get_filename_cache_sig (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_filename_source (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_firmware_base_uri (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_report_uri (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_security_report_uri (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_metadata_uri (FwupdRemote *self);
|
||||
const gchar *fwupd_remote_get_metadata_uri_sig (FwupdRemote *self);
|
||||
gboolean fwupd_remote_get_enabled (FwupdRemote *self);
|
||||
gboolean fwupd_remote_get_approval_required (FwupdRemote *self);
|
||||
gboolean fwupd_remote_get_automatic_reports (FwupdRemote *self);
|
||||
gboolean fwupd_remote_get_automatic_security_reports (FwupdRemote *self);
|
||||
gint fwupd_remote_get_priority (FwupdRemote *self);
|
||||
guint64 fwupd_remote_get_age (FwupdRemote *self);
|
||||
FwupdRemoteKind fwupd_remote_get_kind (FwupdRemote *self);
|
||||
|
||||
52
libfwupd/fwupd-security-attr-private.h
Normal file
52
libfwupd/fwupd-security-attr-private.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#include "fwupd-security-attr.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FWUPD_SECURITY_ATTR_ID_ACPI_DMAR "org.fwupd.hsi.AcpiDmar" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_ENCRYPTED_RAM "org.fwupd.hsi.EncryptedRam" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_FWUPD_ATTESTATION "org.fwupd.hsi.Fwupd.Attestation" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_FWUPD_PLUGINS "org.fwupd.hsi.Fwupd.Plugins" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_FWUPD_UPDATES "org.fwupd.hsi.Fwupd.Updates" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_BOOTGUARD_ENABLED "org.fwupd.hsi.IntelBootguard.Enabled" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_BOOTGUARD_VERIFIED "org.fwupd.hsi.IntelBootguard.Verified" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_BOOTGUARD_ACM "org.fwupd.hsi.IntelBootguard.Acm" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_BOOTGUARD_POLICY "org.fwupd.hsi.IntelBootguard.Policy" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_BOOTGUARD_OTP "org.fwupd.hsi.IntelBootguard.Otp" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_CET_ENABLED "org.fwupd.hsi.IntelCet.Enabled" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_CET_ACTIVE "org.fwupd.hsi.IntelCet.Active" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_SMAP "org.fwupd.hsi.IntelSmap" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_IOMMU "org.fwupd.hsi.Iommu" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_KERNEL_LOCKDOWN "org.fwupd.hsi.Kernel.Lockdown" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_KERNEL_SWAP "org.fwupd.hsi.Kernel.Swap" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_KERNEL_TAINTED "org.fwupd.hsi.Kernel.Tainted" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_MEI_MANUFACTURING_MODE "org.fwupd.hsi.Mei.ManufacturingMode" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_MEI_OVERRIDE_STRAP "org.fwupd.hsi.Mei.OverrideStrap" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_MEI_VERSION "org.fwupd.hsi.Mei.Version" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_SPI_BIOSWE "org.fwupd.hsi.Spi.Bioswe" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_SPI_BLE "org.fwupd.hsi.Spi.Ble" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_SPI_SMM_BWP "org.fwupd.hsi.Spi.SmmBwp" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_SUSPEND_TO_IDLE "org.fwupd.hsi.SuspendToIdle" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_SUSPEND_TO_RAM "org.fwupd.hsi.SuspendToRam" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_TPM_RECONSTRUCTION_PCR0 "org.fwupd.hsi.Tpm.ReconstructionPcr0" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_TPM_VERSION_20 "org.fwupd.hsi.Tpm.Version20" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_UEFI_SECUREBOOT "org.fwupd.hsi.Uefi.SecureBoot" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_DCI_ENABLED "org.fwupd.hsi.IntelDci.Enabled" /* Since: 1.5.0 */
|
||||
#define FWUPD_SECURITY_ATTR_ID_INTEL_DCI_LOCKED "org.fwupd.hsi.IntelDci.Locked" /* Since: 1.5.0 */
|
||||
|
||||
GVariant *fwupd_security_attr_to_variant (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_to_json (FwupdSecurityAttr *self,
|
||||
JsonBuilder *builder);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
916
libfwupd/fwupd-security-attr.c
Normal file
916
libfwupd/fwupd-security-attr.c
Normal file
@ -0,0 +1,916 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "fwupd-common-private.h"
|
||||
#include "fwupd-enums-private.h"
|
||||
#include "fwupd-security-attr-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:fwupd-security-attr
|
||||
*
|
||||
* An object that represents an Host Security ID attribute.
|
||||
*/
|
||||
|
||||
static void fwupd_security_attr_finalize (GObject *object);
|
||||
|
||||
typedef struct {
|
||||
gchar *appstream_id;
|
||||
GPtrArray *obsoletes;
|
||||
GHashTable *metadata; /* (nullable) */
|
||||
gchar *name;
|
||||
gchar *plugin;
|
||||
gchar *url;
|
||||
FwupdSecurityAttrLevel level;
|
||||
FwupdSecurityAttrResult result;
|
||||
FwupdSecurityAttrFlags flags;
|
||||
} FwupdSecurityAttrPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (FwupdSecurityAttr, fwupd_security_attr, G_TYPE_OBJECT)
|
||||
#define GET_PRIVATE(o) (fwupd_security_attr_get_instance_private (o))
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_flag_to_string:
|
||||
* @flag: A #FwupdSecurityAttrFlags, e.g. %FWUPD_SECURITY_ATTR_FLAG_SUCCESS
|
||||
*
|
||||
* Returns the printable string for the flag.
|
||||
*
|
||||
* Returns: string, or %NULL
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_flag_to_string (FwupdSecurityAttrFlags flag)
|
||||
{
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_NONE)
|
||||
return "none";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_SUCCESS)
|
||||
return "success";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_OBSOLETED)
|
||||
return "obsoleted";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES)
|
||||
return "runtime-updates";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION)
|
||||
return "runtime-attestation";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE)
|
||||
return "runtime-issue";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_result_to_string:
|
||||
* @result: A #FwupdSecurityAttrResult, e.g. %FWUPD_SECURITY_ATTR_RESULT_ENABLED
|
||||
*
|
||||
* Returns the printable string for the result enum.
|
||||
*
|
||||
* Returns: string, or %NULL
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_result_to_string (FwupdSecurityAttrResult result)
|
||||
{
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_VALID)
|
||||
return "valid";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_VALID)
|
||||
return "not-valid";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_ENABLED)
|
||||
return "enabled";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED)
|
||||
return "not-enabled";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_LOCKED)
|
||||
return "locked";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED)
|
||||
return "not-locked";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_ENCRYPTED)
|
||||
return "encrypted";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_ENCRYPTED)
|
||||
return "not-encrypted";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_TAINTED)
|
||||
return "tainted";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_TAINTED)
|
||||
return "not-tainted";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_FOUND)
|
||||
return "found";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_FOUND)
|
||||
return "not-found";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_SUPPORTED)
|
||||
return "supported";
|
||||
if (result == FWUPD_SECURITY_ATTR_RESULT_NOT_SUPPORTED)
|
||||
return "not-supported";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_flag_to_suffix:
|
||||
* @flag: A #FwupdSecurityAttrFlags, e.g. %FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES
|
||||
*
|
||||
* Returns the string suffix for the flag.
|
||||
*
|
||||
* Returns: string, or %NULL
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_flag_to_suffix (FwupdSecurityAttrFlags flag)
|
||||
{
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES)
|
||||
return "U";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION)
|
||||
return "A";
|
||||
if (flag == FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE)
|
||||
return "!";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_obsoletes:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the list of attribute obsoletes. The obsoleted attributes will not
|
||||
* contribute to the calculated HSI value or be visible in command line tools.
|
||||
*
|
||||
* Returns: (element-type utf8) (transfer none): the obsoletes, which may be empty
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GPtrArray *
|
||||
fwupd_security_attr_get_obsoletes (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
return priv->obsoletes;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_add_obsolete:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @appstream_id: the appstream_id or plugin name
|
||||
*
|
||||
* Adds an attribute appstream_id to obsolete. The obsoleted attribute will not
|
||||
* contribute to the calculated HSI value or be visible in command line tools.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_add_obsolete (FwupdSecurityAttr *self, const gchar *appstream_id)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
g_return_if_fail (appstream_id != NULL);
|
||||
if (fwupd_security_attr_has_obsolete (self, appstream_id))
|
||||
return;
|
||||
g_ptr_array_add (priv->obsoletes, g_strdup (appstream_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_has_obsolete:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @appstream_id: the attribute appstream_id
|
||||
*
|
||||
* Finds out if the attribute obsoletes a specific appstream_id.
|
||||
*
|
||||
* Returns: %TRUE if the self matches
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fwupd_security_attr_has_obsolete (FwupdSecurityAttr *self, const gchar *appstream_id)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), FALSE);
|
||||
g_return_val_if_fail (appstream_id != NULL, FALSE);
|
||||
for (guint i = 0; i < priv->obsoletes->len; i++) {
|
||||
const gchar *obsolete_tmp = g_ptr_array_index (priv->obsoletes, i);
|
||||
if (g_strcmp0 (obsolete_tmp, appstream_id) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_appstream_id:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the AppStream ID.
|
||||
*
|
||||
* Returns: the AppStream ID, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_get_appstream_id (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
return priv->appstream_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_appstream_id:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @appstream_id: the AppStream component ID, e.g. `com.intel.BiosGuard`
|
||||
*
|
||||
* Sets the AppStream ID.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_appstream_id (FwupdSecurityAttr *self, const gchar *appstream_id)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
|
||||
/* sanity check */
|
||||
if (!g_str_has_prefix (appstream_id, "org.fwupd.hsi."))
|
||||
g_critical ("HSI attributes need to have a 'org.fwupd.hsi.' prefix");
|
||||
|
||||
g_free (priv->appstream_id);
|
||||
priv->appstream_id = g_strdup (appstream_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_url:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the attribute URL.
|
||||
*
|
||||
* Returns: the attribute result, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_get_url (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
return priv->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_name:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @name: the attribute name
|
||||
*
|
||||
* Sets the attribute name.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_name (FwupdSecurityAttr *self, const gchar *name)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_plugin:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @plugin: the plugin name
|
||||
*
|
||||
* Sets the plugin that created the attribute.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_plugin (FwupdSecurityAttr *self, const gchar *plugin)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
g_free (priv->plugin);
|
||||
priv->plugin = g_strdup (plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_url:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @url: the attribute URL
|
||||
*
|
||||
* Sets the attribute result.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_url (FwupdSecurityAttr *self, const gchar *url)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
g_free (priv->url);
|
||||
priv->url = g_strdup (url);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_name:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the attribute name.
|
||||
*
|
||||
* Returns: the attribute name, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_get_name (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_plugin:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the plugin that created the attribute.
|
||||
*
|
||||
* Returns: the plugin name, or %NULL if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_get_plugin (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
return priv->plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_flags:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the self flags.
|
||||
*
|
||||
* Returns: the self flags, or 0 if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdSecurityAttrFlags
|
||||
fwupd_security_attr_get_flags (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), 0);
|
||||
return priv->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_flags:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @flags: the self flags, e.g. %FWUPD_SECURITY_ATTR_FLAG_OBSOLETED
|
||||
*
|
||||
* Sets the self flags.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_flags (FwupdSecurityAttr *self, FwupdSecurityAttrFlags flags)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
priv->flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_add_flag:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @flag: the #FwupdSecurityAttrFlags
|
||||
*
|
||||
* Adds a specific self flag to the self.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_add_flag (FwupdSecurityAttr *self, FwupdSecurityAttrFlags flag)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
priv->flags |= flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_has_flag:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @flag: the #FwupdSecurityAttrFlags
|
||||
*
|
||||
* Finds if the self has a specific self flag.
|
||||
*
|
||||
* Returns: %TRUE if the flag is set
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fwupd_security_attr_has_flag (FwupdSecurityAttr *self, FwupdSecurityAttrFlags flag)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), FALSE);
|
||||
return (priv->flags & flag) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_level:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the HSI level.
|
||||
*
|
||||
* Returns: the #FwupdSecurityAttrLevel, or %FWUPD_SECURITY_ATTR_LEVEL_NONE if unset
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdSecurityAttrLevel
|
||||
fwupd_security_attr_get_level (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), 0);
|
||||
return priv->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_level:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @level: A #FwupdSecurityAttrLevel, e.g. %FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT
|
||||
*
|
||||
* Sets the HSI level. A @level of %FWUPD_SECURITY_ATTR_LEVEL_NONE is not used
|
||||
* for the HSI calculation.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_level (FwupdSecurityAttr *self, FwupdSecurityAttrLevel level)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
priv->level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_set_result:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @result: A #FwupdSecurityAttrResult, e.g. %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
|
||||
*
|
||||
* Sets the optional HSI result. This is required because some attributes may
|
||||
* be a "success" when something is `locked` or may be "failed" if `found`.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_set_result (FwupdSecurityAttr *self, FwupdSecurityAttrResult result)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
priv->result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_result:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Gets the optional HSI result.
|
||||
*
|
||||
* Returns: the #FwupdSecurityAttrResult, e.g %FWUPD_SECURITY_ATTR_LEVEL_LOCKED
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdSecurityAttrResult
|
||||
fwupd_security_attr_get_result (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), 0);
|
||||
return priv->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_to_variant:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Creates a GVariant from the self data.
|
||||
*
|
||||
* Returns: the GVariant, or %NULL for error
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GVariant *
|
||||
fwupd_security_attr_to_variant (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
if (priv->appstream_id != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_APPSTREAM_ID,
|
||||
g_variant_new_string (priv->appstream_id));
|
||||
}
|
||||
if (priv->name != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_NAME,
|
||||
g_variant_new_string (priv->name));
|
||||
}
|
||||
if (priv->url != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_URI,
|
||||
g_variant_new_string (priv->url));
|
||||
}
|
||||
if (priv->obsoletes->len > 0) {
|
||||
g_autofree const gchar **strv = g_new0 (const gchar *, priv->obsoletes->len + 1);
|
||||
for (guint i = 0; i < priv->obsoletes->len; i++)
|
||||
strv[i] = (const gchar *) g_ptr_array_index (priv->obsoletes, i);
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_CATEGORIES,
|
||||
g_variant_new_strv (strv, -1));
|
||||
}
|
||||
if (priv->flags != 0) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_FLAGS,
|
||||
g_variant_new_uint64 (priv->flags));
|
||||
}
|
||||
if (priv->level > 0) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_HSI_LEVEL,
|
||||
g_variant_new_uint32 (priv->level));
|
||||
}
|
||||
if (priv->result != FWUPD_SECURITY_ATTR_RESULT_UNKNOWN) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_HSI_RESULT,
|
||||
g_variant_new_uint32 (priv->result));
|
||||
}
|
||||
if (priv->metadata != NULL) {
|
||||
g_variant_builder_add (&builder, "{sv}",
|
||||
FWUPD_RESULT_KEY_METADATA,
|
||||
fwupd_hash_kv_to_variant (priv->metadata));
|
||||
}
|
||||
return g_variant_new ("a{sv}", &builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_get_metadata:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @key: metadata key
|
||||
*
|
||||
* Gets private metadata from the attribute which may be used in the name.
|
||||
*
|
||||
* Returns: (nullable): the metadata value, or %NULL if unfound
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
const gchar *
|
||||
fwupd_security_attr_get_metadata (FwupdSecurityAttr *self, const gchar *key)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
|
||||
if (priv->metadata == NULL)
|
||||
return NULL;
|
||||
return g_hash_table_lookup (priv->metadata, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_add_metadata:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @key: metadata key
|
||||
* @value: (nullable): metadata value
|
||||
*
|
||||
* Adds metadata to the attribute which may be used in the name.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_add_metadata (FwupdSecurityAttr *self,
|
||||
const gchar *key,
|
||||
const gchar *value)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
g_return_if_fail (key != NULL);
|
||||
|
||||
if (priv->metadata == NULL) {
|
||||
priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_free);
|
||||
}
|
||||
g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value));
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_from_key_value (FwupdSecurityAttr *self, const gchar *key, GVariant *value)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_APPSTREAM_ID) == 0) {
|
||||
fwupd_security_attr_set_appstream_id (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME) == 0) {
|
||||
fwupd_security_attr_set_name (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_URI) == 0) {
|
||||
fwupd_security_attr_set_url (self, g_variant_get_string (value, NULL));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_FLAGS) == 0) {
|
||||
fwupd_security_attr_set_flags (self, g_variant_get_uint64 (value));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_HSI_LEVEL) == 0) {
|
||||
fwupd_security_attr_set_level (self, g_variant_get_uint32 (value));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_HSI_RESULT) == 0) {
|
||||
fwupd_security_attr_set_result (self, g_variant_get_uint32 (value));
|
||||
return;
|
||||
}
|
||||
if (g_strcmp0 (key, FWUPD_RESULT_KEY_METADATA) == 0) {
|
||||
if (priv->metadata != NULL)
|
||||
g_hash_table_unref (priv->metadata);
|
||||
priv->metadata = fwupd_variant_to_hash_kv (value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value)
|
||||
{
|
||||
/* ignore */
|
||||
if (key == NULL || value == NULL)
|
||||
return;
|
||||
g_string_append_printf (str, " %s: ", key);
|
||||
for (gsize i = strlen (key); i < 20; i++)
|
||||
g_string_append (str, " ");
|
||||
g_string_append_printf (str, "%s\n", value);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_pad_kv_tfl (GString *str, const gchar *key, FwupdSecurityAttrFlags security_attr_flags)
|
||||
{
|
||||
g_autoptr(GString) tmp = g_string_new ("");
|
||||
for (guint i = 0; i < 64; i++) {
|
||||
if ((security_attr_flags & ((guint64) 1 << i)) == 0)
|
||||
continue;
|
||||
g_string_append_printf (tmp, "%s|",
|
||||
fwupd_security_attr_flag_to_string ((guint64) 1 << i));
|
||||
}
|
||||
if (tmp->len == 0) {
|
||||
g_string_append (tmp, fwupd_security_attr_flag_to_string (0));
|
||||
} else {
|
||||
g_string_truncate (tmp, tmp->len - 1);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_json_add_string (JsonBuilder *builder, const gchar *key, const gchar *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return;
|
||||
json_builder_set_member_name (builder, key);
|
||||
json_builder_add_string_value (builder, str);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_json_add_int (JsonBuilder *builder, const gchar *key, guint64 num)
|
||||
{
|
||||
if (num == 0)
|
||||
return;
|
||||
json_builder_set_member_name (builder, key);
|
||||
json_builder_add_int_value (builder, num);
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_to_json:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
* @builder: A #JsonBuilder
|
||||
*
|
||||
* Adds a fwupd self to a JSON builder
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fwupd_security_attr_to_json (FwupdSecurityAttr *self, JsonBuilder *builder)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (FWUPD_IS_SECURITY_ATTR (self));
|
||||
g_return_if_fail (builder != NULL);
|
||||
|
||||
fwupd_security_attr_json_add_string (builder, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id);
|
||||
fwupd_security_attr_json_add_int (builder, FWUPD_RESULT_KEY_HSI_LEVEL, priv->level);
|
||||
fwupd_security_attr_json_add_string (builder, FWUPD_RESULT_KEY_HSI_RESULT,
|
||||
fwupd_security_attr_result_to_string (priv->result));
|
||||
fwupd_security_attr_json_add_string (builder, FWUPD_RESULT_KEY_NAME, priv->name);
|
||||
fwupd_security_attr_json_add_string (builder, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
|
||||
fwupd_security_attr_json_add_string (builder, FWUPD_RESULT_KEY_URI, priv->url);
|
||||
if (priv->flags != FWUPD_SECURITY_ATTR_FLAG_NONE) {
|
||||
json_builder_set_member_name (builder, FWUPD_RESULT_KEY_FLAGS);
|
||||
json_builder_begin_array (builder);
|
||||
for (guint i = 0; i < 64; i++) {
|
||||
const gchar *tmp;
|
||||
if ((priv->flags & ((guint64) 1 << i)) == 0)
|
||||
continue;
|
||||
tmp = fwupd_security_attr_flag_to_string ((guint64) 1 << i);
|
||||
json_builder_add_string_value (builder, tmp);
|
||||
}
|
||||
json_builder_end_array (builder);
|
||||
}
|
||||
if (priv->metadata != NULL) {
|
||||
g_autoptr(GList) keys = g_hash_table_get_keys (priv->metadata);
|
||||
for (GList *l = keys; l != NULL; l = l->next) {
|
||||
const gchar *key = l->data;
|
||||
const gchar *value = g_hash_table_lookup (priv->metadata, key);
|
||||
fwupd_security_attr_json_add_string (builder, key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_to_string:
|
||||
* @self: A #FwupdSecurityAttr
|
||||
*
|
||||
* Builds a text representation of the object.
|
||||
*
|
||||
* Returns: text, or %NULL for invalid
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gchar *
|
||||
fwupd_security_attr_to_string (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
GString *str;
|
||||
|
||||
g_return_val_if_fail (FWUPD_IS_SECURITY_ATTR (self), NULL);
|
||||
|
||||
str = g_string_new ("");
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id);
|
||||
fwupd_pad_kv_int (str, FWUPD_RESULT_KEY_HSI_LEVEL, priv->level);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_HSI_RESULT,
|
||||
fwupd_security_attr_result_to_string (priv->result));
|
||||
if (priv->flags != FWUPD_SECURITY_ATTR_FLAG_NONE)
|
||||
fwupd_pad_kv_tfl (str, FWUPD_RESULT_KEY_FLAGS, priv->flags);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_NAME, priv->name);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
|
||||
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_URI, priv->url);
|
||||
for (guint i = 0; i < priv->obsoletes->len; i++) {
|
||||
const gchar *appstream_id = g_ptr_array_index (priv->obsoletes, i);
|
||||
fwupd_pad_kv_str (str, "Obsolete", appstream_id);
|
||||
}
|
||||
if (priv->metadata != NULL) {
|
||||
g_autoptr(GList) keys = g_hash_table_get_keys (priv->metadata);
|
||||
for (GList *l = keys; l != NULL; l = l->next) {
|
||||
const gchar *key = l->data;
|
||||
const gchar *value = g_hash_table_lookup (priv->metadata, key);
|
||||
fwupd_pad_kv_str (str, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_class_init (FwupdSecurityAttrClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->finalize = fwupd_security_attr_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_init (FwupdSecurityAttr *self)
|
||||
{
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
priv->obsoletes = g_ptr_array_new_with_free_func (g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_finalize (GObject *object)
|
||||
{
|
||||
FwupdSecurityAttr *self = FWUPD_SECURITY_ATTR (object);
|
||||
FwupdSecurityAttrPrivate *priv = GET_PRIVATE (self);
|
||||
|
||||
if (priv->metadata != NULL)
|
||||
g_hash_table_unref (priv->metadata);
|
||||
g_free (priv->appstream_id);
|
||||
g_free (priv->name);
|
||||
g_free (priv->plugin);
|
||||
g_free (priv->url);
|
||||
g_ptr_array_unref (priv->obsoletes);
|
||||
|
||||
G_OBJECT_CLASS (fwupd_security_attr_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
fwupd_security_attr_set_from_variant_iter (FwupdSecurityAttr *self, GVariantIter *iter)
|
||||
{
|
||||
GVariant *value;
|
||||
const gchar *key;
|
||||
while (g_variant_iter_next (iter, "{&sv}", &key, &value)) {
|
||||
fwupd_security_attr_from_key_value (self, key, value);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_from_variant:
|
||||
* @value: a #GVariant
|
||||
*
|
||||
* Creates a new self using packed data.
|
||||
*
|
||||
* Returns: (transfer full): a new #FwupdSecurityAttr, or %NULL if @value was invalid
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdSecurityAttr *
|
||||
fwupd_security_attr_from_variant (GVariant *value)
|
||||
{
|
||||
FwupdSecurityAttr *rel = NULL;
|
||||
const gchar *type_string;
|
||||
g_autoptr(GVariantIter) iter = NULL;
|
||||
|
||||
type_string = g_variant_get_type_string (value);
|
||||
if (g_strcmp0 (type_string, "(a{sv})") == 0) {
|
||||
rel = fwupd_security_attr_new (NULL);
|
||||
g_variant_get (value, "(a{sv})", &iter);
|
||||
fwupd_security_attr_set_from_variant_iter (rel, iter);
|
||||
} else if (g_strcmp0 (type_string, "a{sv}") == 0) {
|
||||
rel = fwupd_security_attr_new (NULL);
|
||||
g_variant_get (value, "a{sv}", &iter);
|
||||
fwupd_security_attr_set_from_variant_iter (rel, iter);
|
||||
} else {
|
||||
g_warning ("type %s not known", type_string);
|
||||
}
|
||||
return rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_array_from_variant:
|
||||
* @value: a #GVariant
|
||||
*
|
||||
* Creates an array of new security_attrs using packed data.
|
||||
*
|
||||
* Returns: (transfer container) (element-type FwupdSecurityAttr): attributes, or %NULL if @value was invalid
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GPtrArray *
|
||||
fwupd_security_attr_array_from_variant (GVariant *value)
|
||||
{
|
||||
GPtrArray *array = NULL;
|
||||
gsize sz;
|
||||
g_autoptr(GVariant) untuple = NULL;
|
||||
|
||||
array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
untuple = g_variant_get_child_value (value, 0);
|
||||
sz = g_variant_n_children (untuple);
|
||||
for (guint i = 0; i < sz; i++) {
|
||||
FwupdSecurityAttr *rel;
|
||||
g_autoptr(GVariant) data = NULL;
|
||||
data = g_variant_get_child_value (untuple, i);
|
||||
rel = fwupd_security_attr_from_variant (data);
|
||||
if (rel == NULL)
|
||||
continue;
|
||||
g_ptr_array_add (array, rel);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwupd_security_attr_new:
|
||||
* @appstream_id: (allow-none): the AppStream component ID, e.g. `com.intel.BiosGuard`
|
||||
*
|
||||
* Creates a new self.
|
||||
*
|
||||
* Returns: a new #FwupdSecurityAttr
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
FwupdSecurityAttr *
|
||||
fwupd_security_attr_new (const gchar *appstream_id)
|
||||
{
|
||||
FwupdSecurityAttr *self;
|
||||
self = g_object_new (FWUPD_TYPE_SECURITY_ATTR, NULL);
|
||||
if (appstream_id != NULL)
|
||||
fwupd_security_attr_set_appstream_id (self, appstream_id);
|
||||
return FWUPD_SECURITY_ATTR (self);
|
||||
}
|
||||
159
libfwupd/fwupd-security-attr.h
Normal file
159
libfwupd/fwupd-security-attr.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "fwupd-enums.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define FWUPD_TYPE_SECURITY_ATTR (fwupd_security_attr_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (FwupdSecurityAttr, fwupd_security_attr, FWUPD, SECURITY_ATTR, GObject)
|
||||
|
||||
struct _FwupdSecurityAttrClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
/*< private >*/
|
||||
void (*_fwupd_reserved1) (void);
|
||||
void (*_fwupd_reserved2) (void);
|
||||
void (*_fwupd_reserved3) (void);
|
||||
void (*_fwupd_reserved4) (void);
|
||||
void (*_fwupd_reserved5) (void);
|
||||
void (*_fwupd_reserved6) (void);
|
||||
void (*_fwupd_reserved7) (void);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FwupdSecurityAttrFlags:
|
||||
* @FWUPD_SECURITY_ATTR_FLAG_NONE: No flags set
|
||||
* @FWUPD_SECURITY_ATTR_FLAG_SUCCESS: Success
|
||||
* @FWUPD_SECURITY_ATTR_FLAG_OBSOLETED: Obsoleted by another attribute
|
||||
* @FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES: Suffix `U`
|
||||
* @FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION: Suffix `A`
|
||||
* @FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE: Suffix `!`
|
||||
*
|
||||
* The flags available for HSI attributes.
|
||||
**/
|
||||
typedef enum {
|
||||
FWUPD_SECURITY_ATTR_FLAG_NONE = 0,
|
||||
FWUPD_SECURITY_ATTR_FLAG_SUCCESS = 1 << 0,
|
||||
FWUPD_SECURITY_ATTR_FLAG_OBSOLETED = 1 << 1,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_UPDATES = 1 << 8,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ATTESTATION = 1 << 9,
|
||||
FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE = 1 << 10,
|
||||
} FwupdSecurityAttrFlags;
|
||||
|
||||
/**
|
||||
* FwupdSecurityAttrLevel:
|
||||
* @FWUPD_SECURITY_ATTR_LEVEL_NONE: Very few detected firmware protections
|
||||
* @FWUPD_SECURITY_ATTR_LEVEL_CRITICAL: The most basic of security protections
|
||||
* @FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT: Firmware security issues considered important
|
||||
* @FWUPD_SECURITY_ATTR_LEVEL_THEORETICAL: Firmware security issues that pose a theoretical concern
|
||||
* @FWUPD_SECURITY_ATTR_LEVEL_SYSTEM_PROTECTION: Out-of-band protection of the system firmware
|
||||
* @FWUPD_SECURITY_ATTR_LEVEL_SYSTEM_ATTESTATION: Out-of-band attestation of the system firmware
|
||||
*
|
||||
* The HSI level.
|
||||
**/
|
||||
typedef enum {
|
||||
FWUPD_SECURITY_ATTR_LEVEL_NONE = 0, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_LEVEL_CRITICAL = 1, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT = 2, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_LEVEL_THEORETICAL = 3, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_LEVEL_SYSTEM_PROTECTION = 4, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_LEVEL_SYSTEM_ATTESTATION = 5, /* Since: 1.5.0 */
|
||||
/*< private >*/
|
||||
FWUPD_SECURITY_ATTR_LEVEL_LAST = 6 /* perhaps increased in the future */
|
||||
} FwupdSecurityAttrLevel;
|
||||
|
||||
/**
|
||||
* FwupdSecurityAttrResult:
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_UNKNOWN: Not known
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_ENABLED: Enabled
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED: Not enabled
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_VALID: Valid
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_VALID: Not valid
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_LOCKED: Locked
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED: Not locked
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_ENCRYPTED: Encrypted
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_ENCRYPTED: Not encrypted
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_TAINTED: Tainted
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_TAINTED: Not tainted
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_FOUND: Found
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_FOUND: NOt found
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_SUPPORTED: Supported
|
||||
* @FWUPD_SECURITY_ATTR_RESULT_NOT_SUPPORTED: Not supported
|
||||
*
|
||||
* The HSI result.
|
||||
**/
|
||||
typedef enum {
|
||||
FWUPD_SECURITY_ATTR_RESULT_UNKNOWN, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_ENABLED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_VALID, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_VALID, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_LOCKED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_ENCRYPTED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_ENCRYPTED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_TAINTED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_TAINTED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_FOUND, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_FOUND, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_SUPPORTED, /* Since: 1.5.0 */
|
||||
FWUPD_SECURITY_ATTR_RESULT_NOT_SUPPORTED, /* Since: 1.5.0 */
|
||||
/*< private >*/
|
||||
FWUPD_SECURITY_ATTR_RESULT_LAST
|
||||
} FwupdSecurityAttrResult;
|
||||
|
||||
FwupdSecurityAttr *fwupd_security_attr_new (const gchar *appstream_id);
|
||||
gchar *fwupd_security_attr_to_string (FwupdSecurityAttr *self);
|
||||
|
||||
const gchar *fwupd_security_attr_get_appstream_id (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_appstream_id (FwupdSecurityAttr *self,
|
||||
const gchar *appstream_id);
|
||||
FwupdSecurityAttrLevel fwupd_security_attr_get_level (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_level (FwupdSecurityAttr *self,
|
||||
FwupdSecurityAttrLevel level);
|
||||
FwupdSecurityAttrResult fwupd_security_attr_get_result (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_result (FwupdSecurityAttr *self,
|
||||
FwupdSecurityAttrResult result);
|
||||
const gchar *fwupd_security_attr_get_name (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_name (FwupdSecurityAttr *self,
|
||||
const gchar *name);
|
||||
const gchar *fwupd_security_attr_get_plugin (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_plugin (FwupdSecurityAttr *self,
|
||||
const gchar *plugin);
|
||||
const gchar *fwupd_security_attr_get_url (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_url (FwupdSecurityAttr *self,
|
||||
const gchar *url);
|
||||
GPtrArray *fwupd_security_attr_get_obsoletes (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_add_obsolete (FwupdSecurityAttr *self,
|
||||
const gchar *appstream_id);
|
||||
gboolean fwupd_security_attr_has_obsolete (FwupdSecurityAttr *self,
|
||||
const gchar *appstream_id);
|
||||
const gchar *fwupd_security_attr_get_metadata (FwupdSecurityAttr *self,
|
||||
const gchar *key);
|
||||
void fwupd_security_attr_add_metadata (FwupdSecurityAttr *self,
|
||||
const gchar *key,
|
||||
const gchar *value);
|
||||
FwupdSecurityAttrFlags fwupd_security_attr_get_flags (FwupdSecurityAttr *self);
|
||||
void fwupd_security_attr_set_flags (FwupdSecurityAttr *self,
|
||||
FwupdSecurityAttrFlags flags);
|
||||
void fwupd_security_attr_add_flag (FwupdSecurityAttr *self,
|
||||
FwupdSecurityAttrFlags flag);
|
||||
gboolean fwupd_security_attr_has_flag (FwupdSecurityAttr *self,
|
||||
FwupdSecurityAttrFlags flag);
|
||||
const gchar *fwupd_security_attr_flag_to_string (FwupdSecurityAttrFlags flag);
|
||||
const gchar *fwupd_security_attr_flag_to_suffix (FwupdSecurityAttrFlags flag);
|
||||
const gchar *fwupd_security_attr_result_to_string (FwupdSecurityAttrResult result);
|
||||
|
||||
FwupdSecurityAttr *fwupd_security_attr_from_variant (GVariant *value);
|
||||
GPtrArray *fwupd_security_attr_array_from_variant (GVariant *value);
|
||||
|
||||
G_END_DECLS
|
||||
@ -12,6 +12,7 @@
|
||||
#endif
|
||||
|
||||
#include "fwupd-client.h"
|
||||
#include "fwupd-client-sync.h"
|
||||
#include "fwupd-common.h"
|
||||
#include "fwupd-enums.h"
|
||||
#include "fwupd-error.h"
|
||||
@ -147,6 +148,12 @@ fwupd_enums_func (void)
|
||||
break;
|
||||
g_assert_cmpint (fwupd_device_flag_from_string (tmp), ==, i);
|
||||
}
|
||||
for (guint64 i = 1; i < FWUPD_PLUGIN_FLAG_UNKNOWN; i *= 2) {
|
||||
const gchar *tmp = fwupd_plugin_flag_to_string (i);
|
||||
if (tmp == NULL)
|
||||
break;
|
||||
g_assert_cmpint (fwupd_plugin_flag_from_string (tmp), ==, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -14,10 +14,13 @@
|
||||
#define __FWUPD_H_INSIDE__
|
||||
|
||||
#include <libfwupd/fwupd-client.h>
|
||||
#include <libfwupd/fwupd-client-sync.h>
|
||||
#include <libfwupd/fwupd-common.h>
|
||||
#include <libfwupd/fwupd-device.h>
|
||||
#include <libfwupd/fwupd-plugin.h>
|
||||
#include <libfwupd/fwupd-enums.h>
|
||||
#include <libfwupd/fwupd-error.h>
|
||||
#include <libfwupd/fwupd-security-attr.h>
|
||||
#include <libfwupd/fwupd-release.h>
|
||||
#include <libfwupd/fwupd-remote.h>
|
||||
#include <libfwupd/fwupd-version.h>
|
||||
|
||||
@ -475,3 +475,144 @@ LIBFWUPD_1.4.6 {
|
||||
fwupd_client_set_blocked_firmware;
|
||||
local: *;
|
||||
} LIBFWUPD_1.4.5;
|
||||
|
||||
LIBFWUPD_1.5.0 {
|
||||
global:
|
||||
fwupd_client_activate_async;
|
||||
fwupd_client_activate_finish;
|
||||
fwupd_client_clear_results_async;
|
||||
fwupd_client_clear_results_finish;
|
||||
fwupd_client_connect_async;
|
||||
fwupd_client_connect_finish;
|
||||
fwupd_client_download_bytes_async;
|
||||
fwupd_client_download_bytes_finish;
|
||||
fwupd_client_get_approved_firmware_async;
|
||||
fwupd_client_get_approved_firmware_finish;
|
||||
fwupd_client_get_blocked_firmware_async;
|
||||
fwupd_client_get_blocked_firmware_finish;
|
||||
fwupd_client_get_details_bytes;
|
||||
fwupd_client_get_details_bytes_async;
|
||||
fwupd_client_get_details_bytes_finish;
|
||||
fwupd_client_get_device_by_id_async;
|
||||
fwupd_client_get_device_by_id_finish;
|
||||
fwupd_client_get_devices_async;
|
||||
fwupd_client_get_devices_by_guid_async;
|
||||
fwupd_client_get_devices_by_guid_finish;
|
||||
fwupd_client_get_devices_finish;
|
||||
fwupd_client_get_downgrades_async;
|
||||
fwupd_client_get_downgrades_finish;
|
||||
fwupd_client_get_history_async;
|
||||
fwupd_client_get_history_finish;
|
||||
fwupd_client_get_host_security_attrs;
|
||||
fwupd_client_get_host_security_attrs_async;
|
||||
fwupd_client_get_host_security_attrs_finish;
|
||||
fwupd_client_get_host_security_id;
|
||||
fwupd_client_get_plugins;
|
||||
fwupd_client_get_plugins_async;
|
||||
fwupd_client_get_plugins_finish;
|
||||
fwupd_client_get_releases_async;
|
||||
fwupd_client_get_releases_finish;
|
||||
fwupd_client_get_remote_by_id_async;
|
||||
fwupd_client_get_remote_by_id_finish;
|
||||
fwupd_client_get_remotes_async;
|
||||
fwupd_client_get_remotes_finish;
|
||||
fwupd_client_get_report_metadata;
|
||||
fwupd_client_get_report_metadata_async;
|
||||
fwupd_client_get_report_metadata_finish;
|
||||
fwupd_client_get_results_async;
|
||||
fwupd_client_get_results_finish;
|
||||
fwupd_client_get_upgrades_async;
|
||||
fwupd_client_get_upgrades_finish;
|
||||
fwupd_client_install_async;
|
||||
fwupd_client_install_bytes_async;
|
||||
fwupd_client_install_bytes_finish;
|
||||
fwupd_client_install_finish;
|
||||
fwupd_client_install_release_async;
|
||||
fwupd_client_install_release_finish;
|
||||
fwupd_client_modify_config_async;
|
||||
fwupd_client_modify_config_finish;
|
||||
fwupd_client_modify_device_async;
|
||||
fwupd_client_modify_device_finish;
|
||||
fwupd_client_modify_remote_async;
|
||||
fwupd_client_modify_remote_finish;
|
||||
fwupd_client_refresh_remote_async;
|
||||
fwupd_client_refresh_remote_finish;
|
||||
fwupd_client_self_sign_async;
|
||||
fwupd_client_self_sign_finish;
|
||||
fwupd_client_set_approved_firmware_async;
|
||||
fwupd_client_set_approved_firmware_finish;
|
||||
fwupd_client_set_blocked_firmware_async;
|
||||
fwupd_client_set_blocked_firmware_finish;
|
||||
fwupd_client_set_feature_flags_async;
|
||||
fwupd_client_set_feature_flags_finish;
|
||||
fwupd_client_unlock_async;
|
||||
fwupd_client_unlock_finish;
|
||||
fwupd_client_update_metadata_bytes_async;
|
||||
fwupd_client_update_metadata_bytes_finish;
|
||||
fwupd_client_upload_bytes_async;
|
||||
fwupd_client_upload_bytes_finish;
|
||||
fwupd_client_verify_async;
|
||||
fwupd_client_verify_finish;
|
||||
fwupd_client_verify_update_async;
|
||||
fwupd_client_verify_update_finish;
|
||||
fwupd_device_get_branch;
|
||||
fwupd_device_set_branch;
|
||||
fwupd_plugin_add_flag;
|
||||
fwupd_plugin_array_from_variant;
|
||||
fwupd_plugin_flag_from_string;
|
||||
fwupd_plugin_flag_to_string;
|
||||
fwupd_plugin_from_variant;
|
||||
fwupd_plugin_get_flags;
|
||||
fwupd_plugin_get_name;
|
||||
fwupd_plugin_get_type;
|
||||
fwupd_plugin_has_flag;
|
||||
fwupd_plugin_new;
|
||||
fwupd_plugin_remove_flag;
|
||||
fwupd_plugin_set_flags;
|
||||
fwupd_plugin_set_name;
|
||||
fwupd_plugin_to_json;
|
||||
fwupd_plugin_to_string;
|
||||
fwupd_plugin_to_variant;
|
||||
fwupd_release_get_branch;
|
||||
fwupd_release_set_branch;
|
||||
fwupd_remote_get_automatic_security_reports;
|
||||
fwupd_remote_get_security_report_uri;
|
||||
fwupd_security_attr_add_flag;
|
||||
fwupd_security_attr_add_metadata;
|
||||
fwupd_security_attr_add_obsolete;
|
||||
fwupd_security_attr_array_from_variant;
|
||||
fwupd_security_attr_flag_to_string;
|
||||
fwupd_security_attr_flag_to_suffix;
|
||||
fwupd_security_attr_from_variant;
|
||||
fwupd_security_attr_get_appstream_id;
|
||||
fwupd_security_attr_get_flags;
|
||||
fwupd_security_attr_get_level;
|
||||
fwupd_security_attr_get_metadata;
|
||||
fwupd_security_attr_get_name;
|
||||
fwupd_security_attr_get_obsoletes;
|
||||
fwupd_security_attr_get_plugin;
|
||||
fwupd_security_attr_get_result;
|
||||
fwupd_security_attr_get_type;
|
||||
fwupd_security_attr_get_url;
|
||||
fwupd_security_attr_has_flag;
|
||||
fwupd_security_attr_has_obsolete;
|
||||
fwupd_security_attr_new;
|
||||
fwupd_security_attr_result_to_string;
|
||||
fwupd_security_attr_set_appstream_id;
|
||||
fwupd_security_attr_set_flags;
|
||||
fwupd_security_attr_set_level;
|
||||
fwupd_security_attr_set_name;
|
||||
fwupd_security_attr_set_plugin;
|
||||
fwupd_security_attr_set_result;
|
||||
fwupd_security_attr_set_url;
|
||||
fwupd_security_attr_to_json;
|
||||
fwupd_security_attr_to_string;
|
||||
fwupd_security_attr_to_variant;
|
||||
local: *;
|
||||
} LIBFWUPD_1.4.6;
|
||||
|
||||
LIBFWUPD_1.5.1 {
|
||||
global:
|
||||
fwupd_device_add_child;
|
||||
local: *;
|
||||
} LIBFWUPD_1.5.0;
|
||||
|
||||
@ -15,13 +15,16 @@ install_headers(
|
||||
|
||||
install_headers([
|
||||
'fwupd-client.h',
|
||||
'fwupd-client-sync.h',
|
||||
'fwupd-common.h',
|
||||
'fwupd-deprecated.h',
|
||||
'fwupd-device.h',
|
||||
'fwupd-enums.h',
|
||||
'fwupd-error.h',
|
||||
'fwupd-remote.h',
|
||||
'fwupd-security-attr.h',
|
||||
'fwupd-release.h',
|
||||
'fwupd-plugin.h',
|
||||
fwupd_version_h,
|
||||
],
|
||||
subdir : 'fwupd-1/libfwupd',
|
||||
@ -33,11 +36,14 @@ fwupd = shared_library(
|
||||
'fwupd',
|
||||
sources : [
|
||||
'fwupd-client.c',
|
||||
'fwupd-client-sync.c',
|
||||
'fwupd-common.c',
|
||||
'fwupd-device.c',
|
||||
'fwupd-enums.c',
|
||||
'fwupd-error.c',
|
||||
'fwupd-security-attr.c',
|
||||
'fwupd-release.c',
|
||||
'fwupd-plugin.c',
|
||||
'fwupd-remote.c',
|
||||
],
|
||||
soversion : libfwupd_lt_current,
|
||||
@ -74,6 +80,8 @@ if get_option('introspection')
|
||||
sources : [
|
||||
'fwupd-client.c',
|
||||
'fwupd-client.h',
|
||||
'fwupd-client-sync.c',
|
||||
'fwupd-client-sync.h',
|
||||
'fwupd-common.c',
|
||||
'fwupd-common.h',
|
||||
'fwupd-common-private.h',
|
||||
@ -85,9 +93,15 @@ if get_option('introspection')
|
||||
'fwupd-enums-private.h',
|
||||
'fwupd-error.c',
|
||||
'fwupd-error.h',
|
||||
'fwupd-security-attr.c',
|
||||
'fwupd-security-attr.h',
|
||||
'fwupd-security-attr-private.h',
|
||||
'fwupd-release.c',
|
||||
'fwupd-release.h',
|
||||
'fwupd-release-private.h',
|
||||
'fwupd-plugin.c',
|
||||
'fwupd-plugin.h',
|
||||
'fwupd-plugin-private.h',
|
||||
'fwupd-remote.c',
|
||||
'fwupd-remote.h',
|
||||
'fwupd-remote-private.h',
|
||||
|
||||
@ -341,8 +341,11 @@ fu_cabinet_set_container_checksum_cb (XbBuilderFixup *builder_fixup,
|
||||
|
||||
/* verify it is correct */
|
||||
if (g_strcmp0 (xb_builder_node_get_text (csum), self->container_checksum) != 0) {
|
||||
g_debug ("invalid container checksum %s, fixing up to %s",
|
||||
xb_builder_node_get_text (csum), self->container_checksum);
|
||||
if (xb_builder_node_get_text (csum) != NULL) {
|
||||
g_warning ("invalid container checksum %s, fixing up to %s",
|
||||
xb_builder_node_get_text (csum),
|
||||
self->container_checksum);
|
||||
}
|
||||
xb_builder_node_set_text (csum, self->container_checksum, -1);
|
||||
}
|
||||
return TRUE;
|
||||
@ -485,7 +488,7 @@ fu_cabinet_build_silo (FuCabinet *self, GBytes *data, GError **error)
|
||||
g_autoptr(XbBuilderFixup) fixup2 = NULL;
|
||||
|
||||
/* verbose profiling */
|
||||
if (g_getenv ("FWUPD_VERBOSE") != NULL) {
|
||||
if (g_getenv ("FWUPD_XMLB_VERBOSE") != NULL) {
|
||||
xb_builder_set_profile_flags (self->builder,
|
||||
XB_SILO_PROFILE_FLAG_XPATH |
|
||||
XB_SILO_PROFILE_FLAG_DEBUG);
|
||||
@ -504,7 +507,6 @@ fu_cabinet_build_silo (FuCabinet *self, GBytes *data, GError **error)
|
||||
/* adds each metainfo file to the silo */
|
||||
for (guint i = 0; i < folders->len; i++) {
|
||||
GCabFolder *cabfolder = GCAB_FOLDER (g_ptr_array_index (folders, i));
|
||||
g_debug ("processing folder: %u/%u", i + 1, folders->len);
|
||||
if (!fu_cabinet_build_silo_folder (self, cabfolder, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -444,10 +444,8 @@ fu_common_version_verify_format (const gchar *version,
|
||||
return TRUE;
|
||||
|
||||
/* nothing we can check for */
|
||||
if (fmt == FWUPD_VERSION_FORMAT_UNKNOWN) {
|
||||
g_debug ("not checking %s as no version format set", version);
|
||||
if (fmt == FWUPD_VERSION_FORMAT_UNKNOWN)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* check the base format */
|
||||
fmt_guess = fu_common_version_guess_format (version);
|
||||
@ -484,6 +482,13 @@ fu_common_vercmp_full (const gchar *version_a,
|
||||
{
|
||||
if (fmt == FWUPD_VERSION_FORMAT_PLAIN)
|
||||
return g_strcmp0 (version_a, version_b);
|
||||
if (fmt == FWUPD_VERSION_FORMAT_HEX) {
|
||||
g_autofree gchar *hex_a = NULL;
|
||||
g_autofree gchar *hex_b = NULL;
|
||||
hex_a = fu_common_version_parse_from_format (version_a, fmt);
|
||||
hex_b = fu_common_version_parse_from_format (version_b, fmt);
|
||||
return fu_common_vercmp (hex_a, hex_b);
|
||||
}
|
||||
return fu_common_vercmp (version_a, version_b);
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
#include <shlwapi.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CPUID_H
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#include <archive_entry.h>
|
||||
#include <archive.h>
|
||||
#include <errno.h>
|
||||
@ -31,11 +35,12 @@
|
||||
#include "fu-common.h"
|
||||
#include "fu-volume-private.h"
|
||||
|
||||
#define UDISKS_DBUS_SERVICE "org.freedesktop.UDisks2"
|
||||
#define UDISKS_DBUS_PATH "/org/freedesktop/UDisks2/Manager"
|
||||
#define UDISKS_DBUS_MANAGER_INTERFACE "org.freedesktop.UDisks2.Manager"
|
||||
#define UDISKS_DBUS_PART_INTERFACE "org.freedesktop.UDisks2.Partition"
|
||||
#define UDISKS_DBUS_FILE_INTERFACE "org.freedesktop.UDisks2.Filesystem"
|
||||
#define UDISKS_DBUS_SERVICE "org.freedesktop.UDisks2"
|
||||
#define UDISKS_DBUS_PATH "/org/freedesktop/UDisks2/Manager"
|
||||
#define UDISKS_DBUS_MANAGER_INTERFACE "org.freedesktop.UDisks2.Manager"
|
||||
#define UDISKS_DBUS_INTERFACE_PARTITION "org.freedesktop.UDisks2.Partition"
|
||||
#define UDISKS_DBUS_INTERFACE_FILESYSTEM "org.freedesktop.UDisks2.Filesystem"
|
||||
#define UDISKS_DBUS_INTERFACE_BLOCK "org.freedesktop.UDisks2.Block"
|
||||
|
||||
/**
|
||||
* SECTION:fu-common
|
||||
@ -159,7 +164,8 @@ fu_common_mkdir_parent (const gchar *filename, GError **error)
|
||||
g_autofree gchar *parent = NULL;
|
||||
|
||||
parent = g_path_get_dirname (filename);
|
||||
g_debug ("creating path %s", parent);
|
||||
if (!g_file_test (parent, G_FILE_TEST_IS_DIR))
|
||||
g_debug ("creating path %s", parent);
|
||||
if (g_mkdir_with_parents (parent, 0755) == -1) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
@ -1033,6 +1039,12 @@ fu_common_get_path (FuPathKind path_kind)
|
||||
if (tmp != NULL)
|
||||
return g_build_filename (tmp, FWUPD_LOCALSTATEDIR, NULL);
|
||||
return g_build_filename (FWUPD_LOCALSTATEDIR, NULL);
|
||||
/* /proc */
|
||||
case FU_PATH_KIND_PROCFS:
|
||||
tmp = g_getenv ("FWUPD_PROCFS");
|
||||
if (tmp != NULL)
|
||||
return g_strdup (tmp);
|
||||
return g_strdup ("/proc");
|
||||
/* /sys/firmware */
|
||||
case FU_PATH_KIND_SYSFSDIR_FW:
|
||||
tmp = g_getenv ("FWUPD_SYSFSFWDIR");
|
||||
@ -1057,6 +1069,12 @@ fu_common_get_path (FuPathKind path_kind)
|
||||
if (tmp != NULL)
|
||||
return g_strdup (tmp);
|
||||
return g_strdup ("/sys/kernel/security");
|
||||
/* /sys/firmware/acpi/tables */
|
||||
case FU_PATH_KIND_ACPI_TABLES:
|
||||
tmp = g_getenv ("FWUPD_ACPITABLESDIR");
|
||||
if (tmp != NULL)
|
||||
return g_strdup (tmp);
|
||||
return g_strdup ("/sys/firmware/acpi/tables");
|
||||
/* /etc */
|
||||
case FU_PATH_KIND_SYSCONFDIR:
|
||||
tmp = g_getenv ("FWUPD_SYSCONFDIR");
|
||||
@ -1217,6 +1235,9 @@ fu_common_strwidth (const gchar *text)
|
||||
{
|
||||
const gchar *p = text;
|
||||
gsize width = 0;
|
||||
|
||||
g_return_val_if_fail (text != NULL, 0);
|
||||
|
||||
while (*p) {
|
||||
gunichar c = g_utf8_get_char (p);
|
||||
if (g_unichar_iswide (c))
|
||||
@ -1679,6 +1700,49 @@ fu_common_fnmatch (const gchar *pattern, const gchar *str)
|
||||
#endif
|
||||
}
|
||||
|
||||
static gint
|
||||
fu_common_filename_glob_sort_cb (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
return g_strcmp0 (*(const gchar **)a, *(const gchar **)b);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_filename_glob:
|
||||
* @directory: a directory path
|
||||
* @pattern: a glob pattern, e.g. `*foo*`
|
||||
* @error: A #GError or %NULL
|
||||
*
|
||||
* Returns all the filenames that match a specific glob pattern.
|
||||
* Any results are sorted. No matching files will set @error.
|
||||
*
|
||||
* Return value: (element-type utf8) (transfer container): matching files, or %NULL
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
GPtrArray *
|
||||
fu_common_filename_glob (const gchar *directory, const gchar *pattern, GError **error)
|
||||
{
|
||||
const gchar *basename;
|
||||
g_autoptr(GDir) dir = g_dir_open (directory, 0, error);
|
||||
g_autoptr(GPtrArray) files = g_ptr_array_new_with_free_func (g_free);
|
||||
if (dir == NULL)
|
||||
return NULL;
|
||||
while ((basename = g_dir_read_name (dir)) != NULL) {
|
||||
if (!fu_common_fnmatch (pattern, basename))
|
||||
continue;
|
||||
g_ptr_array_add (files, g_build_filename (directory, basename, NULL));
|
||||
}
|
||||
if (files->len == 0) {
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"no files matched pattern");
|
||||
return NULL;
|
||||
}
|
||||
g_ptr_array_sort (files, fu_common_filename_glob_sort_cb);
|
||||
return g_steal_pointer (&files);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_strnsplit:
|
||||
* @str: a string to split
|
||||
@ -1937,6 +2001,24 @@ fu_byte_array_append_uint32 (GByteArray *array, guint32 data, FuEndianType endia
|
||||
g_byte_array_append (array, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_byte_array_set_size:
|
||||
* @array: a #GByteArray
|
||||
* @length: the new size of the GByteArray
|
||||
*
|
||||
* Sets the size of the GByteArray, expanding it with NULs if necessary.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
void
|
||||
fu_byte_array_set_size (GByteArray *array, guint length)
|
||||
{
|
||||
guint oldlength = array->len;
|
||||
g_byte_array_set_size (array, length);
|
||||
if (length > oldlength)
|
||||
memset (array->data + oldlength, 0x0, length - oldlength);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_kernel_locked_down:
|
||||
*
|
||||
@ -1971,6 +2053,83 @@ fu_common_kernel_locked_down (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_cpuid:
|
||||
* @leaf: The CPUID level, now called the 'leaf' by Intel
|
||||
* @eax: (out) (nullable): EAX register
|
||||
* @ebx: (out) (nullable): EBX register
|
||||
* @ecx: (out) (nullable): ECX register
|
||||
* @edx: (out) (nullable): EDX register
|
||||
* @error: A #GError or NULL
|
||||
*
|
||||
* Calls CPUID and returns the registers for the given leaf.
|
||||
*
|
||||
* Return value: %TRUE if the registers are set.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fu_common_cpuid (guint32 leaf,
|
||||
guint32 *eax,
|
||||
guint32 *ebx,
|
||||
guint32 *ecx,
|
||||
guint32 *edx,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_CPUID_H
|
||||
guint eax_tmp = 0;
|
||||
guint ebx_tmp = 0;
|
||||
guint ecx_tmp = 0;
|
||||
guint edx_tmp = 0;
|
||||
|
||||
/* get vendor */
|
||||
__get_cpuid_count (leaf, 0x0, &eax_tmp, &ebx_tmp, &ecx_tmp, &edx_tmp);
|
||||
if (eax != NULL)
|
||||
*eax = eax_tmp;
|
||||
if (ebx != NULL)
|
||||
*ebx = ebx_tmp;
|
||||
if (ecx != NULL)
|
||||
*ecx = ecx_tmp;
|
||||
if (edx != NULL)
|
||||
*edx = edx_tmp;
|
||||
return TRUE;
|
||||
#else
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_SUPPORTED,
|
||||
"no <cpuid.h> support");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_is_cpu_intel:
|
||||
*
|
||||
* Uses CPUID to discover the CPU vendor and check if it is Intel.
|
||||
*
|
||||
* Return value: %TRUE if the vendor was Intel.
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
gboolean
|
||||
fu_common_is_cpu_intel (void)
|
||||
{
|
||||
guint ebx = 0;
|
||||
guint ecx = 0;
|
||||
guint edx = 0;
|
||||
|
||||
if (!fu_common_cpuid (0x0, NULL, &ebx, &ecx, &edx, NULL))
|
||||
return FALSE;
|
||||
#ifdef HAVE_CPUID_H
|
||||
if (ebx == signature_INTEL_ebx &&
|
||||
edx == signature_INTEL_edx &&
|
||||
ecx == signature_INTEL_ecx) {
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_is_live_media:
|
||||
*
|
||||
@ -2006,16 +2165,21 @@ fu_common_is_live_media (void)
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
fu_common_get_block_devices (GDBusConnection *connection, GError **error)
|
||||
fu_common_get_block_devices (GError **error)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
GVariant *input;
|
||||
const gchar *obj;
|
||||
g_autoptr(GVariant) output = NULL;
|
||||
g_autoptr(GDBusProxy) proxy = NULL;
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
g_autoptr(GVariantIter) iter = NULL;
|
||||
g_autoptr(GDBusConnection) connection = NULL;
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
|
||||
if (connection == NULL) {
|
||||
g_prefix_error (error, "failed to get system bus: ");
|
||||
return NULL;
|
||||
}
|
||||
proxy = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
UDISKS_DBUS_SERVICE,
|
||||
@ -2027,17 +2191,36 @@ fu_common_get_block_devices (GDBusConnection *connection, GError **error)
|
||||
return NULL;
|
||||
}
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
input = g_variant_new ("(a{sv})", &builder);
|
||||
output = g_dbus_proxy_call_sync (proxy,
|
||||
"GetBlockDevices", g_variant_ref (input),
|
||||
"GetBlockDevices",
|
||||
g_variant_new ("(a{sv})", &builder),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, error);
|
||||
if (output == NULL)
|
||||
if (output == NULL) {
|
||||
if (error != NULL)
|
||||
g_dbus_error_strip_remote_error (*error);
|
||||
g_prefix_error (error, "failed to call %s.%s(): ",
|
||||
UDISKS_DBUS_SERVICE,
|
||||
"GetBlockDevices");
|
||||
return NULL;
|
||||
devices = g_ptr_array_new_with_free_func (g_free);
|
||||
}
|
||||
devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
g_variant_get (output, "(ao)", &iter);
|
||||
while (g_variant_iter_next (iter, "o", &obj))
|
||||
g_ptr_array_add (devices, g_strdup (obj));
|
||||
while (g_variant_iter_next (iter, "&o", &obj)) {
|
||||
g_autoptr(GDBusProxy) proxy_blk = NULL;
|
||||
proxy_blk = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
UDISKS_DBUS_SERVICE,
|
||||
obj,
|
||||
UDISKS_DBUS_INTERFACE_BLOCK,
|
||||
NULL, error);
|
||||
if (proxy_blk == NULL) {
|
||||
g_prefix_error (error, "failed to initialize d-bus proxy for %s: ", obj);
|
||||
return NULL;
|
||||
}
|
||||
g_ptr_array_add (devices, g_steal_pointer (&proxy_blk));
|
||||
}
|
||||
|
||||
|
||||
return g_steal_pointer (&devices);
|
||||
}
|
||||
@ -2047,9 +2230,7 @@ fu_common_get_block_devices (GDBusConnection *connection, GError **error)
|
||||
* @kind: A volume kind, typically a GUID
|
||||
* @error: A #GError or NULL
|
||||
*
|
||||
* Call into the plugin's get results routine
|
||||
*
|
||||
* Finds all volumes of a specific type
|
||||
* Finds all volumes of a specific partition type
|
||||
*
|
||||
* Returns: (transfer container) (element-type FuVolume): a #GPtrArray, or %NULL if the kind was not found
|
||||
*
|
||||
@ -2058,56 +2239,56 @@ fu_common_get_block_devices (GDBusConnection *connection, GError **error)
|
||||
GPtrArray *
|
||||
fu_common_get_volumes_by_kind (const gchar *kind, GError **error)
|
||||
{
|
||||
g_autoptr(GDBusConnection) connection = NULL;
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
g_autoptr(GPtrArray) volumes = NULL;
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
|
||||
if (connection == NULL) {
|
||||
g_prefix_error (error, "failed to get system bus: ");
|
||||
return NULL;
|
||||
}
|
||||
devices = fu_common_get_block_devices (connection, error);
|
||||
devices = fu_common_get_block_devices (error);
|
||||
if (devices == NULL)
|
||||
return NULL;
|
||||
volumes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
for (guint i = 0; i < devices->len; i++) {
|
||||
const gchar *obj = g_ptr_array_index (devices, i);
|
||||
GDBusProxy *proxy_blk = g_ptr_array_index (devices, i);
|
||||
const gchar *type_str;
|
||||
g_autoptr(GDBusProxy) proxy_part = NULL;
|
||||
g_autoptr(GDBusProxy) proxy_file = NULL;
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GDBusProxy) proxy_fs = NULL;
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
|
||||
proxy_part = g_dbus_proxy_new_sync (connection,
|
||||
proxy_part = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy_blk),
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
UDISKS_DBUS_SERVICE,
|
||||
obj,
|
||||
UDISKS_DBUS_PART_INTERFACE,
|
||||
g_dbus_proxy_get_object_path (proxy_blk),
|
||||
UDISKS_DBUS_INTERFACE_PARTITION,
|
||||
NULL, error);
|
||||
if (proxy_part == NULL) {
|
||||
g_prefix_error (error, "failed to initialize d-bus proxy %s: ", obj);
|
||||
g_prefix_error (error, "failed to initialize d-bus proxy %s: ",
|
||||
g_dbus_proxy_get_object_path (proxy_blk));
|
||||
return NULL;
|
||||
}
|
||||
val = g_dbus_proxy_get_cached_property (proxy_part, "Type");
|
||||
if (val == NULL)
|
||||
continue;
|
||||
|
||||
g_variant_get (val, "s", &type_str);
|
||||
g_debug ("device %s, type: %s", obj, type_str);
|
||||
g_variant_get (val, "&s", &type_str);
|
||||
g_debug ("device %s, type: %s",
|
||||
g_dbus_proxy_get_object_path (proxy_blk), type_str);
|
||||
if (g_strcmp0 (type_str, kind) != 0)
|
||||
continue;
|
||||
proxy_file = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
UDISKS_DBUS_SERVICE,
|
||||
obj,
|
||||
UDISKS_DBUS_FILE_INTERFACE,
|
||||
NULL, error);
|
||||
if (proxy_file == NULL) {
|
||||
g_prefix_error (error, "failed to initialize d-bus proxy %s: ", obj);
|
||||
proxy_fs = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy_blk),
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
UDISKS_DBUS_SERVICE,
|
||||
g_dbus_proxy_get_object_path (proxy_blk),
|
||||
UDISKS_DBUS_INTERFACE_FILESYSTEM,
|
||||
NULL, error);
|
||||
if (proxy_fs == NULL) {
|
||||
g_prefix_error (error, "failed to initialize d-bus proxy %s: ",
|
||||
g_dbus_proxy_get_object_path (proxy_blk));
|
||||
return NULL;
|
||||
}
|
||||
g_ptr_array_add (volumes, fu_volume_new_from_proxy (proxy_file));
|
||||
g_ptr_array_add (volumes,
|
||||
g_object_new (FU_TYPE_VOLUME,
|
||||
"proxy-block", proxy_blk,
|
||||
"proxy-filesystem", proxy_fs,
|
||||
NULL));
|
||||
}
|
||||
if (volumes->len == 0) {
|
||||
g_set_error (error,
|
||||
@ -2119,6 +2300,90 @@ fu_common_get_volumes_by_kind (const gchar *kind, GError **error)
|
||||
return g_steal_pointer (&volumes);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_get_volume_by_device:
|
||||
* @device: A device string, typcically starting with `/dev/`
|
||||
* @error: A #GError or NULL
|
||||
*
|
||||
* Finds the first volume from the specified device.
|
||||
*
|
||||
* Returns: (transfer full): a #GPtrArray, or %NULL if the kind was not found
|
||||
*
|
||||
* Since: 1.5.1
|
||||
**/
|
||||
FuVolume *
|
||||
fu_common_get_volume_by_device (const gchar *device, GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
|
||||
/* find matching block device */
|
||||
devices = fu_common_get_block_devices (error);
|
||||
if (devices == NULL)
|
||||
return NULL;
|
||||
for (guint i = 0; i < devices->len; i++) {
|
||||
GDBusProxy *proxy_blk = g_ptr_array_index (devices, i);
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
val = g_dbus_proxy_get_cached_property (proxy_blk, "Device");
|
||||
if (val == NULL)
|
||||
continue;
|
||||
if (g_strcmp0 (g_variant_get_bytestring (val), device) == 0) {
|
||||
return g_object_new (FU_TYPE_VOLUME,
|
||||
"proxy-block", proxy_blk,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* failed */
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"no volumes for device %s",
|
||||
device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_get_volume_by_devnum:
|
||||
* @devicenum: A device number
|
||||
* @error: A #GError or NULL
|
||||
*
|
||||
* Finds the first volume from the specified device.
|
||||
*
|
||||
* Returns: (transfer full): a #GPtrArray, or %NULL if the kind was not found
|
||||
*
|
||||
* Since: 1.5.1
|
||||
**/
|
||||
FuVolume *
|
||||
fu_common_get_volume_by_devnum (guint32 devnum, GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) devices = NULL;
|
||||
|
||||
/* find matching block device */
|
||||
devices = fu_common_get_block_devices (error);
|
||||
if (devices == NULL)
|
||||
return NULL;
|
||||
for (guint i = 0; i < devices->len; i++) {
|
||||
GDBusProxy *proxy_blk = g_ptr_array_index (devices, i);
|
||||
g_autoptr(GVariant) val = NULL;
|
||||
val = g_dbus_proxy_get_cached_property (proxy_blk, "DeviceNumber");
|
||||
if (val == NULL)
|
||||
continue;
|
||||
if (devnum == g_variant_get_uint64 (val)) {
|
||||
return g_object_new (FU_TYPE_VOLUME,
|
||||
"proxy-block", proxy_blk,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* failed */
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"no volumes for devnum %u",
|
||||
devnum);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_get_esp_default:
|
||||
* @error: A #GError or NULL
|
||||
@ -2186,7 +2451,7 @@ fu_common_get_esp_for_path (const gchar *esp_path, GError **error)
|
||||
return NULL;
|
||||
for (guint i = 0; i < volumes->len; i++) {
|
||||
FuVolume *vol = g_ptr_array_index (volumes, i);
|
||||
g_autofree gchar *vol_basename = g_path_get_basename (fu_volume_get_id (vol));
|
||||
g_autofree gchar *vol_basename = g_path_get_basename (fu_volume_get_mount_point (vol));
|
||||
if (g_strcmp0 (basename, vol_basename) == 0)
|
||||
return g_object_ref (vol);
|
||||
}
|
||||
@ -2197,3 +2462,101 @@ fu_common_get_esp_for_path (const gchar *esp_path, GError **error)
|
||||
esp_path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_crc8:
|
||||
* @buf: memory buffer
|
||||
* @bufsz: sizeof buf
|
||||
*
|
||||
* Returns the cyclic redundancy check value for the given memory buffer.
|
||||
*
|
||||
* Returns: CRC value
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
guint8
|
||||
fu_common_crc8 (const guint8 *buf, gsize bufsz)
|
||||
{
|
||||
guint32 crc = 0;
|
||||
for (gsize j = bufsz; j > 0; j--) {
|
||||
crc ^= (*(buf++) << 8);
|
||||
for (guint32 i = 8; i; i--) {
|
||||
if (crc & 0x8000)
|
||||
crc ^= (0x1070 << 3);
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
return ~((guint8) (crc >> 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_crc16:
|
||||
* @buf: memory buffer
|
||||
* @bufsz: sizeof buf
|
||||
*
|
||||
* Returns the cyclic redundancy check value for the given memory buffer.
|
||||
*
|
||||
* Returns: CRC value
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
guint16
|
||||
fu_common_crc16 (const guint8 *buf, gsize bufsz)
|
||||
{
|
||||
guint16 crc = 0xffff;
|
||||
for (gsize len = bufsz; len > 0; len--) {
|
||||
crc = (guint16) (crc ^ (*buf++));
|
||||
for (guint8 i = 0; i < 8; i++) {
|
||||
if (crc & 0x1) {
|
||||
crc = (crc >> 1) ^ 0xa001;
|
||||
} else {
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_crc32_full:
|
||||
* @buf: memory buffer
|
||||
* @bufsz: sizeof buf
|
||||
* @crc: initial CRC value, typically 0xFFFFFFFF
|
||||
* @polynomial: CRC polynomial, typically 0xEDB88320
|
||||
*
|
||||
* Returns the cyclic redundancy check value for the given memory buffer.
|
||||
*
|
||||
* Returns: CRC value
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
guint32
|
||||
fu_common_crc32_full (const guint8 *buf, gsize bufsz, guint32 crc, guint32 polynomial)
|
||||
{
|
||||
for (guint32 idx = 0; idx < bufsz; idx++) {
|
||||
guint8 data = *buf++;
|
||||
crc = crc ^ data;
|
||||
for (guint32 bit = 0; bit < 8; bit++) {
|
||||
guint32 mask = -(crc & 1);
|
||||
crc = (crc >> 1) ^ (polynomial & mask);
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_common_crc32:
|
||||
* @buf: memory buffer
|
||||
* @bufsz: sizeof buf
|
||||
*
|
||||
* Returns the cyclic redundancy check value for the given memory buffer.
|
||||
*
|
||||
* Returns: CRC value
|
||||
*
|
||||
* Since: 1.5.0
|
||||
**/
|
||||
guint32
|
||||
fu_common_crc32 (const guint8 *buf, gsize bufsz)
|
||||
{
|
||||
return fu_common_crc32_full (buf, bufsz, 0xFFFFFFFF, 0xEDB88320);
|
||||
}
|
||||
|
||||
@ -55,9 +55,11 @@ typedef guint FuEndianType;
|
||||
* @FU_PATH_KIND_SYSFSDIR_FW: The sysfs firmware location (IE /sys/firmware)
|
||||
* @FU_PATH_KIND_SYSFSDIR_DRIVERS: The platform sysfs directory (IE /sys/bus/platform/drivers)
|
||||
* @FU_PATH_KIND_SYSFSDIR_TPM: The TPM sysfs directory (IE /sys/class/tpm)
|
||||
* @FU_PATH_KIND_PROCFS: The procfs location (IE /proc)
|
||||
* @FU_PATH_KIND_POLKIT_ACTIONS: The directory for policy kit actions (IE /usr/share/polkit-1/actions/)
|
||||
* @FU_PATH_KIND_OFFLINE_TRIGGER: The file for the offline trigger (IE /system-update)
|
||||
* @FU_PATH_KIND_SYSFSDIR_SECURITY: The sysfs security location (IE /sys/kernel/security)
|
||||
* @FU_PATH_KIND_ACPI_TABLES: The location of the ACPI tables
|
||||
*
|
||||
* Path types to use when dynamically determining a path at runtime
|
||||
**/
|
||||
@ -73,9 +75,11 @@ typedef enum {
|
||||
FU_PATH_KIND_SYSFSDIR_FW,
|
||||
FU_PATH_KIND_SYSFSDIR_DRIVERS,
|
||||
FU_PATH_KIND_SYSFSDIR_TPM,
|
||||
FU_PATH_KIND_PROCFS,
|
||||
FU_PATH_KIND_POLKIT_ACTIONS,
|
||||
FU_PATH_KIND_OFFLINE_TRIGGER,
|
||||
FU_PATH_KIND_SYSFSDIR_SECURITY,
|
||||
FU_PATH_KIND_ACPI_TABLES,
|
||||
/*< private >*/
|
||||
FU_PATH_KIND_LAST
|
||||
} FuPathKind;
|
||||
@ -93,6 +97,9 @@ gboolean fu_common_spawn_sync (const gchar * const *argv,
|
||||
gchar *fu_common_get_path (FuPathKind path_kind);
|
||||
gchar *fu_common_realpath (const gchar *filename,
|
||||
GError **error);
|
||||
GPtrArray *fu_common_filename_glob (const gchar *directory,
|
||||
const gchar *pattern,
|
||||
GError **error);
|
||||
gboolean fu_common_fnmatch (const gchar *pattern,
|
||||
const gchar *str);
|
||||
gboolean fu_common_rmtree (const gchar *directory,
|
||||
@ -175,6 +182,8 @@ gboolean fu_common_read_uint32_safe (const guint8 *buf,
|
||||
FuEndianType endian,
|
||||
GError **error);
|
||||
|
||||
void fu_byte_array_set_size (GByteArray *array,
|
||||
guint length);
|
||||
void fu_byte_array_append_uint8 (GByteArray *array,
|
||||
guint8 data);
|
||||
void fu_byte_array_append_uint16 (GByteArray *array,
|
||||
@ -219,9 +228,31 @@ gchar **fu_common_strnsplit (const gchar *str,
|
||||
const gchar *delimiter,
|
||||
gint max_tokens);
|
||||
gboolean fu_common_kernel_locked_down (void);
|
||||
gboolean fu_common_cpuid (guint32 leaf,
|
||||
guint32 *eax,
|
||||
guint32 *ebx,
|
||||
guint32 *ecx,
|
||||
guint32 *edx,
|
||||
GError **error);
|
||||
gboolean fu_common_is_cpu_intel (void);
|
||||
gboolean fu_common_is_live_media (void);
|
||||
GPtrArray *fu_common_get_volumes_by_kind (const gchar *kind,
|
||||
GError **error);
|
||||
FuVolume *fu_common_get_volume_by_device (const gchar *device,
|
||||
GError **error);
|
||||
FuVolume *fu_common_get_volume_by_devnum (guint32 devnum,
|
||||
GError **error);
|
||||
FuVolume *fu_common_get_esp_for_path (const gchar *esp_path,
|
||||
GError **error);
|
||||
FuVolume *fu_common_get_esp_default (GError **error);
|
||||
|
||||
guint8 fu_common_crc8 (const guint8 *buf,
|
||||
gsize bufsz);
|
||||
guint16 fu_common_crc16 (const guint8 *buf,
|
||||
gsize bufsz);
|
||||
guint32 fu_common_crc32 (const guint8 *buf,
|
||||
gsize bufsz);
|
||||
guint32 fu_common_crc32_full (const guint8 *buf,
|
||||
gsize bufsz,
|
||||
guint32 crc,
|
||||
guint32 polynomial);
|
||||
|
||||
@ -16,12 +16,11 @@ gboolean fu_device_has_parent_guid (FuDevice *self,
|
||||
const gchar *guid);
|
||||
void fu_device_set_parent (FuDevice *self,
|
||||
FuDevice *parent);
|
||||
guint fu_device_get_order (FuDevice *self);
|
||||
gint fu_device_get_order (FuDevice *self);
|
||||
void fu_device_set_order (FuDevice *self,
|
||||
guint order);
|
||||
gint order);
|
||||
void fu_device_set_alternate (FuDevice *self,
|
||||
FuDevice *alternate);
|
||||
GType fu_device_get_specialized_gtype (FuDevice *self);
|
||||
gboolean fu_device_ensure_id (FuDevice *self,
|
||||
GError **error);
|
||||
void fu_device_incorporate_from_component (FuDevice *device,
|
||||
@ -29,3 +28,5 @@ void fu_device_incorporate_from_component (FuDevice *device,
|
||||
void fu_device_convert_instance_ids (FuDevice *self);
|
||||
gchar *fu_device_get_guids_as_str (FuDevice *self);
|
||||
GPtrArray *fu_device_get_possible_plugins (FuDevice *self);
|
||||
void fu_device_add_possible_plugin (FuDevice *self,
|
||||
const gchar *plugin);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user