Release fwupd 1.3.2

-----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEEFj61ARkiXbPfj0nqF6y6jfqXDhcFAl2MjVIUHHJpY2hhcmRA
 aHVnaHNpZS5jb20ACgkQF6y6jfqXDhfDAQgAo3NxZyh8m0ZXJy7I+MeDFjHV6OFY
 67EPdfBZ6zFjfNZ/06DkOXc80Hi3EfopbhhBGjszzS+VuKFAG57swkMsP9U2GDIl
 wLu8T6+qwtIfc+Qw7Z4xRtpB8Y8DkcTuZG1/JR5c5i4enj5p5skilu+xXOWWLqbc
 DMGmo8vGeZYdqtrtAeNJgQiSv6vVO3OXrbaq0+z8B2rhNy0V5rqjAzPVRf/1G3AV
 jm8yg1sWETp1LbDzCBS/3Q/scYLTCDOmYzXcdQhmAvyBMO0PhWPZOPfZgOwp9waD
 SpaJ2CrdIV5KbscYdtKiS3U4OdPY/a6p2NtLPCFAOAF0hShrM/6e2ZzX8g==
 =w5wJ
 -----END PGP SIGNATURE-----

Merge tag '1.3.2' into debian

Release fwupd 1.3.2
This commit is contained in:
Mario Limonciello 2019-09-26 09:12:07 -05:00
commit fc705a8040
272 changed files with 13011 additions and 7038 deletions

View File

@ -1,25 +1,44 @@
version: 2
jobs:
build-s390x:
check-abi:
machine:
image: circleci/classic:latest
steps:
- checkout
- run:
name: "Build container"
command: OS=debian-s390x ./contrib/ci/generate_docker.py
command: OS=debian-x86_64 ./contrib/ci/generate_docker.py
- run:
name: "Run build script"
command: docker run --privileged -e CI=true -t -v `pwd`/dist:/build/dist fwupd-debian-s390x
command: docker run -t -v `pwd`:/build fwupd-debian-x86_64 ./contrib/ci/check-abi $(git describe --abbrev=0 --tags) $(git rev-parse HEAD)
build-ubuntu-x86_64:
machine:
image: circleci/classic:latest
steps:
- checkout
- run:
name: "Build container"
command: OS=ubuntu-x86_64 ./contrib/ci/generate_docker.py
- run:
name: "Run build script"
command: docker run --privileged -e CI=true -t -v `pwd`/dist:/build/dist fwupd-ubuntu-x86_64
- persist_to_workspace:
root: .
paths:
- "dist/docs"
build-snap:
docker:
- image: superm1/snapcraft-edge:latest
- image: ubuntu:18.04
steps:
- checkout
- run:
name: "Update apt"
command: apt update
- run:
name: "install snapcraft"
command: apt install snapcraft -y
- run:
name: "Build Snap"
command: snapcraft
@ -28,6 +47,31 @@ jobs:
paths:
- "*.snap"
publish-docs:
machine: true
steps:
- attach_workspace:
at: .
- add_ssh_keys:
fingerprints:
- "d8:73:05:1b:7c:93:8c:12:41:78:15:3d:5d:af:b4:c2"
- run:
name: Clone docs
working_directory: dist/docs
command: |
git clone --depth 1 git@github.com:fwupd/fwupd.github.io.git
- deploy:
name: Trigger docs deployment
working_directory: dist/docs/fwupd.github.io
command: |
git config credential.helper 'cache --timeout=120'
git config user.email "info@fwupd.org"
git config user.name "Documentation deployment Bot"
rm -rf *
cp ../html/* . -R
git commit -a --allow-empty -m "Trigger deployment"
git push git@github.com:fwupd/fwupd.github.io.git
publish-edge:
docker:
- image: cibuilds/snapcraft:stable
@ -58,8 +102,9 @@ workflows:
version: 2
main:
jobs:
- build-s390x
- build-ubuntu-x86_64
- build-snap
- check-abi
- publish-edge:
requires:
- build-snap
@ -68,6 +113,20 @@ workflows:
only: master
deploy:
jobs:
- build-ubuntu-x86_64:
filters:
branches:
ignore: /.*/
tags:
only: /^\d+\.\d+\.\d+$/
- publish-docs:
requires:
- build-ubuntu-x86_64
filters:
branches:
ignore: /.*/
tags:
only: /^\d+\.\d+\.\d+$/
- build-snap:
filters:
branches:

17
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,17 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 30
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- enhancement
- regression
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -10,6 +10,7 @@ extraction:
- libcogl-pango-dev
- python3-pil
- python3-cairo
- libssl-dev
after_prepare:
- "wget -O libxmlb.zip https://github.com/hughsie/libxmlb/archive/0.1.7.zip"
- "mkdir -p subprojects/libxmlb"
@ -17,6 +18,15 @@ extraction:
- "wget -O flashrom.zip https://github.com/hughsie/flashrom/archive/wip/hughsie/fwupd.zip"
- "mkdir -p subprojects/flashrom"
- "bsdtar --strip-components=1 -xvf flashrom.zip -C subprojects/flashrom"
- "cd $LGTM_WORKSPACE"
- "mkdir installdir"
- "wget https://github.com/tpm2-software/tpm2-tss/releases/download/2.3.0/tpm2-tss-2.3.0.tar.gz"
- "tar xf tpm2-tss-2.3.0.tar.gz"
- "cd tpm2-tss-2.3.0"
- "./configure --prefix=$LGTM_WORKSPACE/installdir/usr --disable-doxygen-doc"
- "make install"
- "export PKG_CONFIG_PATH=$LGTM_WORKSPACE/installdir/usr/lib/pkgconfig:$PKG_CONFIG_PATH"
- "export LD_LIBRARY_PATH=$LGTM_WORKSPACE/installdir/usr/lib:$LD_LIBRARY_PATH"
index:
build_command:
- "meson setup build"

View File

@ -10,7 +10,7 @@ env:
- OS=debian-x86_64
- OS=arch
- OS=debian-i386
- OS=ubuntu-x86_64
- OS=debian-s390x
install:
- ./contrib/ci/generate_docker.py

View File

@ -1,6 +1,6 @@
fwupd
=====
[![Build Status](https://travis-ci.org/hughsie/fwupd.png?branch=master)](https://travis-ci.org/hughsie/fwupd)
[![Build Status](https://travis-ci.org/fwupd/fwupd.png?branch=master)](https://travis-ci.org/fwupd/fwupd)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/10744/badge.svg)](https://scan.coverity.com/projects/10744)
[![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-white.svg)](https://snapcraft.io/fwupd)
@ -11,7 +11,7 @@ Additional information is available at the website: https://fwupd.org
## Compiling
The most up to date compilation instructions are available in the [Wiki](https://github.com/hughsie/fwupd/wiki/Compilation)
The most up to date compilation instructions are available in the [Wiki](https://github.com/fwupd/fwupd/wiki/Compilation)
LVFS
----

View File

@ -2,7 +2,7 @@ fwupd Release Notes
Write release entries:
git log --format="%s" --cherry-pick --right-only 1.2.9... | grep -i -v trivial | grep -v Merge | sort | uniq
git log --format="%s" --cherry-pick --right-only 1.3.1... | 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
@ -17,7 +17,7 @@ git add ../po/*.po
2. Commit changes to git:
# MAKE SURE THIS IS CORRECT
export release_ver="1.2.10"
export release_ver="1.3.2"
git commit -a -m "Release fwupd ${release_ver}"
git tag -s -f -m "Release fwupd ${release_ver}" "${release_ver}"

View File

@ -2,18 +2,26 @@
# Contributor: Mirco Tischler <mt-ml at gmx dot de>
pkgname=fwupd
pkgver=#VERSION#
pkgver=dummy
pkgrel=1
pkgdesc='A simple daemon to allow session software to update firmware'
arch=('i686' 'x86_64')
url='https://github.com/hughsie/fwupd'
url='https://github.com/fwupd/fwupd'
license=('GPL2')
depends=('libgusb' 'modemmanager')
optdepends=('tpm2-abrmd' 'tpm2-tools')
depends=('libgusb' 'modemmanager' 'tpm2-tss')
makedepends=('meson' 'valgrind' 'gobject-introspection' 'gtk-doc' 'python-pillow' 'git'
'python-cairo' 'noto-fonts' 'noto-fonts-cjk' 'python-gobject' 'vala'
'libsoup' 'polkit' 'gcab')
pkgver() {
cd ${pkgname}
VERSION=$(git describe | sed 's/-/.r/;s/-/./')
[ -z $VERSION ] && VERSION=$(head meson.build | grep ' version :' | cut -d \' -f2)
echo $VERSION
}
build() {
cd ${pkgname}
if [ -n "$CI" ]; then

View File

@ -1,4 +1,4 @@
FROM fedora:29
FROM fedora:30
%%%OS%%%
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en

View File

@ -1,6 +1,6 @@
Continuous Integration
======================
Continuous integration for fwupd is provided by [Travis CI](https://travis-ci.org/hughsie/fwupd).
Continuous integration for fwupd is provided by [Travis CI](https://travis-ci.org/fwupd/fwupd).
By using Travis CI, builds are exercised across a variety of environments attempting to maximize code coverage.
For every commit or pull request 6 builds are performed:

3
contrib/ci/abidiff.suppr Normal file
View File

@ -0,0 +1,3 @@
[suppress_type]
type_kind = enum
changed_enumerators = FWUPD_STATUS_LAST

View File

@ -3,24 +3,26 @@ set -e
set -x
shopt -s extglob
VERSION=`git describe | sed 's/-/.r/;s/-/./'`
[ -z $VERSION ] && VERSION=`head meson.build | grep ' version :' | cut -d \' -f2`
# prepare the build tree
rm -rf build
mkdir build && pushd build
cp ../contrib/PKGBUILD .
sed -i "s,#VERSION#,$VERSION," PKGBUILD
mkdir -p src/fwupd && pushd src/fwupd
cp -R ../../../!(build|dist) .
popd
chown nobody . -R
# install and run TPM simulator necessary for plugins/uefi/uefi-self-test
pacman -S --noconfirm ibm-sw-tpm2
tpm_server &
trap "kill $!" EXIT
export TPM_SERVER_RUNNING=1
# build the package and install it
sudo -E -u nobody makepkg -e --noconfirm
pacman -U --noconfirm *.pkg.tar.xz
sudo -E -u nobody PKGEXT='.pkg.tar' makepkg -e --noconfirm
pacman -U --noconfirm *.pkg.*
# move the package to working dir
mv *.pkg.tar.xz ../dist
mv *.pkg.* ../dist
# no testing here because gnome-desktop-testing isnt available in Arch

114
contrib/ci/check-abi Executable file
View File

@ -0,0 +1,114 @@
#!/usr/bin/python3
import argparse
import contextlib
import os
import shutil
import subprocess
import sys
def format_title(title):
box = {
'tl': '╔', 'tr': '╗', 'bl': '╚', 'br': '╝', 'h': '═', 'v': '║',
}
hline = box['h'] * (len(title) + 2)
return '\n'.join([
f"{box['tl']}{hline}{box['tr']}",
f"{box['v']} {title} {box['v']}",
f"{box['bl']}{hline}{box['br']}",
])
def rm_rf(path):
try:
shutil.rmtree(path)
except FileNotFoundError:
pass
def sanitize_path(name):
return name.replace('/', '-')
def get_current_revision():
revision = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
encoding='utf-8').strip()
if revision == 'HEAD':
# This is a detached HEAD, get the commit hash
revision = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8')
return revision
@contextlib.contextmanager
def checkout_git_revision(revision):
current_revision = get_current_revision()
subprocess.check_call(['git', 'checkout', '-q', revision])
try:
yield
finally:
subprocess.check_call(['git', 'checkout', '-q', current_revision])
def build_install(revision):
build_dir = '_build'
dest_dir = os.path.abspath(sanitize_path(revision))
print(format_title(f'# Building and installing {revision} in {dest_dir}'),
end='\n\n', flush=True)
with checkout_git_revision(revision):
rm_rf(build_dir)
rm_rf(revision)
subprocess.check_call(['meson', build_dir,
'--prefix=/usr', '--libdir=lib',
'-Db_coverage=false', '-Dgtkdoc=false', '-Dtests=false'])
subprocess.check_call(['ninja', '-v', '-C', build_dir])
subprocess.check_call(['ninja', '-v', '-C', build_dir, 'install'],
env={'DESTDIR': dest_dir})
return dest_dir
def compare(old_tree, new_tree):
print(format_title(f'# Comparing the two ABIs'), end='\n\n', flush=True)
old_headers = os.path.join(old_tree, 'usr', 'include')
old_lib = os.path.join(old_tree, 'usr', 'lib', 'libfwupd.so')
new_headers = os.path.join(new_tree, 'usr', 'include')
new_lib = os.path.join(new_tree, 'usr', 'lib', 'libfwupd.so')
subprocess.check_call([
'abidiff', '--headers-dir1', old_headers, '--headers-dir2', new_headers,
'--drop-private-types', '--suppressions', 'contrib/ci/abidiff.suppr',
'--fail-no-debug-info', '--no-added-syms', old_lib, new_lib])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('old', help='the previous revision, considered the reference')
parser.add_argument('new', help='the new revision, to compare to the reference')
args = parser.parse_args()
if args.old == args.new:
print("Let's not waste time comparing something to itself")
sys.exit(0)
old_tree = build_install(args.old)
new_tree = build_install(args.new)
try:
compare(old_tree, new_tree)
except subprocess.CalledProcessError:
sys.exit(1)
print(f'Hurray! {args.old} and {args.new} are ABI-compatible!')

View File

@ -10,6 +10,11 @@
<package />
</distro>
</dependency>
<dependency type="build" id="abigail-tools">
<distro id="debian">
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="bash-completion">
<distro id="debian">
<control />
@ -1286,4 +1291,29 @@
<package />
</distro>
</dependency>
<dependency type="build" id="libtss2-dev">
<distro id="arch">
<package>tpm2-tss</package>
</distro>
<distro id="centos">
<package>tpm2-tss-devel</package>
</distro>
<distro id="fedora">
<package>tpm2-tss-devel</package>
</distro>
<distro id="debian">
<control />
<package variant="x86_64" />
<package variant="i386" />
</distro>
<distro id="ubuntu">
<control />
<package variant="x86_64" />
</distro>
</dependency>
<dependency type="build" id="libgcrypt-devel">
<distro id="fedora">
<package />
</distro>
</dependency>
</dependencies>

View File

@ -79,7 +79,7 @@ with open(out.name, 'w') as wfd:
wfd.write("RUN apt update -qq && \\\n")
wfd.write("\tapt install -yq --no-install-recommends\\\n")
elif OS == "arch":
wfd.write("RUN pacman -Syu --noconfirm \\\n")
wfd.write("RUN pacman -Syu --noconfirm --needed\\\n")
for i in range(0, len(deps)):
if i < len(deps)-1:
wfd.write("\t%s \\\n" % deps[i])

View File

@ -8,8 +8,14 @@ eval "$(dpkg-buildflags --export=sh)"
export LDFLAGS=$(dpkg-buildflags --get LDFLAGS | sed "s/-Wl,-Bsymbolic-functions\s//")
rm -rf build
meson build --werror
meson build --werror -Dman=false -Dgtkdoc=true
#build with clang and -Werror
ninja -C build test -v
#make docs available outside of docker
ninja -C build install -v
mkdir -p dist/docs
cp build/docs/libfwupd/* dist/docs -R
#run static analysis (these mostly won't be critical)
ninja -C build scan-build -v

View File

@ -10,6 +10,7 @@
%global enable_ci 0
%global enable_tests 1
%global enable_dummy 1
%global enable_flashrom 1
%global __meson_wrap_mode default
# fwupd.efi is only available on these arches
@ -37,7 +38,7 @@ Name: fwupd
Version: #VERSION#
Release: 0.#BUILD#%{?alphatag}%{?dist}
License: LGPLv2+
URL: https://github.com/hughsie/fwupd
URL: https://github.com/fwupd/fwupd
Source0: http://people.freedesktop.org/~hughsient/releases/%{name}-%{version}.tar.xz
BuildRequires: gettext
@ -86,6 +87,7 @@ BuildRequires: freetype
BuildRequires: fontconfig
BuildRequires: google-noto-sans-cjk-ttc-fonts
BuildRequires: gnu-efi-devel
BuildRequires: tpm2-tss-devel >= 2.2.3
BuildRequires: pesign
%endif
@ -105,8 +107,9 @@ Requires: libsoup%{?_isa} >= %{libsoup_version}
Requires: bubblewrap
Requires: shared-mime-info
%if 0%{?rhel} > 7 || 0%{?fedora} > 28
Recommends: python3
Recommends: tpm2-tools tpm2-abrmd
%endif
Obsoletes: fwupd-sign < 0.1.6
Obsoletes: libebitdo < 0.7.5-3
@ -152,7 +155,11 @@ Data files for installed tests.
%else
-Dplugin_dummy=false \
%endif
%if 0%{?enable_flashrom}
-Dplugin_flashrom=true \
%else
-Dplugin_flashrom=false \
%endif
-Dplugin_thunderbolt=true \
%if 0%{?have_redfish}
-Dplugin_redfish=true \
@ -204,11 +211,13 @@ Data files for installed tests.
mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%if 0%{?enable_flashrom}
# delete most files from the subproject
rm ${RPM_BUILD_ROOT}%{_includedir}/libflashrom.h
rm ${RPM_BUILD_ROOT}%{_libdir}/libflashrom.so
rm ${RPM_BUILD_ROOT}%{_libdir}/pkgconfig/libflashrom.pc
rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%endif
%find_lang %{name}
@ -232,6 +241,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%if 0%{?have_redfish}
%config(noreplace)%{_sysconfdir}/fwupd/redfish.conf
%endif
%config(noreplace)%{_sysconfdir}/fwupd/thunderbolt.conf
%dir %{_libexecdir}/fwupd
%{_libexecdir}/fwupd/fwupd
%{_libexecdir}/fwupd/fwupdtool
@ -255,7 +265,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%config(noreplace)%{_sysconfdir}/fwupd/remotes.d/vendor-directory.conf
%config(noreplace)%{_sysconfdir}/pki/fwupd
%{_sysconfdir}/pki/fwupd-metadata
%{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf
%{_datadir}/dbus-1/system.d/org.freedesktop.fwupd.conf
%{_datadir}/bash-completion/completions/fwupdmgr
%{_datadir}/bash-completion/completions/fwupdtool
%{_datadir}/bash-completion/completions/fwupdagent
@ -275,6 +285,8 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%{_datadir}/fwupd/firmware-packager
%{_unitdir}/fwupd-offline-update.service
%{_unitdir}/fwupd.service
%{_unitdir}/fwupd-refresh.service
%{_unitdir}/fwupd-refresh.timer
%{_unitdir}/system-update.target.wants/
%dir %{_localstatedir}/lib/fwupd
%dir %{_datadir}/fwupd/quirks.d
@ -298,7 +310,9 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%{_libdir}/fwupd-plugins-3/libfu_plugin_dfu.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_ebitdo.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_fastboot.so
%if 0%{?enable_flashrom}
%{_libdir}/fwupd-plugins-3/libfu_plugin_flashrom.so
%endif
%if 0%{?have_modem_manager}
%{_libdir}/fwupd-plugins-3/libfu_plugin_modem_manager.so
%endif
@ -311,20 +325,24 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%endif
%{_libdir}/fwupd-plugins-3/libfu_plugin_rts54hid.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_rts54hub.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_solokey.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_steelseries.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_superio.so
%if 0%{?have_dell}
%{_libdir}/fwupd-plugins-3/libfu_plugin_synapticsmst.so
%endif
%{_libdir}/fwupd-plugins-3/libfu_plugin_synaptics_cxaudio.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_synaptics_prometheus.so
%if 0%{?enable_dummy}
%{_libdir}/fwupd-plugins-3/libfu_plugin_test.so
%endif
%{_libdir}/fwupd-plugins-3/libfu_plugin_thelio_io.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt_power.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_udev.so
%if 0%{?have_uefi}
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so
%endif
%{_libdir}/fwupd-plugins-3/libfu_plugin_unifying.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so
@ -335,8 +353,10 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%{_datadir}/locale/*/LC_IMAGES/fwupd*
%endif
%if 0%{?enable_flashrom}
# eww, but just until the Fedora package ships these...
%{_libdir}/libflashrom.so.1*
%endif
%files devel
%{_datadir}/gir-1.0/Fwupd-2.0.gir

View File

@ -221,7 +221,7 @@ def use_included_version(minimum_version):
print("fwupd %s is already installed but this package requires %s" %
(version.version, minimum_version))
else:
print("New enough fwupd already installed")
print("Using existing fwupd version %s already installed on system." % version.version)
return False
else:
print("fwupd %s is installed and must be removed" % version.version)
@ -229,18 +229,20 @@ def use_included_version(minimum_version):
def remove_packaged_version(pkg, cache):
res = False
while not res:
while True:
res = input("Remove now (Y/N)? ")
if res.lower() == 'n':
return False
if res.lower() == 'y':
res = False
break
res = False
pkg.mark_delete()
res = cache.commit()
if res.lower() == 'y':
res = True
break
if res:
pkg.mark_delete()
res = cache.commit()
if not res:
raise Exception("Need to remove packaged version")
return res
return True
def install_builtin(directory, verbose, allow_reinstall, allow_older):
cabs = []
@ -271,7 +273,7 @@ def run_installation (directory, verbose, allow_reinstall, allow_older, uninstal
with open(minimum_path, "r") as rfd:
minimum = rfd.read()
if use_included_version(minimum):
if not use_included_version(minimum):
install_builtin(directory, verbose, allow_reinstall, allow_older)
return

View File

@ -15,6 +15,7 @@ _fwupdmgr_cmd_list=(
'get-results'
'get-topology'
'get-updates'
'get-upgrades'
'install'
'modify-config'
'modify-remote'
@ -23,6 +24,7 @@ _fwupdmgr_cmd_list=(
'set-approved-firmware'
'unlock'
'update'
'upgrade'
'verify'
'verify-update'
'--version'
@ -41,8 +43,18 @@ _fwupdmgr_opts=(
'--no-reboot-check'
'--show-all-devices'
'--sign'
'--filter'
'--log'
'--disable-ssl-strict'
)
_show_filters()
{
local flags
flags="$(command @libexecdir@/fwupdtool get-device-flags 2>/dev/null)"
COMPREPLY+=( $(compgen -W "${flags}" -- "$cur") )
}
_show_modifiers()
{
COMPREPLY+=( $(compgen -W '${_fwupdmgr_opts[@]}' -- "$cur") )
@ -73,6 +85,13 @@ _fwupdmgr()
prev=${COMP_WORDS[COMP_CWORD-1]}
command=${COMP_WORDS[1]}
case $prev in
--filter)
_show_filters
return 0
;;
esac
case $command in
activate|clear-results|downgrade|get-releases|get-results|unlock|verify|verify-update)
if [[ "$prev" = "$command" ]]; then

View File

@ -2,13 +2,16 @@ _fwupdtool_cmd_list=(
'activate'
'build-firmware'
'get-updates'
'get-updgrades'
'get-details'
'get-device-flags'
'get-devices'
'get-history'
'get-plugins'
'get-topology'
'hwids'
'update'
'upgrade'
'install'
'install-blob'
'monitor'
@ -30,8 +33,17 @@ _fwupdtool_opts=(
'--plugin-whitelist'
'--prepare'
'--cleanup'
'--filter'
'--disable-ssl-strict'
)
_show_filters()
{
local flags
flags="$(command @libexecdir@/fwupdtool get-device-flags 2>/dev/null)"
COMPREPLY+=( $(compgen -W "${flags}" -- "$cur") )
}
_show_plugins()
{
local plugins
@ -57,6 +69,10 @@ _fwupdtool()
_show_plugins
return 0
;;
--filter)
_show_filters
return 0
;;
esac
case $command in

View File

@ -4,17 +4,11 @@ if bashcomp.found()
)
if get_option('daemon')
install_data(['fwupdmgr'],
install_dir : tgt,
)
endif
if get_option('agent')
install_data(['fwupdagent'],
install_dir : tgt,
)
endif
endif # get_option('agent')
# replace @libexecdir@
fwupdtool_path = join_paths(libexecdir, 'fwupd')
@ -27,4 +21,13 @@ configure_file(
install: true,
install_dir: tgt)
endif
if build_daemon
configure_file(
input : 'fwupdmgr.in',
output : 'fwupdmgr',
configuration : con2,
install: true,
install_dir: tgt)
endif # build_daemon
endif # bashcomp.found()

View File

@ -8,6 +8,9 @@ Before=display-manager.service
Type=dbus
BusName=org.freedesktop.fwupd
ExecStart=@libexecdir@/fwupd/fwupd
StateDirectory=@package_name@
CacheDirectory=@package_name@
ConfigurationDirectory=@package_name@
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full

View File

@ -3,17 +3,20 @@ subdir('pki')
subdir('remotes.d')
subdir('bash-completion')
if build_daemon
subdir('motd')
endif
if get_option('tests')
subdir('tests')
endif
if get_option('daemon')
if build_daemon
subdir('installed-tests')
install_data(['daemon.conf'],
install_dir : join_paths(sysconfdir, 'fwupd')
)
endif
install_data(['daemon.conf'],
install_dir : join_paths(sysconfdir, 'fwupd')
)
install_data(['org.freedesktop.fwupd.metainfo.xml'],
install_dir: join_paths(datadir, 'metainfo')
)
@ -22,27 +25,23 @@ install_data(['org.freedesktop.fwupd.svg'],
install_dir : join_paths(datadir, 'icons', 'hicolor', 'scalable', 'apps')
)
install_data(['org.freedesktop.fwupd.conf'],
install_dir : join_paths(sysconfdir, 'dbus-1', 'system.d')
)
if get_option('daemon')
if build_daemon
install_data(['org.freedesktop.fwupd.conf'],
install_dir : join_paths(datadir, 'dbus-1', 'system.d')
)
install_data(['90-fwupd-devices.rules'],
install_dir : join_paths(udevdir, 'rules.d')
)
endif
if get_option('systemd')
if get_option('systemd') and build_daemon
con2 = configuration_data()
con2.set('libexecdir', libexecdir)
con2.set('bindir', bindir)
con2.set('datadir', datadir)
con2.set('localstatedir', localstatedir)
con2.set('package_name', meson.project_name())
rw_directories = []
rw_directories += join_paths (localstatedir, 'lib', 'fwupd')
rw_directories += join_paths (sysconfdir, 'fwupd')
rw_directories += join_paths (sysconfdir, 'fwupd', 'remotes.d')
if get_option('plugin_uefi')
rw_directories += ['-/boot/efi', '-/efi/EFI', '-/boot/EFI']
endif
@ -89,7 +88,7 @@ if get_option('systemd')
)
endif
if get_option('systemd') or get_option('elogind')
if (get_option('systemd') or get_option('elogind')) and build_daemon
con2 = configuration_data()
con2.set('libexecdir', libexecdir)

5
data/motd/85-fwupd.motd.in Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
if [ -f @motd_fullpath@ ]; then
cat @motd_fullpath@
fi

17
data/motd/README.md Normal file
View File

@ -0,0 +1,17 @@
# Message of the day integration
Message on the day integration is used to display the availability of updates when connecting to a remote console.
It has two elements:
* Automatic firmware metadata refresh
* Message of the day display
## Automatic firmware metadata refresh
This uses a systemd timer to run on a regular cadence.
To enable this, run
```
# systemctl enable fwupd-refresh.timer
```
## Motd display
Motd display is dependent upon the availability of the update-motd snippet consumption service such as pam_motd.

View File

@ -0,0 +1,19 @@
[Unit]
Description=Refresh fwupd metadata and update motd
Documentation=man:fwupdmgr(1)
After=network.target network-online.target systemd-networkd.service NetworkManager.service connman.service
[Service]
Type=oneshot
RuntimeDirectory=@motd_dir@
CacheDirectory=fwupd
RuntimeDirectoryPreserve=yes
StandardError=null
ExecStart=@bindir@/fwupdmgr refresh
ExecStart=@bindir@/fwupdmgr get-updates --log @motd_file@
DynamicUser=yes
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET AF_INET6
SystemCallFilter=~@mount
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictRealtime=yes

View File

@ -0,0 +1,10 @@
[Unit]
Description=Refresh fwupd metadata regularly
[Timer]
OnCalendar=*-*-* 6,18:00
RandomizedDelaySec=12h
Persistent=true
[Install]
WantedBy=timers.target

30
data/motd/meson.build Normal file
View File

@ -0,0 +1,30 @@
motd_file = '85-fwupd'
motd_dir = 'motd.d'
motd_fullpath = join_paths ('/run', motd_dir, motd_file)
con2 = configuration_data()
con2.set('bindir', bindir)
con2.set('motd_file', motd_file)
con2.set('motd_dir', motd_dir)
con2.set('motd_fullpath', motd_fullpath)
# This file is only used in Ubuntu, which chooses to use update-motd instead
# of sourcing /run/motd.d/*
# See https://bugs.launchpad.net/ubuntu/+source/pam/+bug/399071
configure_file(
input : '85-fwupd.motd.in',
output : motd_file,
configuration : con2,
install: false,
)
if get_option('systemd')
install_data(['fwupd-refresh.timer'],
install_dir: systemdunitdir)
configure_file(
input : 'fwupd-refresh.service.in',
output : 'fwupd-refresh.service',
configuration : con2,
install: true,
install_dir: systemdunitdir)
endif

View File

@ -20,7 +20,7 @@
tablets and on headless servers.
</p>
</description>
<url type="bugtracker">https://github.com/hughsie/fwupd/issues</url>
<url type="bugtracker">https://github.com/fwupd/fwupd/issues</url>
<url type="homepage">https://fwupd.org/</url>
<url type="translate">https://www.transifex.com/freedesktop/fwupd/</url>
<update_contact>richard_at_hughsie.com</update_contact>
@ -32,6 +32,62 @@
<binary>fwupdmgr</binary>
</provides>
<releases>
<release version="1.3.2" date="2019-09-26">
<description>
<p>This release adds the following features:</p>
<ul>
<li>Add a plugin to detach the Thelio IO board</li>
<li>Add a plugin to update Conexant audio devices</li>
<li>Support issues in AppStream metadata</li>
</ul>
<p>This release fixes the following bugs:</p>
<ul>
<li>Align the key values to the text width not the number of bytes</li>
<li>Display more helpful historical device information</li>
<li>Do not ask the user to upload a report if ReportURI is not set</li>
<li>Do not crash when starting tpm2-abrmd</li>
<li>Ensure HID++ v2.0 peripheral devices get added</li>
<li>Fall back to /var/lib/dbus/machine-id when required</li>
<li>Include all GUIDs when uploading a report</li>
<li>Move D-Bus conf file to datadir/dbus-1/system.d</li>
<li>Update device_modified in sql database during updates</li>
</ul>
</description>
</release>
<release version="1.3.1" date="2019-07-15">
<description>
<p>This release adds the following features:</p>
<ul>
<li>Add support for the Minnowboard Turbot</li>
<li>Add support for the SoloKey Secure</li>
<li>Add support for thunderbolt kernel safety checks</li>
<li>Add support to integrate into the motd</li>
<li>Allow filtering devices when using the command line tools</li>
<li>Allow setting custom flags when using fwupdate</li>
<li>Allow specifying a firmware GUID to check any version exists</li>
<li>Include the kernel release as a runtime version</li>
<li>Print devices, remotes, releases using a tree</li>
<li>Publish docs to fwupd.github.io using CircleCI</li>
</ul>
<p>This release fixes the following bugs:</p>
<ul>
<li>Add aliases for get-upgrades and upgrade</li>
<li>Allow disabling SSL strict mode for broken corporate proxies</li>
<li>Be more accepting when trying to recover a failed database migration</li>
<li>Do not segfault when trying to quit the downgrade selection</li>
<li>Fix a possible crash when stopping the fwupd service</li>
<li>Fix incomplete hex file parsing in unifying plugin</li>
<li>Fix thunderbolt logic to work properly with ICL thunderbolt controller</li>
<li>Never show AppStream markup on the console</li>
<li>Never use memcpy() in a possibly unsafe way</li>
<li>Only write the new UEFI device path if different than before</li>
<li>Partially rewrite the Synapticsmst plugin to support more hardware</li>
<li>Reload metadata store when configuration changes</li>
<li>Use environment variables for systemd managed directories</li>
<li>Use tpm2-tss library to read PCR values</li>
</ul>
</description>
</release>
<release version="1.2.10" date="2019-07-15">
<description>
<p>This release adds the following features:</p>

View File

@ -1,4 +1,4 @@
if get_option('daemon') and get_option('lvfs')
if build_daemon and get_option('lvfs')
install_data([
'lvfs.conf',
'lvfs-testing.conf',

11
data/tests/firmware.shex Normal file
View File

@ -0,0 +1,11 @@
:100000003DEF20F000000000FACF01F0FBCF02F03E
:10001000E9CF03F0EACF04F0E1CF05F0E2CF06F03C
:10002000D9CF07F0DACF08F0F3CF09F0F4CF0AF018
:10003000F6CF0BF0F7CF0CF0F8CF0DF0F5CF0EF0B8
:100040000EC0F5FF0DC0F8FF0CC0F7FF0BC0F6FFA8
:100050000AC0F4FF09C0F3FF08C0DAFF07C0D9FFE8
:1000600006C0E2FF05C0E1FF04C0EAFF03C0E9FFEC
:1000700002C0FBFF01C0FAFF11003FEF20F00001BA
:0800800042EF20F03DEF20F0FB
:080000FD6465616462656566DB
:00000001FF

14
debian/control.in vendored
View File

@ -8,7 +8,7 @@ Uploaders: Steve McIntyre <93sam@debian.org>,
Build-Depends: %%%DYNAMIC%%%
Standards-Version: 4.3.0
Section: admin
Homepage: https://github.com/hughsie/fwupd
Homepage: https://github.com/fwupd/fwupd
Vcs-Git: https://salsa.debian.org/efi-team/fwupd.git
Vcs-Browser: https://salsa.debian.org/efi-team/fwupd
@ -23,7 +23,7 @@ Description: Firmware update daemon library
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
See <https://github.com/fwupd/fwupd> for details
.
This package provides the library used by the daemon.
@ -34,8 +34,6 @@ Depends: ${misc:Depends},
shared-mime-info
Recommends: python3,
bolt,
tpm2-tools,
tpm2-abrmd,
fwupd-signed
Breaks: gir1.2-dfu-1.0 (<< 0.9.7-1),
libdfu1 (<< 0.9.7-1),
@ -49,7 +47,7 @@ Description: Firmware update daemon
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
See <https://github.com/fwupd/fwupd> for details
Package: fwupd-tests
Architecture: linux-any
@ -71,7 +69,7 @@ Description: Test suite for firmware update daemon
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
See <https://github.com/fwupd/fwupd> for details
.
This package provides a set of installed tests that can be run to validate
the daemon in a continuous integration system.
@ -86,7 +84,7 @@ Description: Firmware update daemon documentation (HTML format)
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
See <https://github.com/fwupd/fwupd> for details
.
This package provides development documentation for creating a package that
uses fwupd.
@ -105,7 +103,7 @@ Description: development files for libfwupd
You can either use a GUI software manager like GNOME Software to view and
apply updates, the command-line tool or the system D-Bus interface directly.
Firmware updates are supported for a variety of technologies.
See <https://github.com/hughsie/fwupd> for details
See <https://github.com/fwupd/fwupd> for details
.
This package provides the development files for libfwupd

2
debian/copyright.in vendored
View File

@ -1,6 +1,6 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: fwupd
Source: https://github.com/hughsie/fwupd
Source: https://github.com/fwupd/fwupd
%%%DYNAMIC%%%
Files: *.metainfo.xml

View File

@ -21,3 +21,4 @@ data/daemon.conf etc/fwupd
debian/fwupd.pkla /var/lib/polkit-1/localauthority/10-vendor.d
usr/lib/*/fwupd-plugins-*/*.so
debian/lintian/fwupd usr/share/lintian/overrides
obj*/data/motd/85-fwupd /etc/update-motd.d

2
debian/rules vendored
View File

@ -52,7 +52,7 @@ override_dh_auto_configure:
else \
export FLASHROM="-Dplugin_flashrom=false"; \
fi; \
dh_auto_configure -- $$UEFI $$DELL $$FLASHROM $$CI -Dplugin_dummy=true --libexecdir=/usr/lib
dh_auto_configure -- $$UEFI $$DELL $$FLASHROM $$CI -Dplugin_dummy=true -Dgtkdoc=true --libexecdir=/usr/lib
override_dh_install:
find debian/tmp/usr -type f -name "*a" -print | xargs rm -f

View File

@ -5,7 +5,7 @@ Uploaders: Daniel Jared Dominguez <jared.dominguez@dell.com>, Steve McIntyre <93
Build-Depends: debhelper (>= 9.0.0), sbsigntool [amd64 arm64 armhf i386], fwupd (= SIGNVERSION) [SIGNARCH]
Standards-Version: 4.1.3
Section: libs
Homepage: https://github.com/hughsie/fwupd
Homepage: https://github.com/fwupd/fwupd
Vcs-Git: https://salsa.debian.org/efi-team/fwupd.git
Vcs-Browser: https://salsa.debian.org/efi-team/fwupd
@ -16,8 +16,8 @@ Provides: fwupd-signed
Depends: ${shlibs:Depends}, ${misc:Depends}, fwupd (= SIGNVERSION)
Built-Using: fwupd (= SIGNVERSION)
Description: Tools to manage UEFI firmware updates (signed)
fwupd provides functionality to update system firmware. It has been
initially designed to update firmware using UEFI capsule updates, but
fwupd provides functionality to update system firmware. It has been
initially designed to update firmware using UEFI capsule updates, but
it is designed to be extensible to other firmware update standards.
.
This package contains just the signed version of the fwupd binary,

View File

@ -1,6 +1,6 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: fwupd
Source: https://github.com/hughsie/fwupd
Source: https://github.com/fwupd/fwupd
Files: *
Copyright: 2015 Richard Hughes <richard@hughsie.com>

2
debian/watch vendored
View File

@ -3,4 +3,4 @@
version=3
opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/fwupd-$1\.tar\.gz/ \
https://github.com/hughsie/fwupd/tags .*/v?(\d\S*)\.tar\.gz
https://github.com/fwupd/fwupd/tags .*/v?(\d\S*)\.tar\.gz

View File

@ -40,6 +40,8 @@ typedef struct {
gboolean tainted;
guint percentage;
gchar *daemon_version;
gchar *host_product;
gchar *host_machine_id;
GDBusConnection *conn;
GDBusProxy *proxy;
} FwupdClientPrivate;
@ -59,6 +61,8 @@ enum {
PROP_PERCENTAGE,
PROP_DAEMON_VERSION,
PROP_TAINTED,
PROP_HOST_PRODUCT,
PROP_HOST_MACHINE_ID,
PROP_LAST
};
@ -102,6 +106,24 @@ fwupd_client_helper_new (void)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(FwupdClientHelper, fwupd_client_helper_free)
#pragma clang diagnostic pop
static void
fwupd_client_set_host_product (FwupdClient *client, const gchar *host_product)
{
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_free (priv->host_product);
priv->host_product = g_strdup (host_product);
g_object_notify (G_OBJECT (client), "host-product");
}
static void
fwupd_client_set_host_machine_id (FwupdClient *client, const gchar *host_machine_id)
{
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_free (priv->host_machine_id);
priv->host_machine_id = g_strdup (host_machine_id);
g_object_notify (G_OBJECT (client), "host-machine-id");
}
static void
fwupd_client_set_daemon_version (FwupdClient *client, const gchar *daemon_version)
{
@ -155,6 +177,18 @@ fwupd_client_properties_changed_cb (GDBusProxy *proxy,
if (val != NULL)
fwupd_client_set_daemon_version (client, g_variant_get_string (val, NULL));
}
if (g_variant_dict_contains (dict, "HostProduct")) {
g_autoptr(GVariant) val = NULL;
val = g_dbus_proxy_get_cached_property (proxy, "HostProduct");
if (val != NULL)
fwupd_client_set_host_product (client, g_variant_get_string (val, NULL));
}
if (g_variant_dict_contains (dict, "HostMachineId")) {
g_autoptr(GVariant) val = NULL;
val = g_dbus_proxy_get_cached_property (proxy, "HostMachineId");
if (val != NULL)
fwupd_client_set_host_machine_id (client, g_variant_get_string (val, NULL));
}
}
static void
@ -249,6 +283,13 @@ fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **e
val2 = g_dbus_proxy_get_cached_property (priv->proxy, "Tainted");
if (val2 != NULL)
priv->tainted = g_variant_get_boolean (val2);
val = g_dbus_proxy_get_cached_property (priv->proxy, "HostProduct");
if (val != NULL)
fwupd_client_set_host_product (client, g_variant_get_string (val, NULL));
val = g_dbus_proxy_get_cached_property (priv->proxy, "HostMachineId");
if (val != NULL)
fwupd_client_set_host_machine_id (client, g_variant_get_string (val, NULL));
return TRUE;
}
@ -1150,6 +1191,42 @@ fwupd_client_get_daemon_version (FwupdClient *client)
return priv->daemon_version;
}
/**
* fwupd_client_get_host_product:
* @client: A #FwupdClient
*
* Gets the string that represents the host running fwupd
*
* Returns: a string, or %NULL for unknown.
*
* Since: 1.3.1
**/
const gchar *
fwupd_client_get_host_product (FwupdClient *client)
{
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
return priv->host_product;
}
/**
* fwupd_client_get_host_machine_id:
* @client: A #FwupdClient
*
* Gets the string that represents the host machine ID
*
* Returns: a string, or %NULL for unknown.
*
* Since: 1.3.2
**/
const gchar *
fwupd_client_get_host_machine_id (FwupdClient *client)
{
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE);
return priv->host_machine_id;
}
/**
* fwupd_client_get_status:
* @client: A #FwupdClient
@ -1672,6 +1749,12 @@ fwupd_client_get_property (GObject *object, guint prop_id,
case PROP_DAEMON_VERSION:
g_value_set_string (value, priv->daemon_version);
break;
case PROP_HOST_PRODUCT:
g_value_set_string (value, priv->host_product);
break;
case PROP_HOST_MACHINE_ID:
g_value_set_string (value, priv->host_machine_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1836,6 +1919,28 @@ fwupd_client_class_init (FwupdClientClass *klass)
pspec = g_param_spec_string ("daemon-version", NULL, NULL,
NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_DAEMON_VERSION, pspec);
/**
* FwupdClient:host-product:
*
* The host product string
*
* Since: 1.3.1
*/
pspec = g_param_spec_string ("host-product", NULL, NULL,
NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_HOST_PRODUCT, pspec);
/**
* FwupdClient:host-machine-id:
*
* The host machine-id string
*
* Since: 1.3.2
*/
pspec = g_param_spec_string ("host-machine-id", NULL, NULL,
NULL, G_PARAM_READABLE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_HOST_MACHINE_ID, pspec);
}
static void
@ -1850,6 +1955,8 @@ fwupd_client_finalize (GObject *object)
FwupdClientPrivate *priv = GET_PRIVATE (client);
g_free (priv->daemon_version);
g_free (priv->host_product);
g_free (priv->host_machine_id);
if (priv->conn != NULL)
g_object_unref (priv->conn);
if (priv->proxy != NULL)

View File

@ -127,6 +127,8 @@ FwupdStatus fwupd_client_get_status (FwupdClient *client);
gboolean fwupd_client_get_tainted (FwupdClient *client);
guint fwupd_client_get_percentage (FwupdClient *client);
const gchar *fwupd_client_get_daemon_version (FwupdClient *client);
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,
GCancellable *cancellable,

View File

@ -313,12 +313,31 @@ fwupd_build_user_agent (const gchar *package_name, const gchar *package_version)
gchar *
fwupd_build_machine_id (const gchar *salt, GError **error)
{
const gchar *fn = NULL;
g_autofree gchar *buf = NULL;
g_auto(GStrv) fns = g_new0 (gchar *, 5);
g_autoptr(GChecksum) csum = NULL;
gsize sz = 0;
/* this has to exist */
if (!g_file_get_contents ("/etc/machine-id", &buf, &sz, error))
/* one of these has to exist */
fns[0] = g_build_filename (SYSCONFDIR, "machine-id", NULL);
fns[1] = g_build_filename (LOCALSTATEDIR, "lib", "dbus", "machine-id", NULL);
fns[2] = g_strdup ("/etc/machine-id");
fns[3] = g_strdup ("/var/lib/dbus/machine-id");
for (guint i = 0; fns[i] != NULL; i++) {
if (g_file_test (fns[i], G_FILE_TEST_EXISTS)) {
fn = fns[i];
break;
}
}
if (fn == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_READ,
"The machine-id is not present");
return NULL;
}
if (!g_file_get_contents (fn, &buf, &sz, error))
return NULL;
if (sz == 0) {
g_set_error_literal (error,
@ -356,6 +375,7 @@ fwupd_build_history_report_json_device (JsonBuilder *builder, FwupdDevice *dev)
{
FwupdRelease *rel = fwupd_device_get_release_default (dev);
GPtrArray *checksums;
GPtrArray *guids;
/* identify the firmware used */
json_builder_set_member_name (builder, "Checksum");
@ -393,8 +413,16 @@ fwupd_build_history_report_json_device (JsonBuilder *builder, FwupdDevice *dev)
}
/* map back to the dev type on the LVFS */
json_builder_set_member_name (builder, "Guid");
json_builder_add_string_value (builder, fwupd_device_get_guid_default (dev));
guids = fwupd_device_get_guids (dev);
if (guids->len > 0) {
json_builder_set_member_name (builder, "Guid");
json_builder_begin_array (builder);
for (guint i = 0; i < guids->len; i++) {
const gchar *guid = g_ptr_array_index (guids, i);
json_builder_add_string_value (builder, guid);
}
json_builder_end_array (builder);
}
json_builder_set_member_name (builder, "Plugin");
json_builder_add_string_value (builder, fwupd_device_get_plugin (dev));

View File

@ -1789,7 +1789,6 @@ fwupd_device_to_string (FwupdDevice *device)
{
FwupdDevicePrivate *priv = GET_PRIVATE (device);
GString *str;
g_autoptr(GHashTable) ids = NULL;
g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
@ -1800,22 +1799,30 @@ fwupd_device_to_string (FwupdDevice *device)
str = g_string_append (str, "Unknown Device\n");
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_ID, priv->id);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PARENT_DEVICE_ID, priv->parent_id);
ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
for (guint i = 0; i < priv->instance_ids->len; i++) {
const gchar *instance_id = g_ptr_array_index (priv->instance_ids, i);
g_hash_table_insert (ids,
fwupd_guid_hash_string (instance_id),
g_strdup (instance_id));
}
for (guint i = 0; i < priv->guids->len; i++) {
const gchar *guid = g_ptr_array_index (priv->guids, i);
const gchar *instance_id = g_hash_table_lookup (ids, guid);
if (instance_id == NULL) {
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_GUID, guid);
} else {
g_autofree gchar *tmp = NULL;
tmp = g_strdup_printf ("%s <- %s", guid, instance_id);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_GUID, tmp);
if (priv->guids->len > 0) {
g_autoptr(GHashTable) ids = NULL;
ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
for (guint i = 0; i < priv->instance_ids->len; i++) {
const gchar *instance_id = g_ptr_array_index (priv->instance_ids, i);
g_hash_table_insert (ids,
fwupd_guid_hash_string (instance_id),
g_strdup (instance_id));
}
for (guint i = 0; i < priv->guids->len; i++) {
const gchar *guid = g_ptr_array_index (priv->guids, i);
const gchar *instance_id = g_hash_table_lookup (ids, guid);
if (instance_id == NULL) {
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_GUID, guid);
} else {
g_autofree gchar *tmp = NULL;
tmp = g_strdup_printf ("%s <- %s", guid, instance_id);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_GUID, tmp);
}
}
} else {
for (guint i = 0; i < priv->instance_ids->len; i++) {
const gchar *instance_id = g_ptr_array_index (priv->instance_ids, i);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_INSTANCE_IDS, instance_id);
}
}
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SERIAL, priv->serial);

View File

@ -17,6 +17,7 @@ G_BEGIN_DECLS
#define FWUPD_RESULT_KEY_FILENAME "Filename" /* s */
#define FWUPD_RESULT_KEY_PROTOCOL "Protocol" /* s */
#define FWUPD_RESULT_KEY_CATEGORIES "Categories" /* as */
#define FWUPD_RESULT_KEY_ISSUES "Issues" /* as */
#define FWUPD_RESULT_KEY_FLAGS "Flags" /* t */
#define FWUPD_RESULT_KEY_FLASHES_LEFT "FlashesLeft" /* u */
#define FWUPD_RESULT_KEY_INSTALL_DURATION "InstallDuration" /* u */
@ -30,6 +31,7 @@ G_BEGIN_DECLS
#define FWUPD_RESULT_KEY_MODIFIED "Modified" /* t */
#define FWUPD_RESULT_KEY_METADATA "Metadata" /* a{ss} */
#define FWUPD_RESULT_KEY_NAME "Name" /* s */
#define FWUPD_RESULT_KEY_NAME_VARIANT_SUFFIX "NameVariantSuffix" /* s */
#define FWUPD_RESULT_KEY_PLUGIN "Plugin" /* s */
#define FWUPD_RESULT_KEY_RELEASE "Release" /* a{sv} */
#define FWUPD_RESULT_KEY_REMOTE_ID "RemoteId" /* s */

View File

@ -163,6 +163,8 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag)
return "needs-activation";
if (device_flag == FWUPD_DEVICE_FLAG_ENSURE_SEMVER)
return "ensure-semver";
if (device_flag == FWUPD_DEVICE_FLAG_HISTORICAL)
return "historical";
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
return "unknown";
return NULL;
@ -227,6 +229,8 @@ fwupd_device_flag_from_string (const gchar *device_flag)
return FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION;
if (g_strcmp0 (device_flag, "ensure-semver") == 0)
return FWUPD_DEVICE_FLAG_ENSURE_SEMVER;
if (g_strcmp0 (device_flag, "historical") == 0)
return FWUPD_DEVICE_FLAG_HISTORICAL;
return FWUPD_DEVICE_FLAG_UNKNOWN;
}

View File

@ -88,6 +88,7 @@ typedef enum {
* @FWUPD_DEVICE_FLAG_ANOTHER_WRITE_REQUIRED: Requires the update to be retried with a new plugin
* @FWUPD_DEVICE_FLAG_NO_AUTO_INSTANCE_IDS: Do not add instance IDs from the device baseclass
* @FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION: Device update needs to be separately activated
* @FWUPD_DEVICE_FLAG_HISTORICAL Device is for historical data only
* @FWUPD_DEVICE_FLAG_ENSURE_SEMVER: Ensure the version is a valid semantic version, e.g. numbers separated with dots
*
* The device flags.
@ -115,6 +116,7 @@ typedef enum {
#define FWUPD_DEVICE_FLAG_NO_AUTO_INSTANCE_IDS (1u << 19) /* Since: 1.2.5 */
#define FWUPD_DEVICE_FLAG_NEEDS_ACTIVATION (1u << 20) /* Since: 1.2.6 */
#define FWUPD_DEVICE_FLAG_ENSURE_SEMVER (1u << 21) /* Since: 1.2.9 */
#define FWUPD_DEVICE_FLAG_HISTORICAL (1u << 22) /* Since: 1.3.2 */
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
typedef guint64 FwupdDeviceFlags;

View File

@ -31,6 +31,7 @@ static void fwupd_release_finalize (GObject *object);
typedef struct {
GPtrArray *checksums;
GPtrArray *categories;
GPtrArray *issues;
GHashTable *metadata;
gchar *description;
gchar *filename;
@ -41,6 +42,7 @@ typedef struct {
gchar *appstream_id;
gchar *license;
gchar *name;
gchar *name_variant_suffix;
gchar *summary;
gchar *uri;
gchar *vendor;
@ -239,6 +241,47 @@ fwupd_release_set_protocol (FwupdRelease *release, const gchar *protocol)
priv->protocol = g_strdup (protocol);
}
/**
* fwupd_release_get_issues:
* @release: A #FwupdRelease
*
* Gets the list of issues fixed in this release.
*
* Returns: (element-type utf8) (transfer none): the issues, which may be empty
*
* Since: 1.3.2
**/
GPtrArray *
fwupd_release_get_issues (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
return priv->issues;
}
/**
* fwupd_release_add_issue:
* @release: A #FwupdRelease
* @issue: the update issue, e.g. `CVE-2019-12345`
*
* Adds an resolved issue to this release.
*
* Since: 1.3.2
**/
void
fwupd_release_add_issue (FwupdRelease *release, const gchar *issue)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
g_return_if_fail (issue != NULL);
for (guint i = 0; i < priv->issues->len; i++) {
const gchar *issue_tmp = g_ptr_array_index (priv->issues, i);
if (g_strcmp0 (issue_tmp, issue) == 0)
return;
}
g_ptr_array_add (priv->issues, g_strdup (issue));
}
/**
* fwupd_release_get_categories:
* @release: A #FwupdRelease
@ -851,6 +894,42 @@ fwupd_release_set_name (FwupdRelease *release, const gchar *name)
priv->name = g_strdup (name);
}
/**
* fwupd_release_get_name_variant_suffix:
* @release: A #FwupdRelease
*
* Gets the update variant suffix.
*
* Returns: the update variant, or %NULL if unset
*
* Since: 1.3.2
**/
const gchar *
fwupd_release_get_name_variant_suffix (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
return priv->name_variant_suffix;
}
/**
* fwupd_release_set_name_variant_suffix:
* @release: A #FwupdRelease
* @name_variant_suffix: the description
*
* Sets the update variant suffix.
*
* Since: 1.3.2
**/
void
fwupd_release_set_name_variant_suffix (FwupdRelease *release, const gchar *name_variant_suffix)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
g_return_if_fail (FWUPD_IS_RELEASE (release));
g_free (priv->name_variant_suffix);
priv->name_variant_suffix = g_strdup (name_variant_suffix);
}
/**
* fwupd_release_get_trust_flags:
* @release: A #FwupdRelease
@ -1089,6 +1168,11 @@ fwupd_release_to_variant (FwupdRelease *release)
FWUPD_RESULT_KEY_NAME,
g_variant_new_string (priv->name));
}
if (priv->name_variant_suffix != NULL) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_NAME_VARIANT_SUFFIX,
g_variant_new_string (priv->name_variant_suffix));
}
if (priv->size != 0) {
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_SIZE,
@ -1112,6 +1196,14 @@ fwupd_release_to_variant (FwupdRelease *release)
FWUPD_RESULT_KEY_CATEGORIES,
g_variant_new_strv (strv, -1));
}
if (priv->issues->len > 0) {
g_autofree const gchar **strv = g_new0 (const gchar *, priv->issues->len + 1);
for (guint i = 0; i < priv->issues->len; i++)
strv[i] = (const gchar *) g_ptr_array_index (priv->issues, i);
g_variant_builder_add (&builder, "{sv}",
FWUPD_RESULT_KEY_ISSUES,
g_variant_new_strv (strv, -1));
}
if (priv->checksums->len > 0) {
g_autoptr(GString) str = g_string_new ("");
for (guint i = 0; i < priv->checksums->len; i++) {
@ -1200,6 +1292,10 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
fwupd_release_set_name (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME_VARIANT_SUFFIX) == 0) {
fwupd_release_set_name_variant_suffix (release, g_variant_get_string (value, NULL));
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_SIZE) == 0) {
fwupd_release_set_size (release, g_variant_get_uint64 (value));
return;
@ -1218,6 +1314,12 @@ fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant
fwupd_release_add_category (release, strv[i]);
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_ISSUES) == 0) {
g_autofree const gchar **strv = g_variant_get_strv (value, NULL);
for (guint i = 0; strv[i] != NULL; i++)
fwupd_release_add_issue (release, strv[i]);
return;
}
if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) {
const gchar *checksums = g_variant_get_string (value, NULL);
g_auto(GStrv) split = g_strsplit (checksums, ",", -1);
@ -1374,6 +1476,15 @@ fwupd_release_to_json (FwupdRelease *release, JsonBuilder *builder)
}
json_builder_end_array (builder);
}
if (priv->issues->len > 0) {
json_builder_set_member_name (builder, FWUPD_RESULT_KEY_ISSUES);
json_builder_begin_array (builder);
for (guint i = 0; i < priv->issues->len; i++) {
const gchar *tmp = g_ptr_array_index (priv->issues, i);
json_builder_add_string_value (builder, tmp);
}
json_builder_end_array (builder);
}
if (priv->checksums->len > 0) {
json_builder_set_member_name (builder, FWUPD_RESULT_KEY_CHECKSUM);
json_builder_begin_array (builder);
@ -1445,6 +1556,10 @@ fwupd_release_to_string (FwupdRelease *release)
const gchar *tmp = g_ptr_array_index (priv->categories, i);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_CATEGORIES, tmp);
}
for (guint i = 0; i < priv->issues->len; i++) {
const gchar *tmp = g_ptr_array_index (priv->issues, i);
fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_ISSUES, tmp);
}
for (guint i = 0; i < priv->checksums->len; i++) {
const gchar *checksum = g_ptr_array_index (priv->checksums, i);
g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum);
@ -1484,6 +1599,7 @@ fwupd_release_init (FwupdRelease *release)
{
FwupdReleasePrivate *priv = GET_PRIVATE (release);
priv->categories = g_ptr_array_new_with_free_func (g_free);
priv->issues = g_ptr_array_new_with_free_func (g_free);
priv->checksums = g_ptr_array_new_with_free_func (g_free);
priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}
@ -1500,6 +1616,7 @@ fwupd_release_finalize (GObject *object)
g_free (priv->appstream_id);
g_free (priv->license);
g_free (priv->name);
g_free (priv->name_variant_suffix);
g_free (priv->summary);
g_free (priv->uri);
g_free (priv->homepage);
@ -1510,6 +1627,7 @@ fwupd_release_finalize (GObject *object)
g_free (priv->remote_id);
g_free (priv->update_message);
g_ptr_array_unref (priv->categories);
g_ptr_array_unref (priv->issues);
g_ptr_array_unref (priv->checksums);
g_hash_table_unref (priv->metadata);

View File

@ -37,6 +37,9 @@ void fwupd_release_set_version (FwupdRelease *release,
const gchar *fwupd_release_get_uri (FwupdRelease *release);
void fwupd_release_set_uri (FwupdRelease *release,
const gchar *uri);
GPtrArray *fwupd_release_get_issues (FwupdRelease *release);
void fwupd_release_add_issue (FwupdRelease *release,
const gchar *issue);
GPtrArray *fwupd_release_get_categories (FwupdRelease *release);
void fwupd_release_add_category (FwupdRelease *release,
const gchar *category);
@ -75,6 +78,9 @@ void fwupd_release_set_vendor (FwupdRelease *release,
const gchar *fwupd_release_get_name (FwupdRelease *release);
void fwupd_release_set_name (FwupdRelease *release,
const gchar *name);
const gchar *fwupd_release_get_name_variant_suffix (FwupdRelease *release);
void fwupd_release_set_name_variant_suffix (FwupdRelease *release,
const gchar *name_variant_suffix);
const gchar *fwupd_release_get_summary (FwupdRelease *release);
void fwupd_release_set_summary (FwupdRelease *release,
const gchar *summary);

View File

@ -24,4 +24,6 @@ void fwupd_remote_set_mtime (FwupdRemote *self,
gchar **fwupd_remote_get_order_after (FwupdRemote *self);
gchar **fwupd_remote_get_order_before (FwupdRemote *self);
void fwupd_remote_set_remotes_dir (FwupdRemote *self,
const gchar *directory);
G_END_DECLS

View File

@ -47,6 +47,7 @@ typedef struct {
guint64 mtime;
gchar **order_after;
gchar **order_before;
gchar *remotes_dir;
} FwupdRemotePrivate;
enum {
@ -447,11 +448,15 @@ fwupd_remote_load_from_filename (FwupdRemote *self,
if (password != NULL)
fwupd_remote_set_password (self, password);
if (priv->remotes_dir == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"Remotes directory not set");
return FALSE;
}
/* set cache to /var/lib... */
filename_cache = g_build_filename (LOCALSTATEDIR,
"lib",
"fwupd",
"remotes.d",
filename_cache = g_build_filename (priv->remotes_dir,
priv->id,
"metadata.xml.gz",
NULL);
@ -677,6 +682,24 @@ fwupd_remote_get_age (FwupdRemote *self)
return now - priv->mtime;
}
/**
* fwupd_remote_set_remotes_dir:
* @self: A #FwupdRemote
* @directory: Remotes directory
*
* Sets the directory to store remote data
*
* Since: 1.3.1
**/
void
fwupd_remote_set_remotes_dir (FwupdRemote *self, const gchar *directory)
{
FwupdRemotePrivate *priv = GET_PRIVATE (self);
g_return_if_fail (FWUPD_IS_REMOTE (self));
g_free (priv->remotes_dir);
priv->remotes_dir = g_strdup (directory);
}
/**
* fwupd_remote_set_priority:
* @self: A #FwupdRemote
@ -783,6 +806,24 @@ fwupd_remote_get_agreement (FwupdRemote *self)
return priv->agreement;
}
/**
* fwupd_remote_get_remotes_dir:
* @self: A #FwupdRemote
*
* Gets the base directory for storing remote metadata
*
* Returns: a string, or %NULL if unset
*
* Since: 1.3.1
**/
const gchar *
fwupd_remote_get_remotes_dir (FwupdRemote *self)
{
FwupdRemotePrivate *priv = GET_PRIVATE (self);
g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
return priv->remotes_dir;
}
/**
* fwupd_remote_get_checksum:
* @self: A #FwupdRemote
@ -1083,6 +1124,10 @@ fwupd_remote_to_variant (FwupdRemote *self)
g_variant_builder_add (&builder, "{sv}", "FilenameSource",
g_variant_new_string (priv->filename_source));
}
if (priv->remotes_dir != NULL) {
g_variant_builder_add (&builder, "{sv}", "RemotesDir",
g_variant_new_string (priv->remotes_dir));
}
g_variant_builder_add (&builder, "{sv}", "Enabled",
g_variant_new_boolean (priv->enabled));
g_variant_builder_add (&builder, "{sv}", "ApprovalRequired",
@ -1200,6 +1245,7 @@ fwupd_remote_finalize (GObject *obj)
g_free (priv->password);
g_free (priv->title);
g_free (priv->agreement);
g_free (priv->remotes_dir);
g_free (priv->checksum);
g_free (priv->filename_cache);
g_free (priv->filename_cache_sig);

View File

@ -51,6 +51,7 @@ FwupdRemote *fwupd_remote_new (void);
const gchar *fwupd_remote_get_id (FwupdRemote *self);
const gchar *fwupd_remote_get_title (FwupdRemote *self);
const gchar *fwupd_remote_get_agreement (FwupdRemote *self);
const gchar *fwupd_remote_get_remotes_dir (FwupdRemote *self);
const gchar *fwupd_remote_get_checksum (FwupdRemote *self);
const gchar *fwupd_remote_get_username (FwupdRemote *self);
const gchar *fwupd_remote_get_password (FwupdRemote *self);

View File

@ -142,10 +142,17 @@ fwupd_remote_download_func (void)
{
gboolean ret;
g_autofree gchar *fn = NULL;
g_autofree gchar *directory = NULL;
g_autoptr(FwupdRemote) remote = NULL;
g_autoptr(GError) error = NULL;
remote = fwupd_remote_new ();
directory = g_build_filename (LOCALSTATEDIR,
"lib",
"fwupd",
"remotes.d",
NULL);
fwupd_remote_set_remotes_dir (remote, directory);
fn = g_build_filename (FU_SELF_TEST_REMOTES_DIR, "remotes.d", "lvfs.conf", NULL);
ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error);
g_assert_no_error (error);
@ -172,9 +179,16 @@ fwupd_remote_baseuri_func (void)
g_autofree gchar *firmware_uri = NULL;
g_autofree gchar *fn = NULL;
g_autoptr(FwupdRemote) remote = NULL;
g_autofree gchar *directory = NULL;
g_autoptr(GError) error = NULL;
remote = fwupd_remote_new ();
directory = g_build_filename (LOCALSTATEDIR,
"lib",
"fwupd",
"remotes.d",
NULL);
fwupd_remote_set_remotes_dir (remote, directory);
fn = g_build_filename (TESTDATADIR, "tests", "firmware-base-uri.conf", NULL);
ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error);
g_assert_no_error (error);
@ -202,8 +216,15 @@ fwupd_remote_nopath_func (void)
g_autofree gchar *fn = NULL;
g_autoptr(FwupdRemote) remote = NULL;
g_autoptr(GError) error = NULL;
g_autofree gchar *directory = NULL;
remote = fwupd_remote_new ();
directory = g_build_filename (LOCALSTATEDIR,
"lib",
"fwupd",
"remotes.d",
NULL);
fwupd_remote_set_remotes_dir (remote, directory);
fn = g_build_filename (TESTDATADIR, "tests", "firmware-nopath.conf", NULL);
ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error);
g_assert_no_error (error);
@ -504,6 +525,8 @@ fwupd_has_system_bus (void)
static void
fwupd_common_machine_hash_func (void)
{
gsize sz = 0;
g_autofree gchar *buf = NULL;
g_autofree gchar *mhash1 = NULL;
g_autofree gchar *mhash2 = NULL;
g_autoptr(GError) error = NULL;
@ -512,6 +535,15 @@ fwupd_common_machine_hash_func (void)
g_test_skip ("Missing /etc/machine-id");
return;
}
if (!g_file_get_contents ("/etc/machine-id", &buf, &sz, &error)) {
g_test_skip ("/etc/machine-id is unreadable");
return;
}
if (sz == 0) {
g_test_skip ("Empty /etc/machine-id");
return;
}
mhash1 = fwupd_build_machine_id ("salt1", &error);
g_assert_no_error (error);

View File

@ -371,3 +371,21 @@ LIBFWUPD_1.2.10 {
fwupd_remote_array_from_variant;
local: *;
} LIBFWUPD_1.2.9;
LIBFWUPD_1.3.1 {
global:
fwupd_client_get_host_product;
fwupd_remote_get_remotes_dir;
fwupd_remote_set_remotes_dir;
local: *;
} LIBFWUPD_1.2.10;
LIBFWUPD_1.3.2 {
global:
fwupd_client_get_host_machine_id;
fwupd_release_add_issue;
fwupd_release_get_issues;
fwupd_release_get_name_variant_suffix;
fwupd_release_set_name_variant_suffix;
local: *;
} LIBFWUPD_1.3.1;

View File

@ -1,5 +1,5 @@
project('fwupd', 'c',
version : '1.2.10',
version : '1.3.2',
license : 'LGPL-2.1+',
meson_version : '>=0.47.0',
default_options : ['warning_level=2', 'c_std=c99'],
@ -79,6 +79,7 @@ warning_flags = [
'-Wno-cast-function-type',
'-Wno-address-of-packed-member', # incompatible with g_autoptr()
'-Wno-unknown-pragmas',
'-Wno-deprecated-declarations',
'-Wno-discarded-qualifiers',
'-Wno-missing-field-initializers',
'-Wno-strict-aliasing',
@ -134,6 +135,18 @@ add_project_arguments('-DFWUPD_DISABLE_DEPRECATED', language : 'c')
add_project_arguments('-D_BSD_SOURCE', language : 'c')
add_project_arguments('-D_XOPEN_SOURCE=700', language : 'c')
# sanity check
if get_option('build') == 'all'
build_standalone = true
build_daemon = true
elif get_option('build') == 'standalone'
build_standalone = true
build_daemon = false
elif get_option('build') == 'library'
build_standalone = false
build_daemon = false
endif
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))
@ -146,11 +159,12 @@ mandir = join_paths(prefix, get_option('mandir'))
localedir = join_paths(prefix, get_option('localedir'))
gio = dependency('gio-2.0', version : '>= 2.45.8')
giounix = dependency('gio-unix-2.0', version : '>= 2.45.8')
if gio.version().version_compare ('>= 2.55.0')
conf.set('HAVE_GIO_2_55_0', '1')
endif
if build_standalone
gmodule = dependency('gmodule-2.0')
giounix = dependency('gio-unix-2.0', version : '>= 2.45.8')
gudev = dependency('gudev-1.0')
if gudev.version().version_compare('>= 232')
conf.set('HAVE_GUDEV_232', '1')
@ -159,10 +173,11 @@ libxmlb = dependency('xmlb', version : '>= 0.1.7', fallback : ['libxmlb', 'libxm
gusb = dependency('gusb', version : '>= 0.2.9')
sqlite = dependency('sqlite3')
libarchive = dependency('libarchive')
endif
libjsonglib = dependency('json-glib-1.0', version : '>= 1.1.1')
valgrind = dependency('valgrind', required: false)
soup = dependency('libsoup-2.4', version : '>= 2.51.92')
if get_option('daemon')
if build_daemon
polkit = dependency('polkit-gobject-1', version : '>= 0.103')
if polkit.version().version_compare('>= 0.114')
conf.set('HAVE_POLKIT_0_114', '1')
@ -202,15 +217,15 @@ if valgrind.found()
conf.set('HAVE_VALGRIND', '1')
endif
if get_option('plugin_redfish')
if build_standalone and get_option('plugin_redfish')
efivar = dependency('efivar')
endif
if get_option('plugin_altos')
if build_standalone and get_option('plugin_altos')
libelf = dependency('libelf')
endif
if get_option('plugin_uefi')
if build_standalone and get_option('plugin_uefi')
cairo = dependency('cairo')
fontconfig = cc.find_library('fontconfig')
freetype = cc.find_library('freetype')
@ -219,6 +234,7 @@ if get_option('plugin_uefi')
efiboot = dependency('efiboot')
objcopy = find_program ('objcopy')
readelf = find_program ('readelf')
tpm2tss = dependency('tss2-esys', version : '>= 2.0')
efi_app_location = join_paths(libexecdir, 'fwupd', 'efi')
conf.set_quoted ('EFI_APP_LOCATION', efi_app_location)
@ -247,7 +263,7 @@ if get_option('plugin_uefi')
endif
endif
if get_option('plugin_dell')
if build_standalone and get_option('plugin_dell')
libsmbios_c = dependency('libsmbios_c', version : '>= 2.4.0')
efivar = dependency('efivar')
conf.set('HAVE_DELL', '1')
@ -256,63 +272,64 @@ if get_option('plugin_dell')
endif
endif
if get_option('plugin_modem_manager')
if build_standalone and get_option('plugin_modem_manager')
libmm_glib = dependency('mm-glib', version : '>= 1.10.0')
add_project_arguments('-DMM_REQUIRED_VERSION="1.10.0"', language : 'c')
libqmi_glib = dependency('qmi-glib', version : '>= 1.22.0')
add_project_arguments('-DQMI_REQUIRED_VERSION="1.23.1"', language : 'c')
endif
if get_option('plugin_nvme')
if build_standalone and get_option('plugin_nvme')
if not cc.has_header('linux/nvme_ioctl.h')
error('NVMe support requires kernel >= 4.4')
endif
endif
if get_option('plugin_synaptics')
if build_standalone and get_option('plugin_synaptics')
conf.set('HAVE_SYNAPTICS', '1')
endif
if get_option('plugin_thunderbolt')
if build_standalone and get_option('plugin_thunderbolt')
umockdev = dependency('umockdev-1.0', required: false)
conf.set('HAVE_THUNDERBOLT', '1')
endif
if get_option('plugin_flashrom')
if build_standalone and get_option('plugin_flashrom')
libflashrom = dependency('flashrom', fallback : ['flashrom', 'flashrom_dep'])
endif
if get_option('systemd')
if build_standalone and get_option('systemd')
systemd = dependency('systemd', version : '>= 211')
conf.set('HAVE_SYSTEMD' , '1')
conf.set('HAVE_LOGIND' , '1')
systemdunitdir = get_option('systemdunitdir')
if systemdunitdir == '' and get_option('systemd')
systemdunitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
endif
endif
if get_option('elogind')
if build_standalone and get_option('elogind')
elogind = dependency('libelogind', version : '>= 211')
conf.set('HAVE_LOGIND' , '1')
endif
if get_option('consolekit')
if build_standalone and get_option('consolekit')
conf.set('HAVE_CONSOLEKIT' , '1')
endif
systemdunitdir = get_option('systemdunitdir')
if systemdunitdir == '' and get_option('systemd')
systemdunitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
endif
gnome = import('gnome')
i18n = import('i18n')
plugin_dir = join_paths(libdir, 'fwupd-plugins-3')
conf.set_quoted('BINDIR', bindir)
conf.set_quoted('LIBEXECDIR', libexecdir)
conf.set_quoted('DATADIR', datadir)
conf.set_quoted('LOCALSTATEDIR', localstatedir)
conf.set_quoted('SYSCONFDIR', sysconfdir)
if build_standalone
plugin_dir = join_paths(libdir, 'fwupd-plugins-3')
conf.set_quoted('PLUGINDIR', plugin_dir)
endif
conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
conf.set_quoted('PACKAGE_NAME', meson.project_name())
@ -323,30 +340,34 @@ configure_file(
configuration : conf
)
plugin_deps = []
plugin_deps += libxmlb
plugin_deps += gio
plugin_deps += giounix
plugin_deps += gmodule
plugin_deps += gusb
plugin_deps += soup
plugin_deps += libarchive
plugin_deps += gudev
if build_standalone
plugin_deps = []
plugin_deps += libxmlb
plugin_deps += gio
plugin_deps += giounix
plugin_deps += gmodule
plugin_deps += gusb
plugin_deps += soup
plugin_deps += libarchive
plugin_deps += gudev
endif
subdir('data')
if get_option('gtkdoc')
gtkdocscan = find_program('gtkdoc-scan', required : true)
subdir('docs')
endif
subdir('libfwupd')
subdir('po')
if get_option('daemon')
if build_daemon
subdir('policy')
endif
subdir('src')
subdir('plugins')
subdir('contrib')
if build_standalone
subdir('data')
subdir('po')
subdir('src')
subdir('plugins')
subdir('contrib')
endif
if get_option('systemd') and get_option('daemon')
if get_option('systemd') and build_daemon
meson.add_install_script('meson_post_install.sh', systemdunitdir, localstatedir)
endif

View File

@ -1,9 +1,9 @@
option('daemon', type : 'boolean', value : true, description : 'enable the fwupd daemon')
option('build', type : 'combo', choices : ['all', 'standalone', 'library'], value : 'all', description : 'build type')
option('agent', type : 'boolean', value : true, description : 'enable the fwupd agent')
option('consolekit', type : 'boolean', value : true, description : 'enable ConsoleKit support')
option('firmware-packager', type : 'boolean', value : true, description : 'enable firmware-packager installation')
option('gpg', type : 'boolean', value : true, description : 'enable the GPG verification support')
option('gtkdoc', type : 'boolean', value : true, description : 'enable developer documentation')
option('gtkdoc', type : 'boolean', value : false, description : 'enable developer documentation')
option('introspection', type : 'boolean', value : true, description : 'generate GObject Introspection data')
option('lvfs', type : 'boolean', value : true, description : 'enable LVFS remotes')
option('man', type : 'boolean', value : true, description : 'enable man pages')

View File

@ -11,6 +11,4 @@ LOCALSTATEDIR=$2
echo 'Updating systemd deps'
mkdir -p ${DESTDIR}${SYSTEMDUNITDIR}/system-update.target.wants
ln -sf ../fwupd-offline-update.service ${DESTDIR}${SYSTEMDUNITDIR}/system-update.target.wants/fwupd-offline-update.service
echo 'Creating stateful directory'
mkdir -p ${DESTDIR}${LOCALSTATEDIR}/lib/fwupd
#fi

View File

@ -7,12 +7,15 @@ and writing different firmware) as well as ways quirk their behavior.
You can find more information about the architecture in the developers section
of the [fwupd website](https://fwupd.org).
You can use the [fwupd developer documentation](https://fwupd.github.io) to assist
with APIs available to write the plugin.
If you have a firmware specification and would like to see support
in this project, please file an issue and share the spec. Patches are also
welcome.
We will not accept plugins that upgrade hardware using a proprietary Linux
executable, library, or DBus interface.
executable, proprietary UEFI executable, proprietary library, or DBus interface.
Plugin interaction
------------------
@ -21,6 +24,6 @@ This includes things like one plugin turning on a device, or providing missing
metadata to another plugin.
The ABI for these interactions is defined in:
https://github.com/hughsie/fwupd/blob/master/src/fu-device-metadata.h
https://github.com/fwupd/fwupd/blob/master/src/fu-device-metadata.h
All interactions between plugins should have the interface defined in that file.

View File

@ -268,19 +268,31 @@ fu_altos_device_write_page (FuAltosDevice *self,
return TRUE;
}
static FuFirmware *
fu_altos_device_prepare_firmware (FuDevice *device,
GBytes *fw,
FwupdInstallFlags flags,
GError **error)
{
g_autoptr(FuFirmware) firmware = fu_altos_firmware_new ();
if (!fu_firmware_parse (firmware, fw, flags, error))
return NULL;
return g_steal_pointer (&firmware);
}
static gboolean
fu_altos_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuAltosDevice *self = FU_ALTOS_DEVICE (device);
GBytes *fw_blob;
const gchar *data;
const gsize data_len;
guint flash_len;
g_autoptr(FuAltosFirmware) altos_firmware = NULL;
g_autoptr(FuDeviceLocker) locker = NULL;
g_autoptr(FuFirmwareImage) img = NULL;
g_autoptr(GBytes) fw = NULL;
g_autoptr(GString) buf = g_string_new (NULL);
/* check kind */
@ -312,25 +324,27 @@ fu_altos_device_write_firmware (FuDevice *device,
}
/* load ihex blob */
altos_firmware = fu_altos_firmware_new ();
if (!fu_altos_firmware_parse (altos_firmware, fw, error))
img = fu_firmware_get_image_default (firmware, error);
if (img == NULL)
return FALSE;
/* check the start address */
if (fu_altos_firmware_get_address (altos_firmware) != self->addr_base) {
if (fu_firmware_image_get_addr (img) != self->addr_base) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"start address not correct %" G_GUINT64_FORMAT ":"
"%" G_GUINT64_FORMAT,
fu_altos_firmware_get_address (altos_firmware),
fu_firmware_image_get_addr (img),
self->addr_base);
return FALSE;
}
/* check firmware will fit */
fw_blob = fu_altos_firmware_get_data (altos_firmware);
data = g_bytes_get_data (fw_blob, (gsize *) &data_len);
fw = fu_firmware_image_get_bytes (img, error);
if (fw == NULL)
return FALSE;
data = g_bytes_get_data (fw, (gsize *) &data_len);
if (data_len > flash_len) {
g_set_error (error,
FWUPD_ERROR,
@ -357,7 +371,10 @@ fu_altos_device_write_firmware (FuDevice *device,
gsize chunk_len = 0x100;
if (i + 0x100 > data_len)
chunk_len = data_len - i;
memcpy (buf_tmp, data + i, chunk_len);
if (!fu_memcpy_safe (buf_tmp, sizeof(buf_tmp), 0, /* dst */
(const guint8 *) data, data_len, i, /* src */
chunk_len, error))
return FALSE;
}
/* verify data from device */
@ -628,6 +645,7 @@ fu_altos_device_class_init (FuAltosDeviceClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
klass_device->probe = fu_altos_device_probe;
klass_device->prepare_firmware = fu_altos_device_prepare_firmware;
klass_device->write_firmware = fu_altos_device_write_firmware;
klass_device->read_firmware = fu_altos_device_read_firmware;
object_class->finalize = fu_altos_device_finalize;

View File

@ -1,45 +1,34 @@
/*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2017-2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include <gio/gio.h>
#include <gelf.h>
#include <libelf.h>
#include "fu-altos-firmware.h"
#include "fwupd-error.h"
struct _FuAltosFirmware {
GObject parent_instance;
GBytes *data;
guint64 address;
FuFirmware parent_instance;
};
G_DEFINE_TYPE (FuAltosFirmware, fu_altos_firmware, G_TYPE_OBJECT)
G_DEFINE_TYPE (FuAltosFirmware, fu_altos_firmware, FU_TYPE_FIRMWARE)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Elf, elf_end);
#pragma clang diagnostic pop
GBytes *
fu_altos_firmware_get_data (FuAltosFirmware *self)
{
return self->data;
}
guint64
fu_altos_firmware_get_address (FuAltosFirmware *self)
{
return self->address;
}
gboolean
fu_altos_firmware_parse (FuAltosFirmware *self, GBytes *blob, GError **error)
static gboolean
fu_altos_firmware_parse (FuFirmware *firmware,
GBytes *blob,
guint64 addr_start,
guint64 addr_end,
FwupdInstallFlags flags,
GError **error)
{
const gchar *name;
Elf_Scn *scn = NULL;
@ -99,8 +88,12 @@ fu_altos_firmware_parse (FuAltosFirmware *self, GBytes *blob, GError **error)
if (g_strcmp0 (name, ".text") == 0) {
Elf_Data *data = elf_getdata (scn, NULL);
if (data != NULL && data->d_buf != NULL) {
self->data = g_bytes_new (data->d_buf, data->d_size);
self->address = shdr.sh_addr;
g_autoptr(FuFirmwareImage) img = NULL;
g_autoptr(GBytes) bytes = NULL;
bytes = g_bytes_new (data->d_buf, data->d_size);
img = fu_firmware_image_new (bytes);
fu_firmware_image_set_addr (img, shdr.sh_addr);
fu_firmware_add_image (firmware, img);
}
return TRUE;
}
@ -112,22 +105,11 @@ fu_altos_firmware_parse (FuAltosFirmware *self, GBytes *blob, GError **error)
return FALSE;
}
static void
fu_altos_firmware_finalize (GObject *object)
{
FuAltosFirmware *self = FU_ALTOS_FIRMWARE (object);
if (self->data != NULL)
g_bytes_unref (self->data);
G_OBJECT_CLASS (fu_altos_firmware_parent_class)->finalize (object);
}
static void
fu_altos_firmware_class_init (FuAltosFirmwareClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = fu_altos_firmware_finalize;
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
klass_firmware->parse = fu_altos_firmware_parse;
}
static void
@ -135,10 +117,8 @@ fu_altos_firmware_init (FuAltosFirmware *self)
{
}
FuAltosFirmware *
FuFirmware *
fu_altos_firmware_new (void)
{
FuAltosFirmware *self;
self = g_object_new (FU_TYPE_ALTOS_FIRMWARE, NULL);
return FU_ALTOS_FIRMWARE (self);
return FU_FIRMWARE (g_object_new (FU_TYPE_ALTOS_FIRMWARE, NULL));
}

View File

@ -1,22 +1,19 @@
/*
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2017-2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include "fu-firmware.h"
G_BEGIN_DECLS
#define FU_TYPE_ALTOS_FIRMWARE (fu_altos_firmware_get_type ())
G_DECLARE_FINAL_TYPE (FuAltosFirmware, fu_altos_firmware, FU, ALTOS_FIRMWARE, GObject)
G_DECLARE_FINAL_TYPE (FuAltosFirmware, fu_altos_firmware, FU, ALTOS_FIRMWARE, FuFirmware)
FuAltosFirmware *fu_altos_firmware_new (void);
GBytes *fu_altos_firmware_get_data (FuAltosFirmware *self);
guint64 fu_altos_firmware_get_address (FuAltosFirmware *self);
gboolean fu_altos_firmware_parse (FuAltosFirmware *self,
GBytes *blob,
GError **error);
FuFirmware *fu_altos_firmware_new (void);
G_END_DECLS

View File

@ -119,15 +119,14 @@ fu_ata_device_get_string (const guint16 *buf, guint start, guint end)
}
static void
fu_ata_device_to_string (FuDevice *device, GString *str)
fu_ata_device_to_string (FuDevice *device, guint idt, GString *str)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
g_string_append (str, " FuAtaDevice:\n");
g_string_append_printf (str, " fd:\t\t\t%i\n", self->fd);
g_string_append_printf (str, " transfer-mode:\t0x%x\n", (guint) self->transfer_mode);
g_string_append_printf (str, " transfer-size:\t0x%x\n", (guint) self->transfer_blocks);
g_string_append_printf (str, " pci-depth:\t\t%u\n", self->pci_depth);
g_string_append_printf (str, " usb-depth:\t\t%u\n", self->usb_depth);
fu_common_string_append_ku (str, idt, "FD", (guint) self->fd);
fu_common_string_append_kx (str, idt, "TransferMode", self->transfer_mode);
fu_common_string_append_kx (str, idt, "TransferBlocks", self->transfer_blocks);
fu_common_string_append_ku (str, idt, "PciDepth", self->pci_depth);
fu_common_string_append_ku (str, idt, "UsbDepth", self->usb_depth);
}
/* https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices */
@ -578,15 +577,21 @@ fu_ata_device_fw_download (FuAtaDevice *self,
static gboolean
fu_ata_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuAtaDevice *self = FU_ATA_DEVICE (device);
guint32 chunksz = (guint32) self->transfer_blocks * FU_ATA_BLOCK_SIZE;
guint max_size = 0xffff * FU_ATA_BLOCK_SIZE;
g_autoptr(GBytes) fw = NULL;
g_autoptr(GPtrArray) chunks = NULL;
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* only one block allowed */
if (self->transfer_mode == ATA_SUBCMD_MICROCODE_DOWNLOAD_CHUNK)
max_size = 0xffff;

View File

@ -78,8 +78,12 @@ fu_colorhug_device_msg (FuColorhugDevice *self, guint8 cmd,
}
/* optionally copy in data */
if (ibuf != NULL)
memcpy (buf + 1, ibuf, ibufsz);
if (ibuf != NULL) {
if (!fu_memcpy_safe (buf, sizeof(buf), 0x1, /* dst */
ibuf, ibufsz, 0x0, /* src */
ibufsz, error))
return FALSE;
}
/* request */
if (g_getenv ("FWUPD_COLORHUG_VERBOSE") != NULL)
@ -151,9 +155,12 @@ fu_colorhug_device_msg (FuColorhugDevice *self, guint8 cmd,
}
/* copy back optional buf */
if (obuf != NULL)
memcpy (obuf, buf + 2, obufsz);
if (obuf != NULL) {
if (!fu_memcpy_safe (obuf, obufsz, 0x0, /* dst */
buf, sizeof(buf), 0x2, /* src */
obufsz, error))
return FALSE;
}
return TRUE;
}
@ -328,13 +335,19 @@ ch_colorhug_device_calculate_checksum (const guint8 *data, guint32 len)
static gboolean
fu_colorhug_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuColorhugDevice *self = FU_COLORHUG_DEVICE (device);
g_autoptr(GBytes) fw = NULL;
g_autoptr(GPtrArray) chunks = NULL;
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* build packets */
chunks = fu_chunk_array_new_from_bytes (fw,
self->start_addr,
@ -360,7 +373,10 @@ fu_colorhug_device_write_firmware (FuDevice *device,
fu_common_write_uint16 (buf + 0, chk->address, G_LITTLE_ENDIAN);
buf[2] = chk->data_sz;
buf[3] = ch_colorhug_device_calculate_checksum (chk->data, chk->data_sz);
memcpy (buf + 4, chk->data, chk->data_sz);
if (!fu_memcpy_safe (buf, sizeof(buf), 0x4, /* dst */
chk->data, chk->data_sz, 0x0, /* src */
chk->data_sz, error))
return FALSE;
if (!fu_colorhug_device_msg (self, CH_CMD_WRITE_FLASH,
buf, sizeof(buf), /* in */
NULL, 0, /* out */

View File

@ -10,9 +10,9 @@
#include "fu-chunk.h"
#include "fu-csr-device.h"
#include "fu-ihex-firmware.h"
#include "dfu-common.h"
#include "dfu-firmware.h"
/**
* FU_CSR_DEVICE_QUIRK_FLAG_REQUIRE_DELAY:
@ -59,12 +59,11 @@ G_DEFINE_TYPE (FuCsrDevice, fu_csr_device, FU_TYPE_USB_DEVICE)
#define FU_CSR_DEVICE_TIMEOUT 5000 /* ms */
static void
fu_csr_device_to_string (FuDevice *device, GString *str)
fu_csr_device_to_string (FuDevice *device, guint idt, GString *str)
{
FuCsrDevice *self = FU_CSR_DEVICE (device);
g_string_append (str, " DfuCsrDevice:\n");
g_string_append_printf (str, " state:\t\t%s\n", dfu_state_to_string (self->dfu_state));
g_string_append_printf (str, " timeout:\t\t%" G_GUINT32_FORMAT "\n", self->dnload_timeout);
fu_common_string_append_kv (str, idt, "State", dfu_state_to_string (self->dfu_state));
fu_common_string_append_ku (str, idt, "DownloadTimeout", self->dnload_timeout);
}
static gboolean
@ -352,7 +351,10 @@ fu_csr_device_download_chunk (FuCsrDevice *self, guint16 idx, GBytes *chunk, GEr
buf[1] = FU_CSR_COMMAND_UPGRADE;
fu_common_write_uint16 (&buf[2], idx, G_LITTLE_ENDIAN);
fu_common_write_uint16 (&buf[4], chunk_sz, G_LITTLE_ENDIAN);
memcpy (buf + FU_CSR_COMMAND_HEADER_SIZE, chunk_data, chunk_sz);
if (!fu_memcpy_safe (buf, sizeof(buf), FU_CSR_COMMAND_HEADER_SIZE, /* dst */
chunk_data, chunk_sz, 0x0, /* src */
chunk_sz, error))
return FALSE;
/* hit hardware */
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL)
@ -416,71 +418,44 @@ fu_csr_device_download_chunk (FuCsrDevice *self, guint16 idx, GBytes *chunk, GEr
return TRUE;
}
static GBytes *
_dfu_firmware_get_default_element_data (DfuFirmware *firmware)
{
DfuElement *element;
DfuImage *image;
image = dfu_firmware_get_image_default (firmware);
if (image == NULL)
return NULL;
element = dfu_image_get_element_default (image);
if (element == NULL)
return NULL;
return dfu_element_get_contents (element);
}
static GBytes *
static FuFirmware *
fu_csr_device_prepare_firmware (FuDevice *device,
GBytes *fw,
FwupdInstallFlags flags,
GError **error)
{
GBytes *blob_noftr;
g_autoptr(DfuFirmware) dfu_firmware = dfu_firmware_new ();
g_autoptr(FuFirmware) firmware = fu_ihex_firmware_new ();
/* parse the file */
if (!dfu_firmware_parse_data (dfu_firmware, fw,
DFU_FIRMWARE_PARSE_FLAG_NONE, error))
if (!fu_firmware_parse (firmware, fw, flags, error))
return NULL;
if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL) {
g_autofree gchar *fw_str = NULL;
fw_str = dfu_firmware_to_string (dfu_firmware);
fw_str = fu_firmware_to_string (firmware);
g_debug ("%s", fw_str);
}
if (dfu_firmware_get_format (dfu_firmware) != DFU_FIRMWARE_FORMAT_DFU) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"expected DFU firmware");
return NULL;
}
/* get the blob from the firmware file */
blob_noftr = _dfu_firmware_get_default_element_data (dfu_firmware);
if (blob_noftr == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"firmware contained no data");
return NULL;
}
/* success */
return g_bytes_ref (blob_noftr);
return g_steal_pointer (&firmware);
}
static gboolean
fu_csr_device_download (FuDevice *device,
GBytes *blob,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuCsrDevice *self = FU_CSR_DEVICE (device);
guint16 idx;
g_autoptr(GBytes) blob_empty = NULL;
g_autoptr(GBytes) blob = NULL;
g_autoptr(GPtrArray) chunks = NULL;
/* get default image */
blob = fu_firmware_get_image_default_bytes (firmware, error);
if (blob == NULL)
return FALSE;
/* notify UI */
fu_device_set_status (device, FWUPD_STATUS_DEVICE_WRITE);

View File

@ -97,6 +97,7 @@ DellDockInstallDurationI2C=360
DellDockBlobMajorOffset = 0x18400
DellDockBlobMinorOffset = 0x18401
DellDockBlobBuildOffset = 0x18402
Icon = video-display
# Thunderbolt controller
[Guid=TBT-00d4b070]
@ -107,6 +108,7 @@ ParentGuid = USB\VID_413C&PID_B06E&hub&embedded
FirmwareSizeMin=0x40000
FirmwareSizeMax=0x80000
Flags = require-ac
Icon = thunderbolt
InstallDuration = 22
DellDockInstallDurationI2C = 181
DellDockUnlockTarget = 10

View File

@ -46,22 +46,30 @@ fu_dell_dock_hub_probe (FuDevice *device, GError **error)
static gboolean
fu_dell_dock_hub_write_fw (FuDevice *device,
GBytes *blob_fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuDellDockHub *self = FU_DELL_DOCK_HUB (device);
gsize fw_size = 0;
const guint8 *data = g_bytes_get_data (blob_fw, &fw_size);
gsize write_size =
(fw_size / HIDI2C_MAX_WRITE) >= 1 ? HIDI2C_MAX_WRITE : fw_size;
const guint8 *data;
gsize write_size;
gsize nwritten = 0;
guint32 address = 0;
gboolean result = FALSE;
g_autofree gchar *dynamic_version = NULL;
g_autoptr(GBytes) fw = NULL;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (blob_fw != NULL, FALSE);
g_return_val_if_fail (FU_IS_FIRMWARE (firmware), FALSE);
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
data = g_bytes_get_data (fw, &fw_size);
write_size = (fw_size / HIDI2C_MAX_WRITE) >= 1 ?
HIDI2C_MAX_WRITE : fw_size;
dynamic_version = g_strdup_printf ("%02x.%02x",
data[self->blob_major_offset],

View File

@ -529,39 +529,25 @@ fu_dell_dock_ec_get_dock_data (FuDevice *device,
}
static void
fu_dell_dock_ec_to_string (FuDevice *device, GString *str)
fu_dell_dock_ec_to_string (FuDevice *device, guint idt, GString *str)
{
FuDellDockEc *self = FU_DELL_DOCK_EC (device);
gchar service_tag[8] = {0x00};
g_string_append (str, " FuDellDellDockEc:\n");
g_string_append_printf (str, "\tboard ID: %u\n",
self->data->board_id);
g_string_append_printf (str, "\tpower supply: %uW\n",
self->data->power_supply_wattage);
g_string_append_printf (str, "\tstatus (port0): %x\n",
self->data->port0_dock_status);
g_string_append_printf (str, "\tstatus (port1): %x\n",
self->data->port1_dock_status);
fu_common_string_append_ku (str, idt, "BoardId", self->data->board_id);
fu_common_string_append_ku (str, idt, "PowerSupply", self->data->power_supply_wattage);
fu_common_string_append_kx (str, idt, "StatusPort0", self->data->port0_dock_status);
fu_common_string_append_kx (str, idt, "StatusPort1", self->data->port1_dock_status);
memcpy (service_tag, self->data->service_tag, 7);
g_string_append_printf (str, "\tservice tag: %s\n",
service_tag);
g_string_append_printf (str, "\tconfiguration: %u\n",
self->data->dock_configuration);
g_string_append_printf (str, "\tpackage firmware version: %x\n",
self->data->dock_firmware_pkg_ver);
g_string_append_printf (str, "\tmodule serial #: %08" G_GUINT64_FORMAT "\n",
self->data->module_serial);
g_string_append_printf (str, "\toriginal module serial #: %08" G_GUINT64_FORMAT "\n",
self->data->original_module_serial);
g_string_append_printf (str, "\ttype: %u\n",
self->data->dock_type);
g_string_append_printf (str, "\tmodule type: %x\n",
self->data->module_type);
g_string_append_printf (str, "\tminimum ec: %s\n",
self->ec_minimum_version);
g_string_append_printf (str, "\tpassive flow: %d\n",
self->passive_flow);
fu_common_string_append_kv (str, idt, "ServiceTag", service_tag);
fu_common_string_append_ku (str, idt, "Configuration", self->data->dock_configuration);
fu_common_string_append_kx (str, idt, "PackageFirmwareVersion", self->data->dock_firmware_pkg_ver);
fu_common_string_append_ku (str, idt, "ModuleSerial", self->data->module_serial);
fu_common_string_append_ku (str, idt, "OriginalModuleSerial", self->data->original_module_serial);
fu_common_string_append_ku (str, idt, "Type", self->data->dock_type);
fu_common_string_append_kx (str, idt, "ModuleType", self->data->module_type);
fu_common_string_append_kv (str, idt, "MinimumEc", self->ec_minimum_version);
fu_common_string_append_ku (str, idt, "PassiveFlow", self->passive_flow);
}
gboolean
@ -745,7 +731,7 @@ fu_dell_dock_ec_commit_package (FuDevice *device, GBytes *blob_fw,
static gboolean
fu_dell_dock_ec_write_fw (FuDevice *device,
GBytes *blob_fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
@ -753,15 +739,22 @@ fu_dell_dock_ec_write_fw (FuDevice *device,
FuDellDockECFWUpdateStatus status = FW_UPDATE_IN_PROGRESS;
guint8 progress1 = 0, progress0 = 0;
gsize fw_size = 0;
const guint8 *data = g_bytes_get_data (blob_fw, &fw_size);
gsize write_size =
(fw_size / HIDI2C_MAX_WRITE) >= 1 ? HIDI2C_MAX_WRITE : fw_size;
const guint8 *data;
gsize write_size = 0;
gsize nwritten = 0;
guint32 address = 0 | 0xff << 24;
g_autofree gchar *dynamic_version = NULL;
g_autoptr(GBytes) fw = NULL;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (blob_fw != NULL, FALSE);
g_return_val_if_fail (FU_IS_FIRMWARE (firmware), FALSE);
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
data = g_bytes_get_data (fw, &fw_size);
write_size = (fw_size / HIDI2C_MAX_WRITE) >= 1 ? HIDI2C_MAX_WRITE : fw_size;
dynamic_version = g_strndup ((gchar *) data + self->blob_version_offset, 11);
g_debug ("writing EC firmware version %s", dynamic_version);

View File

@ -735,7 +735,7 @@ fu_dell_dock_mst_invalidate_bank (FuDevice *symbiote, MSTBank bank_in_use,
static gboolean
fu_dell_dock_mst_write_fw (FuDevice *device,
GBytes *blob_fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
@ -745,13 +745,20 @@ fu_dell_dock_mst_write_fw (FuDevice *device,
gboolean checksum = FALSE;
guint8 order[2] = {ESM, Bank0};
guint16 chip_id;
const guint8* data = g_bytes_get_data (blob_fw, NULL);
const guint8 *data;
g_autofree gchar *dynamic_version = NULL;
g_autoptr(GBytes) fw = NULL;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (blob_fw != NULL, FALSE);
g_return_val_if_fail (FU_IS_FIRMWARE (firmware), FALSE);
g_return_val_if_fail (self->symbiote != NULL, FALSE);
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
data = g_bytes_get_data (fw, NULL);
dynamic_version = g_strdup_printf ("%02x.%02x.%02x",
data[self->blob_major_offset],
data[self->blob_minor_offset],
@ -787,7 +794,7 @@ fu_dell_dock_mst_write_fw (FuDevice *device,
for (guint phase = 0; phase < 2; phase++) {
g_debug ("MST: Checking bank %u", order[phase]);
if (!fu_dell_dock_mst_checksum_bank (self->symbiote,
blob_fw,
fw,
order[phase],
&checksum, error))
return FALSE;
@ -804,11 +811,11 @@ fu_dell_dock_mst_write_fw (FuDevice *device,
error))
return FALSE;
fu_device_set_status (device, FWUPD_STATUS_DEVICE_WRITE);
if (!fu_dell_dock_write_flash_bank (device, blob_fw,
if (!fu_dell_dock_write_flash_bank (device, fw,
order[phase], error))
return FALSE;
if (!fu_dell_dock_mst_checksum_bank (self->symbiote,
blob_fw,
fw,
order[phase],
&checksum,
error))

View File

@ -53,20 +53,27 @@ G_DEFINE_TYPE (FuDellDockTbt, fu_dell_dock_tbt, FU_TYPE_DEVICE)
static gboolean
fu_dell_dock_tbt_write_fw (FuDevice *device,
GBytes *blob_fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuDellDockTbt *self = FU_DELL_DOCK_TBT (device);
guint32 start_offset = 0;
gsize image_size;
const guint8 *buffer = g_bytes_get_data (blob_fw, &image_size);
gsize image_size = 0;
const guint8 *buffer;
guint16 target_system = 0;
g_autoptr(GTimer) timer = g_timer_new ();
g_autofree gchar *dynamic_version = NULL;
g_autoptr(GBytes) fw = NULL;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (blob_fw != NULL, FALSE);
g_return_val_if_fail (FU_IS_FIRMWARE (firmware), FALSE);
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
buffer = g_bytes_get_data (fw, &image_size);
dynamic_version = g_strdup_printf ("%02x.%02x",
buffer[self->blob_major_offset],

View File

@ -58,7 +58,7 @@ fu_dell_dock_status_setup (FuDevice *device, GError **error)
static gboolean
fu_dell_dock_status_write (FuDevice *device,
GBytes *blob_fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
@ -66,18 +66,27 @@ fu_dell_dock_status_write (FuDevice *device,
FuDevice *parent;
gsize length = 0;
guint32 status_version = 0;
const guint8 *data = g_bytes_get_data (blob_fw, &length);
const guint8 *data;
g_autofree gchar *dynamic_version = NULL;
g_autoptr(GBytes) fw = NULL;
g_return_val_if_fail (device != NULL, FALSE);
g_return_val_if_fail (blob_fw != NULL, FALSE);
g_return_val_if_fail (FU_IS_FIRMWARE (firmware), FALSE);
memcpy (&status_version, data + self->blob_version_offset, sizeof (guint32));
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
data = g_bytes_get_data (fw, &length);
if (!fu_memcpy_safe ((guint8 *) &status_version, sizeof(status_version), 0x0, /* dst */
data, length, self->blob_version_offset, /* src */
sizeof(status_version), error))
return FALSE;
dynamic_version = fu_dell_dock_status_ver_string (status_version);
g_debug ("writing status firmware version %s", dynamic_version);
parent = fu_device_get_parent (device);
if (!fu_dell_dock_ec_commit_package (parent, blob_fw, error))
if (!fu_dell_dock_ec_commit_package (parent, fw, error))
return FALSE;
/* dock will reboot to re-read; this is to appease the daemon */

View File

@ -87,6 +87,7 @@ void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_BETTER_THAN, "uefi");
}
gboolean
@ -159,9 +160,10 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error)
g_autoptr(FuDevice) dev = fu_device_new ();
/* create a dummy device so we can unlock the feature */
fu_device_set_id (dev, "UEFI-dummy-dev0");
fu_device_set_id (dev, "UEFI-dummy");
fu_device_set_name (dev, "Dell UEFI updates");
fu_device_set_summary (dev, "Enable UEFI Update Functionality");
fu_device_add_instance_id (dev, "main-system-firmware");
fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e");
fu_device_set_version (dev, "0", FWUPD_VERSION_FORMAT_NUMBER);
fu_device_add_icon (dev, "computer");

View File

@ -16,6 +16,23 @@ These devices uses custom GUIDs for Dell-specific hardware.
In both cases the `system-id` is derived from the SMBIOS Product SKU property.
TPM GUIDs are also built using the TSS properties
`TPM2_PT_FAMILY_INDICATOR`, `TPM2_PT_MANUFACTURER`, and `TPM2_PT_VENDOR_STRING_*`
These are built hierarchically with more parts for each GUID:
* `DELL-TPM-$FAMILY-$MANUFACTURER-$VENDOR_STRING_1`
* `DELL-TPM-$FAMILY-$MANUFACTURER-$VENDOR_STRING_1$VENDOR_STRING_2`
* `DELL-TPM-$FAMILY-$MANUFACTURER-$VENDOR_STRING_1$VENDOR_STRING_2$VENDOR_STRING_3`
* `DELL-TPM-$FAMILY-$MANUFACTURER-$VENDOR_STRING_1$VENDOR_STRING_2$VENDOR_STRING_3$VENDOR_STRING_4`
If there are non-ASCII values in any vendor string or any vendor is missing that octet will be skipped.
Example resultant GUIDs from a real system containing a TPM from Nuvoton:
```
Guid: 7d65b10b-bb24-552d-ade5-590b3b278188 <- DELL-TPM-2.0-NTC-NPCT
Guid: 6f5ddd3a-8339-5b2a-b9a6-cf3b92f6c86d <- DELL-TPM-2.0-NTC-NPCT75x
Guid: fe462d4a-e48f-5069-9172-47330fc5e838 <- DELL-TPM-2.0-NTC-NPCT75xrls
```
Build Requirements
------------------

View File

@ -12,6 +12,7 @@
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <tss2/tss2_esys.h>
#include "fwupd-common.h"
#include "fu-plugin-dell.h"
@ -85,9 +86,6 @@ struct da_structure {
#define UNIV_CBL_DESC "Universal Cable"
#define TBT_CBL_DESC "Thunderbolt Cable"
/* supported host related GUIDs */
#define MST_GPIO_GUID EFI_GUID (0xF24F9bE4, 0x2a13, 0x4344, 0xBC05, 0x01, 0xCE, 0xF7, 0xDA, 0xEF, 0x92)
/**
* Devices that should allow modeswitching
*/
@ -117,24 +115,6 @@ static guint8 enclosure_whitelist [] = { 0x03, /* desktop */
0x21, /* IoT gateway */
0x22, /* embedded PC */};
/**
* Systems containing host MST device
*/
static guint16 systems_host_mst [] = { 0x062d, /* Latitude E7250 */
0x062e, /* Latitude E7450 */
0x062a, /* Latitude E5250 */
0x062b, /* Latitude E5450 */
0x062c, /* Latitude E5550 */
0x06db, /* Latitude E7270 */
0x06dc, /* Latitude E7470 */
0x06dd, /* Latitude E5270 */
0x06de, /* Latitude E5470 */
0x06df, /* Latitude E5570 */
0x06e0, /* Precision 3510 */
0x071d, /* Latitude Rugged 7214 */
0x071e, /* Latitude Rugged 5414 */
0x071c, /* Latitude Rugged 7414 */};
static guint16
fu_dell_get_system_id (FuPlugin *plugin)
{
@ -152,26 +132,12 @@ fu_dell_get_system_id (FuPlugin *plugin)
return system_id;
}
static gboolean
fu_dell_host_mst_supported (FuPlugin *plugin)
{
guint16 system_id;
system_id = fu_dell_get_system_id (plugin);
if (system_id == 0)
return FALSE;
for (guint i = 0; i < G_N_ELEMENTS (systems_host_mst); i++)
if (systems_host_mst[i] == system_id)
return TRUE;
return FALSE;
}
static gboolean
fu_dell_supported (FuPlugin *plugin)
{
GBytes *de_table = NULL;
GBytes *da_table = NULL;
GBytes *enclosure = NULL;
g_autoptr(GBytes) de_table = NULL;
g_autoptr(GBytes) da_table = NULL;
g_autoptr(GBytes) enclosure = NULL;
const guint8 *value;
const struct da_structure *da_values;
gsize len;
@ -473,16 +439,13 @@ fu_plugin_usb_device_added (FuPlugin *plugin,
return FALSE;
}
#if defined (HAVE_SYNAPTICS)
fu_plugin_request_recoldplug (plugin);
#endif
return TRUE;
}
gboolean
fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error)
{
GBytes *de_table = NULL;
g_autoptr(GBytes) de_table = NULL;
const gchar *tmp = NULL;
const guint16 *completion_code;
gsize len;
@ -560,6 +523,117 @@ fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error)
return TRUE;
}
static void Esys_Finalize_autoptr_cleanup (ESYS_CONTEXT *esys_context)
{
Esys_Finalize (&esys_context);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ESYS_CONTEXT, Esys_Finalize_autoptr_cleanup)
static gchar *
fu_plugin_dell_get_tpm_capability (ESYS_CONTEXT *ctx, guint32 query)
{
TSS2_RC rc;
guint32 val;
gchar result[5] = {'\0'};
g_autofree TPMS_CAPABILITY_DATA *capability = NULL;
rc = Esys_GetCapability (ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
TPM2_CAP_TPM_PROPERTIES, query, 1, NULL, &capability);
if (rc != TSS2_RC_SUCCESS) {
g_debug ("capability request failed for query %x", query);
return NULL;
}
if (capability->data.tpmProperties.count == 0) {
g_debug ("no properties returned for query %x", query);
return NULL;
}
if (capability->data.tpmProperties.tpmProperty[0].property != query) {
g_debug ("wrong query returned (got %x expected %x)",
capability->data.tpmProperties.tpmProperty[0].property,
query);
return NULL;
}
val = GUINT32_FROM_BE (capability->data.tpmProperties.tpmProperty[0].value);
memcpy (result, (gchar *) &val, 4);
/* convert non-ASCII into spaces */
for (guint i = 0; i < 4; i++) {
if (!g_ascii_isgraph (result[i]) && result[i] != '\0')
result[i] = 0x20;
}
return fu_common_strstrip (result);
}
static gboolean
fu_plugin_dell_add_tpm_model (FuDevice *dev, GError **error)
{
TSS2_RC rc;
const gchar *base = "DELL-TPM";
g_autoptr(ESYS_CONTEXT) ctx = NULL;
g_autofree gchar *family = NULL;
g_autofree gchar *manufacturer = NULL;
g_autofree gchar *vendor1 = NULL;
g_autofree gchar *vendor2 = NULL;
g_autofree gchar *vendor3 = NULL;
g_autofree gchar *vendor4 = NULL;
g_autofree gchar *v1 = NULL;
g_autofree gchar *v1_v2 = NULL;
g_autofree gchar *v1_v2_v3 = NULL;
g_autofree gchar *v1_v2_v3_v4 = NULL;
rc = Esys_Initialize (&ctx, NULL, NULL);
if (rc != TSS2_RC_SUCCESS) {
g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND,
"failed to initialize TPM library");
return FALSE;
}
rc = Esys_Startup (ctx, TPM2_SU_CLEAR);
if (rc != TSS2_RC_SUCCESS) {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"failed to initialize TPM");
return FALSE;
}
/* lookup guaranteed details from TPM */
family = fu_plugin_dell_get_tpm_capability (ctx,
TPM2_PT_FAMILY_INDICATOR);
if (family == NULL) {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"failed to read TPM family");
return FALSE;
}
manufacturer = fu_plugin_dell_get_tpm_capability (ctx, TPM2_PT_MANUFACTURER);
if (manufacturer == NULL) {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"failed to read TPM manufacturer");
return FALSE;
}
vendor1 = fu_plugin_dell_get_tpm_capability (ctx, TPM2_PT_VENDOR_STRING_1);
if (vendor1 == NULL) {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"failed to read TPM vendor string");
return FALSE;
}
/* these are not guaranteed by spec and may be NULL */
vendor2 = fu_plugin_dell_get_tpm_capability (ctx, TPM2_PT_VENDOR_STRING_2);
vendor3 = fu_plugin_dell_get_tpm_capability (ctx, TPM2_PT_VENDOR_STRING_3);
vendor4 = fu_plugin_dell_get_tpm_capability (ctx, TPM2_PT_VENDOR_STRING_4);
/* add GUIDs to daemon */
v1 = g_strjoin ("-", base, family, manufacturer, vendor1, NULL);
v1_v2 = g_strconcat (v1, vendor2, NULL);
v1_v2_v3 = g_strconcat (v1_v2, vendor3, NULL);
v1_v2_v3_v4 = g_strconcat (v1_v2_v3, vendor4, NULL);
fu_device_add_instance_id (dev, v1);
fu_device_add_instance_id (dev, v1_v2);
fu_device_add_instance_id (dev, v1_v2_v3);
fu_device_add_instance_id (dev, v1_v2_v3_v4);
return TRUE;
}
gboolean
fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error)
{
@ -580,7 +654,7 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error)
struct tpm_status *out = NULL;
g_autoptr (FuDevice) dev_alt = NULL;
g_autoptr (FuDevice) dev = NULL;
const gchar *product_name = "Unknown";
g_autoptr(GError) error_tss = NULL;
fu_dell_clear_smi (data->smi_obj);
out = (struct tpm_status *) data->smi_obj->output;
@ -647,16 +721,13 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error)
FWUPD_VERSION_FORMAT_QUAD);
/* make it clear that the TPM is a discrete device of the product */
if (!data->smi_obj->fake_smbios) {
product_name = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME);
}
pretty_tpm_name = g_strdup_printf ("%s TPM %s", product_name, tpm_mode);
pretty_tpm_name_alt = g_strdup_printf ("%s TPM %s", product_name, tpm_mode_alt);
pretty_tpm_name = g_strdup_printf ("TPM %s", tpm_mode);
pretty_tpm_name_alt = g_strdup_printf ("TPM %s", tpm_mode_alt);
/* build Standard device nodes */
dev = fu_device_new ();
fu_device_set_id (dev, tpm_id);
fu_device_add_guid (dev, tpm_guid);
fu_device_add_instance_id (dev, tpm_guid_raw);
fu_device_set_vendor (dev, "Dell Inc.");
fu_device_set_name (dev, pretty_tpm_name);
fu_device_set_summary (dev, "Platform TPM device");
@ -675,16 +746,22 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error)
}
fu_device_set_flashes_left (dev, out->flashes_left);
} else {
g_debug ("%s updating disabled due to TPM ownership",
pretty_tpm_name);
fu_device_set_update_error (dev,
"Updating disabled due to TPM ownership");
}
/* build GUIDs from TSS strings */
if (!fu_plugin_dell_add_tpm_model (dev, &error_tss))
g_debug ("could not build instances: %s", error_tss->message);
if (!fu_device_setup (dev, error))
return FALSE;
fu_plugin_device_register (plugin, dev);
/* build alternate device node */
if (can_switch_modes) {
dev_alt = fu_device_new ();
fu_device_set_id (dev_alt, tpm_id_alt);
fu_device_add_guid (dev_alt, tpm_guid_alt);
fu_device_add_instance_id (dev_alt, tpm_guid_raw_alt);
fu_device_set_vendor (dev, "Dell Inc.");
fu_device_set_name (dev_alt, pretty_tpm_name_alt);
fu_device_set_summary (dev_alt, "Alternate mode for platform TPM device");
@ -704,9 +781,10 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error)
if ((out->status & TPM_OWN_MASK) == 0 && out->flashes_left > 0) {
fu_device_set_flashes_left (dev_alt, out->flashes_left);
} else {
g_debug ("%s mode switch disabled due to TPM ownership",
pretty_tpm_name);
fu_device_set_update_error (dev_alt, "mode switch disabled due to TPM ownership");
}
if (!fu_device_setup (dev_alt, error))
return FALSE;
fu_plugin_device_register (plugin, dev_alt);
}
else
@ -742,82 +820,6 @@ fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device)
}
}
static gboolean
fu_dell_toggle_flash (FuPlugin *plugin, FuDevice *device,
gboolean enable, GError **error)
{
FuPluginData *data = fu_plugin_get_data (plugin);
gboolean has_host = fu_dell_host_mst_supported (plugin);
gboolean has_dock;
guint32 dock_location;
const gchar *tmp;
if (device) {
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE))
return TRUE;
tmp = fu_device_get_plugin (device);
if (g_strcmp0 (tmp, "synapticsmst") != 0)
return TRUE;
g_debug ("preparing/cleaning update for %s", tmp);
}
/* Dock MST Hub */
has_dock = fu_dell_detect_dock (data->smi_obj, &dock_location);
if (has_dock) {
if (!fu_dell_toggle_dock_mode (data->smi_obj, enable,
dock_location, error))
g_debug ("unable to change dock to %d", enable);
else
g_debug ("Toggled dock mode to %d", enable);
}
/* System MST hub */
if (has_host) {
if (!fu_dell_toggle_host_mode (data->smi_obj, MST_GPIO_GUID, enable))
g_debug ("Unable to toggle MST hub GPIO to %d", enable);
else
g_debug ("Toggled MST hub GPIO to %d", enable);
}
#if defined (HAVE_SYNAPTICS)
/* set a delay to allow OS response to settling the GPIO change */
if (enable && device == NULL && (has_dock || has_host))
fu_plugin_set_coldplug_delay (plugin, DELL_FLASH_MODE_DELAY * 1000);
#endif
return TRUE;
}
gboolean
fu_plugin_update_prepare (FuPlugin *plugin,
FwupdInstallFlags flags,
FuDevice *device,
GError **error)
{
return fu_dell_toggle_flash (plugin, device, TRUE, error);
}
gboolean
fu_plugin_update_cleanup (FuPlugin *plugin,
FwupdInstallFlags flags,
FuDevice *device,
GError **error)
{
return fu_dell_toggle_flash (plugin, device , FALSE, error);
}
gboolean
fu_plugin_coldplug_prepare (FuPlugin *plugin, GError **error)
{
return fu_dell_toggle_flash (plugin, NULL, TRUE, error);
}
gboolean
fu_plugin_coldplug_cleanup (FuPlugin *plugin, GError **error)
{
return fu_dell_toggle_flash (plugin, NULL, FALSE, error);
}
void
fu_plugin_init (FuPlugin *plugin)
{
@ -834,6 +836,8 @@ fu_plugin_init (FuPlugin *plugin)
data->smi_obj = g_malloc0 (sizeof (FuDellSmiObj));
if (g_getenv ("FWUPD_DELL_VERBOSE") != NULL)
g_setenv ("LIBSMBIOS_C_DEBUG_OUTPUT_ALL", "1", TRUE);
else
g_setenv ("TSS2_LOG", "esys+error,tcti+none", FALSE);
if (fu_dell_supported (plugin))
data->smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS);
data->smi_obj->fake_smbios = FALSE;
@ -914,9 +918,3 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error)
{
return fu_plugin_dell_coldplug (plugin, error);
}
gboolean
fu_plugin_recoldplug (FuPlugin *plugin, GError **error)
{
return fu_plugin_dell_coldplug (plugin, error);
}

View File

@ -68,6 +68,7 @@ fu_plugin_dell_tpm_func (void)
const guint8 fw[30] = { 'F', 'W', 0x00 };
gboolean ret;
struct tpm_status tpm_out;
const gchar *tpm_server_running = g_getenv ("TPM_SERVER_RUNNING");
g_autoptr(FuPlugin) plugin_dell = NULL;
g_autoptr(FuPlugin) plugin_uefi = NULL;
g_autoptr(GBytes) blob_fw = g_bytes_new_static (fw, sizeof(fw));
@ -102,6 +103,12 @@ fu_plugin_dell_tpm_func (void)
g_assert_no_error (error);
g_assert (ret);
if (tpm_server_running == NULL &&
(getuid () != 0 || geteuid () != 0)) {
g_test_skip ("TPM tests require simulated TPM2.0 running or need root access with physical TPM");
return;
}
/* inject fake data (no TPM) */
tpm_out.ret = -2;
fu_plugin_dell_inject_fake_data (plugin_dell,
@ -130,12 +137,12 @@ fu_plugin_dell_tpm_func (void)
g_assert_cmpint (devices->len, ==, 2);
/* make sure 2.0 is locked */
device_v20 = _find_device_by_name (devices, "Unknown TPM 2.0");
device_v20 = _find_device_by_name (devices, "TPM 2.0");
g_assert_nonnull (device_v20);
g_assert_true (fu_device_has_flag (device_v20, FWUPD_DEVICE_FLAG_LOCKED));
/* make sure not allowed to flash 1.2 */
device_v12 = _find_device_by_name (devices, "Unknown TPM 1.2");
device_v12 = _find_device_by_name (devices, "TPM 1.2");
g_assert_nonnull (device_v12);
g_assert_false (fu_device_has_flag (device_v12, FWUPD_DEVICE_FLAG_UPDATABLE));
@ -164,12 +171,12 @@ fu_plugin_dell_tpm_func (void)
g_assert (ret);
/* make sure not allowed to flash 1.2 */
device_v12 = _find_device_by_name (devices, "Unknown TPM 1.2");
device_v12 = _find_device_by_name (devices, "TPM 1.2");
g_assert_nonnull (device_v12);
g_assert_false (fu_device_has_flag (device_v12, FWUPD_DEVICE_FLAG_UPDATABLE));
/* try to unlock 2.0 */
device_v20 = _find_device_by_name (devices, "Unknown TPM 2.0");
device_v20 = _find_device_by_name (devices, "TPM 2.0");
g_assert_nonnull (device_v20);
ret = fu_plugin_runner_unlock (plugin_uefi, device_v20, &error);
g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
@ -195,10 +202,10 @@ fu_plugin_dell_tpm_func (void)
g_assert (ret);
/* make sure allowed to flash 1.2 but not 2.0 */
device_v12 = _find_device_by_name (devices, "Unknown TPM 1.2");
device_v12 = _find_device_by_name (devices, "TPM 1.2");
g_assert_nonnull (device_v12);
g_assert_true (fu_device_has_flag (device_v12, FWUPD_DEVICE_FLAG_UPDATABLE));
device_v20 = _find_device_by_name (devices, "Unknown TPM 2.0");
device_v20 = _find_device_by_name (devices, "TPM 2.0");
g_assert_nonnull (device_v20);
g_assert_false (fu_device_has_flag (device_v20, FWUPD_DEVICE_FLAG_UPDATABLE));
@ -230,10 +237,10 @@ fu_plugin_dell_tpm_func (void)
g_assert (ret);
/* make sure allowed to flash 2.0 but not 1.2 */
device_v20 = _find_device_by_name (devices, "Unknown TPM 2.0");
device_v20 = _find_device_by_name (devices, "TPM 2.0");
g_assert_nonnull (device_v20);
g_assert_true (fu_device_has_flag (device_v20, FWUPD_DEVICE_FLAG_UPDATABLE));
device_v12 = _find_device_by_name (devices, "Unknown TPM 1.2");
device_v12 = _find_device_by_name (devices, "TPM 1.2");
g_assert_nonnull (device_v12);
g_assert_false (fu_device_has_flag (device_v12, FWUPD_DEVICE_FLAG_UPDATABLE));

View File

@ -27,6 +27,7 @@ shared_module('fu_plugin_dell',
plugin_deps,
efivar,
libsmbios_c,
tpm2tss,
],
)
@ -54,6 +55,7 @@ if get_option('tests')
sqlite,
libsmbios_c,
valgrind,
tpm2tss,
],
link_with : [
libfwupdprivate,

View File

@ -55,7 +55,10 @@ dfu_tool_parse_xtea_key (const gchar *key, guint32 *keys, GError **error)
guint64 tmp;
/* copy to 4-char buf (with NUL) */
memcpy (buf, key + i*8, 8);
if (!fu_memcpy_safe ((guint8 *) buf, sizeof(buf), 0x0, /* dst */
(const guint8 *) key, key_len, i * 8, /* src */
8, error))
return FALSE;
tmp = g_ascii_strtoull (buf, &endptr, 16);
if (endptr && endptr[0] != '\0') {
g_set_error (error,

View File

@ -176,157 +176,3 @@ dfu_utils_bytes_join_array (GPtrArray *chunks)
}
return g_bytes_new_take (buffer, total_size);
}
/**
* dfu_utils_bytes_pad:
* @bytes: a #GBytes
* @sz: the desired size in bytes
*
* Pads a GBytes to a given @sz with `0xff`.
*
* Return value: (transfer full): a #GBytes
**/
GBytes *
dfu_utils_bytes_pad (GBytes *bytes, gsize sz)
{
gsize bytes_sz;
g_return_val_if_fail (g_bytes_get_size (bytes) <= sz, NULL);
/* pad */
bytes_sz = g_bytes_get_size (bytes);
if (bytes_sz < sz) {
const guint8 *data = g_bytes_get_data (bytes, NULL);
guint8 *data_new = g_malloc (sz);
memcpy (data_new, data, bytes_sz);
memset (data_new + bytes_sz, 0xff, sz - bytes_sz);
return g_bytes_new_take (data_new, sz);
}
/* exactly right */
return g_bytes_ref (bytes);
}
/**
* dfu_utils_buffer_parse_uint4:
* @data: a string
*
* Parses a base 16 number from a string.
*
* The string MUST be at least 1 byte long as this function cannot check the
* length of @data. Checking the size must be done in the caller.
*
* Return value: A parsed value, or 0 for error
**/
guint8
dfu_utils_buffer_parse_uint4 (const gchar *data)
{
gchar buffer[2];
memcpy (buffer, data, 1);
buffer[1] = '\0';
return (guint8) g_ascii_strtoull (buffer, NULL, 16);
}
/**
* dfu_utils_buffer_parse_uint8:
* @data: a string
*
* Parses a base 16 number from a string.
*
* The string MUST be at least 2 bytes long as this function cannot check the
* length of @data. Checking the size must be done in the caller.
*
* Return value: A parsed value, or 0 for error
**/
guint8
dfu_utils_buffer_parse_uint8 (const gchar *data)
{
gchar buffer[3];
memcpy (buffer, data, 2);
buffer[2] = '\0';
return (guint8) g_ascii_strtoull (buffer, NULL, 16);
}
/**
* dfu_utils_buffer_parse_uint16:
* @data: a string
*
* Parses a base 16 number from a string.
*
* The string MUST be at least 4 bytes long as this function cannot check the
* length of @data. Checking the size must be done in the caller.
*
* Return value: A parsed value, or 0 for error
**/
guint16
dfu_utils_buffer_parse_uint16 (const gchar *data)
{
gchar buffer[5];
memcpy (buffer, data, 4);
buffer[4] = '\0';
return (guint16) g_ascii_strtoull (buffer, NULL, 16);
}
/**
* dfu_utils_buffer_parse_uint24:
* @data: a string
*
* Parses a base 16 number from a string.
*
* The string MUST be at least 6 bytes long as this function cannot check the
* length of @data. Checking the size must be done in the caller.
*
* Return value: A parsed value, or 0 for error
**/
guint32
dfu_utils_buffer_parse_uint24 (const gchar *data)
{
gchar buffer[7];
memcpy (buffer, data, 6);
buffer[6] = '\0';
return (guint32) g_ascii_strtoull (buffer, NULL, 16);
}
/**
* dfu_utils_buffer_parse_uint32:
* @data: a string
*
* Parses a base 16 number from a string.
*
* The string MUST be at least 8 bytes long as this function cannot check the
* length of @data. Checking the size must be done in the caller.
*
* Return value: A parsed value, or 0 for error
**/
guint32
dfu_utils_buffer_parse_uint32 (const gchar *data)
{
gchar buffer[9];
memcpy (buffer, data, 8);
buffer[8] = '\0';
return (guint32) g_ascii_strtoull (buffer, NULL, 16);
}
/**
* dfu_utils_strnsplit:
* @str: a string to split
* @sz: size of @str
* @delimiter: a string which specifies the places at which to split the string
* @max_tokens: the maximum number of pieces to split @str into
*
* Splits a string into a maximum of @max_tokens pieces, using the given
* delimiter. If @max_tokens is reached, the remainder of string is appended
* to the last token.
*
* Return value: a newly-allocated NULL-terminated array of strings
**/
gchar **
dfu_utils_strnsplit (const gchar *str, gsize sz,
const gchar *delimiter, gint max_tokens)
{
if (str[sz - 1] != '\0') {
g_autofree gchar *str2 = g_strndup (str, sz);
return g_strsplit (str2, delimiter, max_tokens);
}
return g_strsplit (str, delimiter, max_tokens);
}

View File

@ -156,16 +156,5 @@ const gchar *dfu_version_to_string (DfuVersion version);
/* helpers */
GBytes *dfu_utils_bytes_join_array (GPtrArray *chunks);
GBytes *dfu_utils_bytes_pad (GBytes *bytes,
gsize sz);
guint8 dfu_utils_buffer_parse_uint4 (const gchar *data);
guint8 dfu_utils_buffer_parse_uint8 (const gchar *data);
guint16 dfu_utils_buffer_parse_uint16 (const gchar *data);
guint32 dfu_utils_buffer_parse_uint24 (const gchar *data);
guint32 dfu_utils_buffer_parse_uint32 (const gchar *data);
gchar **dfu_utils_strnsplit (const gchar *str,
gsize sz,
const gchar *delimiter,
gint max_tokens);
G_END_DECLS

View File

@ -86,6 +86,7 @@
#include "dfu-target-stm.h"
#include "fu-device-locker.h"
#include "fu-firmware-common.h"
#include "fwupd-error.h"
@ -1120,8 +1121,8 @@ dfu_device_detach (DfuDevice *device, GError **error)
g_autoptr(GError) error_jabra = NULL;
/* parse string and create magic packet */
rep = dfu_utils_buffer_parse_uint8 (priv->jabra_detach + 0);
adr = dfu_utils_buffer_parse_uint8 (priv->jabra_detach + 2);
rep = fu_firmware_strparse_uint8 (priv->jabra_detach + 0);
adr = fu_firmware_strparse_uint8 (priv->jabra_detach + 2);
buf[0] = rep;
buf[1] = adr;
buf[2] = 0x00;
@ -2052,7 +2053,7 @@ dfu_device_set_quirk_kv (FuDevice *device,
}
if (g_strcmp0 (key, FU_QUIRKS_DFU_FORCE_VERSION) == 0) {
if (value != NULL && strlen (value) == 4) {
priv->force_version = dfu_utils_buffer_parse_uint16 (value);
priv->force_version = fu_firmware_strparse_uint16 (value);
return TRUE;
}
g_set_error_literal (error,

View File

@ -239,60 +239,3 @@ dfu_element_set_target_size (DfuElement *element, guint32 target_size)
g_bytes_unref (priv->contents);
priv->contents = g_bytes_new_take (buf, target_size);
}
/**
* dfu_element_get_contents_chunk:
* @element: a #DfuElement
* @address: an address greater than dfu_element_get_address()
* @chunk_sz_max: the size of the new chunk
* @error: a #GError, or %NULL
*
* Gets a block of data from the @element. If the contents of the element is
* smaller than the requested chunk size then the #GBytes will be smaller
* than @chunk_sz_max. Use dfu_utils_bytes_pad() if padding is required.
*
* If the @address is larger than the size of the @element then an error is returned.
*
* Return value: (transfer full): a #GBytes, or %NULL
**/
GBytes *
dfu_element_get_contents_chunk (DfuElement *element,
guint32 address,
guint32 chunk_sz_max,
GError **error)
{
GBytes *blob;
gsize chunk_left;
guint32 offset;
/* check address requested is larger than base address */
if (address < dfu_element_get_address (element)) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"requested address 0x%x less than base address 0x%x",
(guint) address, (guint) dfu_element_get_address (element));
return NULL;
}
/* offset into data */
offset = address - dfu_element_get_address (element);
blob = dfu_element_get_contents (element);
if (offset > g_bytes_get_size (blob)) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_FOUND,
"offset 0x%x larger than data size 0x%x",
(guint) offset,
(guint) g_bytes_get_size (blob));
return NULL;
}
/* if we have less data than requested */
chunk_left = g_bytes_get_size (blob) - offset;
if (chunk_sz_max > chunk_left)
return g_bytes_new_from_bytes (blob, offset, chunk_left);
/* check chunk */
return g_bytes_new_from_bytes (blob, offset, chunk_sz_max);
}

View File

@ -23,11 +23,6 @@ DfuElement *dfu_element_new (void);
GBytes *dfu_element_get_contents (DfuElement *element);
guint32 dfu_element_get_address (DfuElement *element);
GBytes *dfu_element_get_contents_chunk (DfuElement *element,
guint32 address,
guint32 chunk_sz_max,
GError **error);
void dfu_element_set_contents (DfuElement *element,
GBytes *contents);
void dfu_element_set_address (DfuElement *element,

View File

@ -8,6 +8,8 @@
#include <string.h>
#include "fu-common.h"
#include "dfu-element.h"
#include "dfu-format-dfuse.h"
#include "dfu-image.h"
@ -232,7 +234,13 @@ dfu_image_to_dfuse (DfuImage *image)
gsize length;
GBytes *bytes = g_ptr_array_index (element_array, i);
const guint8 *data = g_bytes_get_data (bytes, &length);
memcpy (buf + offset, data, length);
g_autoptr(GError) error = NULL;
if (!fu_memcpy_safe (buf, length_total + sizeof (DfuSeImagePrefix), offset, /* dst */
data, length, 0x0, /* src */
length, &error)) {
g_critical ("failed to pack buffer: %s", error->message);
continue;
}
offset += (guint32) length;
}
return g_bytes_new_take (buf, length_total + sizeof (DfuSeImagePrefix));
@ -300,7 +308,10 @@ dfu_firmware_to_dfuse (DfuFirmware *firmware, GError **error)
gsize length;
const guint8 *data;
data = g_bytes_get_data (contents, &length);
memcpy (buf + offset, data, length);
if (!fu_memcpy_safe (buf, sizeof (DfuSePrefix) + image_size_total, offset, /* dst */
data, length, 0x0, /* src */
length, error))
return NULL;
offset += (guint32) length;
}

View File

@ -15,6 +15,9 @@
#include "dfu-format-ihex.h"
#include "dfu-image.h"
#include "fu-firmware-common.h"
#include "fu-ihex-firmware.h"
#include "fwupd-error.h"
/**
@ -46,34 +49,6 @@ dfu_firmware_detect_ihex (GBytes *bytes)
return DFU_FIRMWARE_FORMAT_UNKNOWN;
}
#define DFU_INHX32_RECORD_TYPE_DATA 0x00
#define DFU_INHX32_RECORD_TYPE_EOF 0x01
#define DFU_INHX32_RECORD_TYPE_EXTENDED_SEGMENT 0x02
#define DFU_INHX32_RECORD_TYPE_START_SEGMENT 0x03
#define DFU_INHX32_RECORD_TYPE_EXTENDED_LINEAR 0x04
#define DFU_INHX32_RECORD_TYPE_START_LINEAR 0x05
#define DFU_INHX32_RECORD_TYPE_SIGNATURE 0xfd
static const gchar *
dfu_firmware_ihex_record_type_to_string (guint8 record_type)
{
if (record_type == DFU_INHX32_RECORD_TYPE_DATA)
return "DATA";
if (record_type == DFU_INHX32_RECORD_TYPE_EOF)
return "EOF";
if (record_type == DFU_INHX32_RECORD_TYPE_EXTENDED_SEGMENT)
return "EXTENDED_SEGMENT";
if (record_type == DFU_INHX32_RECORD_TYPE_START_SEGMENT)
return "START_SEGMENT";
if (record_type == DFU_INHX32_RECORD_TYPE_EXTENDED_LINEAR)
return "EXTENDED_LINEAR";
if (record_type == DFU_INHX32_RECORD_TYPE_START_LINEAR)
return "ADDR32";
if (record_type == DFU_INHX32_RECORD_TYPE_SIGNATURE)
return "SIGNATURE";
return NULL;
}
/**
* dfu_firmware_from_ihex: (skip)
* @firmware: a #DfuFirmware
@ -91,315 +66,28 @@ dfu_firmware_from_ihex (DfuFirmware *firmware,
DfuFirmwareParseFlags flags,
GError **error)
{
const gchar *data;
gboolean got_eof = FALSE;
gsize sz = 0;
guint32 abs_addr = 0x0;
guint32 addr_last = 0x0;
guint32 base_addr = G_MAXUINT32;
guint32 seg_addr = 0x0;
g_auto(GStrv) lines = NULL;
g_autoptr(DfuElement) element = NULL;
g_autoptr(DfuImage) image = NULL;
g_autoptr(GBytes) contents = NULL;
g_autoptr(GString) buf = g_string_new (NULL);
g_autoptr(GString) buf_signature = g_string_new (NULL);
g_autoptr(FuFirmware) firmware_new = fu_ihex_firmware_new ();
g_autoptr(GPtrArray) imgs = NULL;
FwupdInstallFlags flags_new = FWUPD_INSTALL_FLAG_NONE;
g_return_val_if_fail (bytes != NULL, FALSE);
/* create element */
image = dfu_image_new ();
dfu_image_set_name (image, "ihex");
element = dfu_element_new ();
/* parse records */
data = g_bytes_get_data (bytes, &sz);
lines = dfu_utils_strnsplit (data, sz, "\n", -1);
for (guint ln = 0; lines[ln] != NULL; ln++) {
const gchar *line = lines[ln];
gsize linesz;
guint32 addr;
guint8 byte_cnt;
guint8 record_type;
guint line_end;
/* ignore comments */
if (g_str_has_prefix (line, ";"))
continue;
/* ignore blank lines */
g_strdelimit (lines[ln], "\r\x1a", '\0');
linesz = strlen (line);
if (linesz == 0)
continue;
/* check starting token */
if (line[0] != ':') {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid starting token on line %u: %s",
ln + 1, line);
return FALSE;
}
/* check there's enough data for the smallest possible record */
if (linesz < 11) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"line %u is incomplete, length %u",
ln + 1, (guint) linesz);
return FALSE;
}
/* length, 16-bit address, type */
byte_cnt = dfu_utils_buffer_parse_uint8 (line + 1);
addr = dfu_utils_buffer_parse_uint16 (line + 3);
record_type = dfu_utils_buffer_parse_uint8 (line + 7);
g_debug ("%s:", dfu_firmware_ihex_record_type_to_string (record_type));
g_debug (" addr_start:\t0x%04x", addr);
g_debug (" length:\t0x%02x", byte_cnt);
addr += seg_addr;
addr += abs_addr;
g_debug (" addr:\t0x%08x", addr);
/* position of checksum */
line_end = 9 + byte_cnt * 2;
if (line_end > (guint) linesz) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"line %u malformed, length: %u",
ln + 1, line_end);
return FALSE;
}
/* verify checksum */
if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
guint8 checksum = 0;
for (guint i = 1; i < line_end + 2; i += 2) {
guint8 data_tmp = dfu_utils_buffer_parse_uint8 (line + i);
checksum += data_tmp;
}
if (checksum != 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"line %u has invalid checksum (0x%02x)",
ln + 1, checksum);
return FALSE;
}
}
/* process different record types */
switch (record_type) {
case DFU_INHX32_RECORD_TYPE_DATA:
/* base address for element */
if (base_addr == G_MAXUINT32)
base_addr = addr;
/* does not make sense */
if (addr < addr_last) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid address 0x%x, last was 0x%x",
(guint) addr,
(guint) addr_last);
return FALSE;
}
/* parse bytes from line */
g_debug ("writing data 0x%08x", (guint32) addr);
for (guint i = 9; i < line_end; i += 2) {
/* any holes in the hex record */
guint32 len_hole = addr - addr_last;
guint8 data_tmp;
if (addr_last > 0 && len_hole > 0x100000) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"hole of 0x%x bytes too large to fill",
(guint) len_hole);
return FALSE;
}
if (addr_last > 0x0 && len_hole > 1) {
g_debug ("filling address 0x%08x to 0x%08x",
addr_last + 1, addr_last + len_hole - 1);
for (guint j = 1; j < len_hole; j++) {
/* although 0xff might be clearer,
* we can't write 0xffff to pic14 */
g_string_append_c (buf, 0x00);
}
}
/* write into buf */
data_tmp = dfu_utils_buffer_parse_uint8 (line + i);
g_string_append_c (buf, (gchar) data_tmp);
addr_last = addr++;
}
break;
case DFU_INHX32_RECORD_TYPE_EOF:
if (got_eof) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"duplicate EOF, perhaps "
"corrupt file");
return FALSE;
}
got_eof = TRUE;
break;
case DFU_INHX32_RECORD_TYPE_EXTENDED_LINEAR:
abs_addr = dfu_utils_buffer_parse_uint16 (line + 9) << 16;
g_debug (" abs_addr:\t0x%02x", abs_addr);
break;
case DFU_INHX32_RECORD_TYPE_START_LINEAR:
abs_addr = dfu_utils_buffer_parse_uint32 (line + 9);
g_debug (" abs_addr:\t0x%08x", abs_addr);
break;
case DFU_INHX32_RECORD_TYPE_EXTENDED_SEGMENT:
/* segment base address, so ~1Mb addressable */
seg_addr = dfu_utils_buffer_parse_uint16 (line + 9) * 16;
g_debug (" seg_addr:\t0x%08x", seg_addr);
break;
case DFU_INHX32_RECORD_TYPE_START_SEGMENT:
/* initial content of the CS:IP registers */
seg_addr = dfu_utils_buffer_parse_uint32 (line + 9);
g_debug (" seg_addr:\t0x%02x", seg_addr);
break;
case DFU_INHX32_RECORD_TYPE_SIGNATURE:
for (guint i = 9; i < line_end; i += 2) {
guint8 tmp_c = dfu_utils_buffer_parse_uint8 (line + i);
g_string_append_c (buf_signature, tmp_c);
}
break;
default:
/* vendors sneak in nonstandard sections past the EOF */
if (got_eof)
break;
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid ihex record type %i",
record_type);
return FALSE;
}
}
/* no EOF */
if (!got_eof) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"no EOF, perhaps truncated file");
/* make a native objects from the abstract firmware */
if (flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST)
flags_new |= FWUPD_INSTALL_FLAG_FORCE;
if (!fu_firmware_parse (firmware_new, bytes, flags_new, error))
return FALSE;
}
imgs = fu_firmware_get_images (firmware_new);
for (guint i = 0; i < imgs->len; i++) {
FuFirmwareImage *img = g_ptr_array_index (imgs, i);
g_autoptr(DfuElement) element = dfu_element_new ();
g_autoptr(DfuImage) image = dfu_image_new ();
dfu_element_set_contents (element, fu_firmware_image_get_bytes (img, NULL));
dfu_element_set_address (element, fu_firmware_image_get_addr (img));
dfu_image_add_element (image, element);
dfu_image_set_name (image, "ihex");
dfu_firmware_add_image (firmware, image);
/* add single image */
contents = g_bytes_new (buf->str, buf->len);
dfu_element_set_contents (element, contents);
if (base_addr != G_MAXUINT32)
dfu_element_set_address (element, base_addr);
dfu_image_add_element (image, element);
dfu_firmware_add_image (firmware, image);
}
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
/* add optional signature */
if (buf_signature->len > 0) {
g_autoptr(DfuElement) element_sig = dfu_element_new ();
g_autoptr(DfuImage) image_sig = dfu_image_new ();
g_autoptr(GBytes) data_sig = g_bytes_new_static (buf_signature->str, buf_signature->len);
dfu_element_set_contents (element_sig, data_sig);
dfu_image_add_element (image_sig, element_sig);
dfu_image_set_name (image_sig, "signature");
dfu_firmware_add_image (firmware, image_sig);
}
return TRUE;
}
static void
dfu_firmware_ihex_emit_chunk (GString *str,
guint16 address,
guint8 record_type,
const guint8 *data,
gsize sz)
{
guint8 checksum = 0x00;
g_string_append_printf (str, ":%02X%04X%02X",
(guint) sz,
(guint) address,
(guint) record_type);
for (gsize j = 0; j < sz; j++)
g_string_append_printf (str, "%02X", data[j]);
checksum = (guint8) sz;
checksum += (guint8) ((address & 0xff00) >> 8);
checksum += (guint8) (address & 0xff);
checksum += record_type;
for (gsize j = 0; j < sz; j++)
checksum += data[j];
g_string_append_printf (str, "%02X\n", (guint) (((~checksum) + 0x01) & 0xff));
}
static void
dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type,
guint32 address, GBytes *contents)
{
const guint8 *data;
const guint chunk_size = 16;
gsize len;
guint32 address_offset_last = 0x0;
/* get number of chunks */
data = g_bytes_get_data (contents, &len);
for (gsize i = 0; i < len; i += chunk_size) {
guint32 address_tmp = address + i;
guint32 address_offset = (address_tmp >> 16) & 0xffff;
gsize chunk_len = MIN (len - i, 16);
/* need to offset */
if (address_offset != address_offset_last) {
guint8 buf[2];
fu_common_write_uint16 (buf, address_offset, G_BIG_ENDIAN);
dfu_firmware_ihex_emit_chunk (str, 0x0,
DFU_INHX32_RECORD_TYPE_EXTENDED_LINEAR,
buf, 2);
address_offset_last = address_offset;
}
address_tmp &= 0xffff;
dfu_firmware_ihex_emit_chunk (str, address_tmp,
record_type, data + i, chunk_len);
}
}
static gboolean
dfu_firmware_to_ihex_element (DfuElement *element, GString *str,
guint8 record_type, GError **error)
{
GBytes *contents = dfu_element_get_contents (element);
dfu_firmware_to_ihex_bytes (str, record_type,
dfu_element_get_address (element),
contents);
return TRUE;
}
static gboolean
dfu_firmware_to_ihex_image (DfuImage *image, GString *str, GError **error)
{
GPtrArray *elements;
guint8 record_type = DFU_INHX32_RECORD_TYPE_DATA;
if (g_strcmp0 (dfu_image_get_name (image), "signature") == 0)
record_type = DFU_INHX32_RECORD_TYPE_SIGNATURE;
elements = dfu_image_get_elements (image);
for (guint i = 0; i < elements->len; i++) {
DfuElement *element = g_ptr_array_index (elements, i);
if (!dfu_firmware_to_ihex_element (element,
str,
record_type,
error))
return FALSE;
}
return TRUE;
}
@ -416,18 +104,21 @@ GBytes *
dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error)
{
GPtrArray *images;
g_autoptr(GString) str = NULL;
g_autoptr(FuFirmware) firmware_new = fu_ihex_firmware_new ();
/* write all the element data */
str = g_string_new ("");
/* make a new object from the native firmware */
images = dfu_firmware_get_images (firmware);
for (guint i = 0; i < images->len; i++) {
DfuImage *image = g_ptr_array_index (images, i);
if (!dfu_firmware_to_ihex_image (image, str, error))
return NULL;
GPtrArray *elements = dfu_image_get_elements (image);
for (guint j = 0; j < elements->len; j++) {
DfuElement *element = g_ptr_array_index (elements, j);
g_autoptr(FuFirmwareImage) img = NULL;
img = fu_firmware_image_new (dfu_element_get_contents (element));
fu_firmware_image_set_id (img, dfu_image_get_name (image));
fu_firmware_image_set_addr (img, dfu_element_get_address (element));
fu_firmware_add_image (firmware_new, img);
}
}
/* add EOF */
dfu_firmware_ihex_emit_chunk (str, 0x0, DFU_INHX32_RECORD_TYPE_EOF, NULL, 0);
return g_bytes_new (str->str, str->len);
return fu_firmware_write (firmware_new, error);
}

View File

@ -8,6 +8,8 @@
#include <string.h>
#include "fu-common.h"
#include "dfu-element.h"
#include "dfu-format-metadata.h"
#include "dfu-image.h"
@ -188,12 +190,18 @@ dfu_firmware_to_metadata (DfuFirmware *firmware, GError **error)
/* write the key */
mdbuf[idx++] = (guint8) key_len;
memcpy(mdbuf + idx, key, key_len);
if (!fu_memcpy_safe (mdbuf, sizeof(mdbuf), idx, /* dst */
(const guint8 *) key, key_len, 0x0, /* src */
key_len, error))
return NULL;
idx += key_len;
/* write the value */
mdbuf[idx++] = (guint8) value_len;
memcpy(mdbuf + idx, value, value_len);
if (!fu_memcpy_safe (mdbuf, sizeof(mdbuf), idx, /* dst */
(const guint8 *) value, value_len, 0x0, /* src */
value_len, error))
return NULL;
idx += value_len;
}
g_debug ("metadata table was %u/%" G_GSIZE_FORMAT " bytes",

View File

@ -10,11 +10,13 @@
#include "fu-common.h"
#include "dfu-element.h"
#include "dfu-firmware.h"
#include "dfu-format-srec.h"
#include "dfu-image.h"
#include "fu-firmware-common.h"
#include "fu-srec-firmware.h"
#include "fwupd-error.h"
/**
@ -38,282 +40,6 @@ dfu_firmware_detect_srec (GBytes *bytes)
return DFU_FIRMWARE_FORMAT_SREC;
}
/**
* dfu_firmware_from_srec: (skip)
* @firmware: a #DfuFirmware
* @bytes: data to parse
* @flags: some #DfuFirmwareParseFlags
* @error: a #GError, or %NULL
*
* Unpacks into a firmware object from raw data.
*
* Returns: %TRUE for success
**/
gboolean
dfu_image_from_srec (DfuImage *image,
GBytes *bytes,
guint32 start_addr,
DfuFirmwareParseFlags flags,
GError **error)
{
const gchar *data;
gboolean got_eof = FALSE;
gboolean got_hdr = FALSE;
gsize sz = 0;
guint16 data_cnt = 0;
guint32 addr32_last = 0;
guint32 element_address = 0;
g_auto(GStrv) lines = NULL;
g_autoptr(DfuElement) element = dfu_element_new ();
g_autoptr(GBytes) contents = NULL;
g_autoptr(GString) outbuf = g_string_new (NULL);
g_return_val_if_fail (bytes != NULL, FALSE);
/* parse records */
data = g_bytes_get_data (bytes, &sz);
lines = dfu_utils_strnsplit (data, sz, "\n", -1);
for (guint ln = 0; lines[ln] != NULL; ln++) {
const gchar *line = lines[ln];
gsize linesz;
guint32 rec_addr32;
guint8 addrsz = 0; /* bytes */
guint8 rec_count; /* words */
guint8 rec_kind;
/* ignore blank lines */
g_strdelimit (lines[ln], "\r", '\0');
linesz = strlen (line);
if (linesz == 0)
continue;
/* check starting token */
if (line[0] != 'S') {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid starting token, got '%c' at line %u",
line[0], ln);
return FALSE;
}
/* check there's enough data for the smallest possible record */
if (linesz < 10) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"record incomplete at line %u, length %u",
ln, (guint) linesz);
return FALSE;
}
/* kind, count, address, (data), checksum, linefeed */
rec_kind = line[1] - '0';
rec_count = dfu_utils_buffer_parse_uint8 (line + 2);
if (rec_count * 2 != linesz - 4) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"count incomplete at line %u, "
"length %u, expected %u",
ln, (guint) linesz - 4, (guint) rec_count * 2);
return FALSE;
}
/* checksum check */
if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
guint8 rec_csum = 0;
guint8 rec_csum_expected;
for (guint8 i = 0; i < rec_count; i++)
rec_csum += dfu_utils_buffer_parse_uint8 (line + (i * 2) + 2);
rec_csum ^= 0xff;
rec_csum_expected = dfu_utils_buffer_parse_uint8 (line + (rec_count * 2) + 2);
if (rec_csum != rec_csum_expected) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"checksum incorrect line %u, "
"expected %02x, got %02x",
ln, rec_csum_expected, rec_csum);
return FALSE;
}
}
/* set each command settings */
switch (rec_kind) {
case 0:
addrsz = 2;
if (got_hdr) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"duplicate header record");
return FALSE;
}
got_hdr = TRUE;
break;
case 1:
addrsz = 2;
break;
case 2:
addrsz = 3;
break;
case 3:
addrsz = 4;
break;
case 5:
addrsz = 2;
got_eof = TRUE;
break;
case 6:
addrsz = 3;
break;
case 7:
addrsz = 4;
got_eof = TRUE;
break;
case 8:
addrsz = 3;
got_eof = TRUE;
break;
case 9:
addrsz = 2;
got_eof = TRUE;
break;
default:
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid srec record type S%c",
line[1]);
return FALSE;
}
/* parse address */
switch (addrsz) {
case 2:
rec_addr32 = dfu_utils_buffer_parse_uint16 (line + 4);
break;
case 3:
rec_addr32 = dfu_utils_buffer_parse_uint24 (line + 4);
break;
case 4:
rec_addr32 = dfu_utils_buffer_parse_uint32 (line + 4);
break;
default:
g_assert_not_reached ();
}
/* header */
if (rec_kind == 0) {
g_autoptr(GString) modname = g_string_new (NULL);
if (rec_addr32 != 0x0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid header record address, got %04x",
rec_addr32);
return FALSE;
}
/* could be anything, lets assume text */
for (guint8 i = 4 + (addrsz * 2); i <= rec_count * 2; i += 2) {
guint8 tmp = dfu_utils_buffer_parse_uint8 (line + i);
if (!g_ascii_isgraph (tmp))
break;
g_string_append_c (modname, tmp);
}
if (modname->len != 0)
dfu_image_set_name (image, modname->str);
continue;
}
/* verify we got all records */
if (rec_kind == 5) {
if (rec_addr32 != data_cnt) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"count record was not valid, got 0x%02x expected 0x%02x",
(guint) rec_addr32, (guint) data_cnt);
return FALSE;
}
}
/* data */
if (rec_kind == 1 || rec_kind == 2 || rec_kind == 3) {
/* invalid */
if (!got_hdr) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"missing header record");
return FALSE;
}
/* does not make sense */
if (rec_addr32 < addr32_last) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"invalid address 0x%x, last was 0x%x",
(guint) rec_addr32,
(guint) addr32_last);
return FALSE;
}
if (rec_addr32 < start_addr) {
g_debug ("ignoring data at 0x%x as before start address 0x%x",
(guint) rec_addr32, (guint) start_addr);
} else {
guint bytecnt = 0;
guint32 len_hole = rec_addr32 - addr32_last;
/* fill any holes, but only up to 1Mb to avoid a DoS */
if (addr32_last > 0 && len_hole > 0x100000) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"hole of 0x%x bytes too large to fill",
(guint) len_hole);
return FALSE;
}
if (addr32_last > 0x0 && len_hole > 1) {
g_debug ("filling address 0x%08x to 0x%08x",
addr32_last + 1, addr32_last + len_hole - 1);
for (guint j = 0; j < len_hole; j++)
g_string_append_c (outbuf, 0xff);
}
/* add data */
for (guint8 i = 4 + (addrsz * 2); i <= rec_count * 2; i += 2) {
guint8 tmp = dfu_utils_buffer_parse_uint8 (line + i);
g_string_append_c (outbuf, tmp);
bytecnt++;
}
if (element_address == 0x0)
element_address = rec_addr32;
addr32_last = rec_addr32 + bytecnt;
}
data_cnt++;
}
}
/* no EOF */
if (!got_eof) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"no EOF, perhaps truncated file");
return FALSE;
}
/* add single image */
contents = g_bytes_new (outbuf->str, outbuf->len);
dfu_element_set_contents (element, contents);
dfu_element_set_address (element, element_address);
dfu_image_add_element (image, element);
return TRUE;
}
/**
* dfu_firmware_from_srec: (skip)
* @firmware: a #DfuFirmware
@ -331,15 +57,26 @@ dfu_firmware_from_srec (DfuFirmware *firmware,
DfuFirmwareParseFlags flags,
GError **error)
{
g_autoptr(DfuImage) image = NULL;
g_autoptr(FuFirmware) firmware_new = fu_srec_firmware_new ();
g_autoptr(GPtrArray) imgs = NULL;
FwupdInstallFlags flags_new = FWUPD_INSTALL_FLAG_NONE;
g_return_val_if_fail (bytes != NULL, FALSE);
/* add single image */
image = dfu_image_new ();
if (!dfu_image_from_srec (image, bytes, 0x0, flags, error))
/* make a native objects from the abstract firmware */
if (flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST)
flags_new |= FWUPD_INSTALL_FLAG_FORCE;
if (!fu_firmware_parse (firmware_new, bytes, flags_new, error))
return FALSE;
dfu_firmware_add_image (firmware, image);
imgs = fu_firmware_get_images (firmware_new);
for (guint i = 0; i < imgs->len; i++) {
FuFirmwareImage *img = g_ptr_array_index (imgs, i);
g_autoptr(DfuElement) element = dfu_element_new ();
g_autoptr(DfuImage) image = dfu_image_new ();
dfu_element_set_contents (element, fu_firmware_image_get_bytes (img, NULL));
dfu_element_set_address (element, fu_firmware_image_get_addr (img));
dfu_image_add_element (image, element);
dfu_firmware_add_image (firmware, image);
}
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_SREC);
return TRUE;
}

View File

@ -20,10 +20,5 @@ gboolean dfu_firmware_from_srec (DfuFirmware *firmware,
GBytes *bytes,
DfuFirmwareParseFlags flags,
GError **error);
gboolean dfu_image_from_srec (DfuImage *image,
GBytes *bytes,
guint32 start_addr,
DfuFirmwareParseFlags flags,
GError **error);
G_END_DECLS

View File

@ -23,6 +23,8 @@
#include <string.h>
#include <stdio.h>
#include "fu-common.h"
#include "dfu-common.h"
#include "dfu-patch.h"
@ -137,14 +139,18 @@ dfu_patch_export (DfuPatch *self, GError **error)
if (priv->checksum_old != NULL) {
gsize csum_sz = 0;
const guint8 *csum_data = g_bytes_get_data (priv->checksum_old, &csum_sz);
memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old),
csum_data, csum_sz);
if (!fu_memcpy_safe (data, sz, G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old), /* dst */
csum_data, csum_sz, 0x0, /* src */
csum_sz, error))
return NULL;
}
if (priv->checksum_new != NULL) {
gsize csum_sz = 0;
const guint8 *csum_data = g_bytes_get_data (priv->checksum_new, &csum_sz);
memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new),
csum_data, csum_sz);
if (!fu_memcpy_safe (data, sz, G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new), /* dst */
csum_data, csum_sz, 0x0, /* src */
csum_sz, error))
return NULL;
}
addr = sizeof(DfuPatchFileHeader);
@ -158,9 +164,15 @@ dfu_patch_export (DfuPatch *self, GError **error)
chunkhdr.off = GUINT32_TO_LE (chunk->off);
chunkhdr.sz = GUINT32_TO_LE (sz_tmp);
chunkhdr.flags = 0;
memcpy (data + addr, &chunkhdr, sizeof(DfuPatchChunkHeader));
memcpy (data + addr + sizeof(DfuPatchChunkHeader), data_new, sz_tmp);
if (!fu_memcpy_safe (data, sz, addr, /* dst */
(const guint8 *) &chunkhdr, sizeof(DfuPatchChunkHeader), 0x0, /* src */
sizeof(DfuPatchChunkHeader), error))
return NULL;
if (!fu_memcpy_safe (data, sz, addr + sizeof(DfuPatchChunkHeader), /* dst */
data_new, sz_tmp, 0x0, /* src */
sz_tmp, error))
return NULL;
/* move up after the copied data */
addr += sizeof(DfuPatchChunkHeader) + sz_tmp;
}
@ -506,7 +518,10 @@ dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError
}
data_new = g_malloc0 (sz_max);
memcpy (data_new, data_old, MIN (sz, sz_max));
if (!fu_memcpy_safe (data_new, sz_max, 0x0, /* dst */
data_old, sz, 0x0, /* src */
MIN (sz, sz_max), error))
return NULL;
for (guint i = 0; i < priv->chunks->len; i++) {
DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
const guint8 *chunk_data;
@ -525,7 +540,10 @@ dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError
/* apply one chunk */
g_debug ("applying chunk %u/%u @0x%04x (length %" G_GSIZE_FORMAT ")",
i + 1, priv->chunks->len, chunk->off, chunk_sz);
memcpy (data_new + chunk->off, chunk_data, chunk_sz);
if (!fu_memcpy_safe (data_new, sz_max, chunk->off, /* dst */
chunk_data, chunk_sz, 0x0, /* src */
chunk_sz, error))
return NULL;
}
/* check we got the desired hash */

View File

@ -320,209 +320,6 @@ dfu_firmware_metadata_func (void)
g_assert_true (ret);
}
static void
dfu_firmware_intel_hex_offset_func (void)
{
DfuElement *element_verify;
DfuImage *image_verify;
const guint8 *data;
gboolean ret;
gsize len;
g_autofree gchar *str = NULL;
g_autoptr(DfuElement) element = NULL;
g_autoptr(DfuFirmware) firmware = NULL;
g_autoptr(DfuFirmware) firmware_verify = NULL;
g_autoptr(DfuImage) image = NULL;
g_autoptr(GBytes) data_bin = NULL;
g_autoptr(GBytes) data_dummy = NULL;
g_autoptr(GError) error = NULL;
/* add a 4 byte image in high memory */
element = dfu_element_new ();
data_dummy = g_bytes_new_static ("foo", 4);
dfu_element_set_address (element, 0x80000000);
dfu_element_set_contents (element, data_dummy);
image = dfu_image_new ();
dfu_image_add_element (image, element);
firmware = dfu_firmware_new ();
dfu_firmware_add_image (firmware, image);
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
data_bin = dfu_firmware_write_data (firmware, &error);
g_assert_no_error (error);
g_assert (data_bin != NULL);
data = g_bytes_get_data (data_bin, &len);
str = g_strndup ((const gchar *) data, len);
g_assert_cmpstr (str, ==,
":0200000480007A\n"
":04000000666F6F00B8\n"
":00000001FF\n");
/* check we can load it too */
firmware_verify = dfu_firmware_new ();
ret = dfu_firmware_parse_data (firmware_verify, data_bin, DFU_FIRMWARE_PARSE_FLAG_NONE, &error);
g_assert_no_error (error);
g_assert (ret);
image_verify = dfu_firmware_get_image_default (firmware_verify);
g_assert (image_verify != NULL);
element_verify = dfu_image_get_element_default (image);
g_assert (element_verify != NULL);
g_assert_cmpint (dfu_element_get_address (element_verify), ==, 0x80000000);
g_assert_cmpint (g_bytes_get_size (dfu_element_get_contents (element_verify)), ==, 0x4);
}
static void
dfu_firmware_srec_func (void)
{
gboolean ret;
g_autofree gchar *filename_hex = NULL;
g_autofree gchar *filename_ref = NULL;
g_autoptr(DfuFirmware) firmware = NULL;
g_autoptr(GBytes) data_bin = NULL;
g_autoptr(GBytes) data_ref = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GFile) file_bin = NULL;
g_autoptr(GFile) file_hex = NULL;
filename_hex = dfu_test_get_filename ("firmware.srec");
g_assert (filename_hex != NULL);
file_hex = g_file_new_for_path (filename_hex);
firmware = dfu_firmware_new ();
ret = dfu_firmware_parse_file (firmware, file_hex,
DFU_FIRMWARE_PARSE_FLAG_NONE,
&error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 136);
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
data_bin = dfu_firmware_write_data (firmware, &error);
g_assert_no_error (error);
g_assert (data_bin != NULL);
/* did we match the reference file? */
filename_ref = dfu_test_get_filename ("firmware.bin");
g_assert (filename_ref != NULL);
file_bin = g_file_new_for_path (filename_ref);
data_ref = dfu_self_test_get_bytes_for_file (file_bin, &error);
g_assert_no_error (error);
g_assert (data_ref != NULL);
ret = fu_common_bytes_compare (data_bin, data_ref, &error);
g_assert_no_error (error);
g_assert_true (ret);
}
static void
dfu_firmware_intel_hex_func (void)
{
const guint8 *data;
gboolean ret;
gsize len;
g_autofree gchar *filename_hex = NULL;
g_autofree gchar *filename_ref = NULL;
g_autofree gchar *str = NULL;
g_autoptr(DfuFirmware) firmware = NULL;
g_autoptr(GBytes) data_bin2 = NULL;
g_autoptr(GBytes) data_bin = NULL;
g_autoptr(GBytes) data_hex = NULL;
g_autoptr(GBytes) data_ref = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GFile) file_bin = NULL;
g_autoptr(GFile) file_hex = NULL;
/* load a Intel hex32 file */
filename_hex = dfu_test_get_filename ("firmware.hex");
g_assert (filename_hex != NULL);
file_hex = g_file_new_for_path (filename_hex);
firmware = dfu_firmware_new ();
ret = dfu_firmware_parse_file (firmware, file_hex,
DFU_FIRMWARE_PARSE_FLAG_NONE,
&error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 136);
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
data_bin = dfu_firmware_write_data (firmware, &error);
g_assert_no_error (error);
g_assert (data_bin != NULL);
/* did we match the reference file? */
filename_ref = dfu_test_get_filename ("firmware.bin");
g_assert (filename_ref != NULL);
file_bin = g_file_new_for_path (filename_ref);
data_ref = dfu_self_test_get_bytes_for_file (file_bin, &error);
g_assert_no_error (error);
g_assert (data_ref != NULL);
ret = fu_common_bytes_compare (data_bin, data_ref, &error);
g_assert_no_error (error);
g_assert_true (ret);
/* export a ihex file (which will be slightly different due to
* non-continous regions being expanded */
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
data_hex = dfu_firmware_write_data (firmware, &error);
g_assert_no_error (error);
g_assert (data_hex != NULL);
data = g_bytes_get_data (data_hex, &len);
str = g_strndup ((const gchar *) data, len);
g_assert_cmpstr (str, ==,
":104000003DEF20F000000000FACF01F0FBCF02F0FE\n"
":10401000E9CF03F0EACF04F0E1CF05F0E2CF06F0FC\n"
":10402000D9CF07F0DACF08F0F3CF09F0F4CF0AF0D8\n"
":10403000F6CF0BF0F7CF0CF0F8CF0DF0F5CF0EF078\n"
":104040000EC0F5FF0DC0F8FF0CC0F7FF0BC0F6FF68\n"
":104050000AC0F4FF09C0F3FF08C0DAFF07C0D9FFA8\n"
":1040600006C0E2FF05C0E1FF04C0EAFF03C0E9FFAC\n"
":1040700002C0FBFF01C0FAFF11003FEF20F000017A\n"
":0840800042EF20F03DEF20F0BB\n"
":00000001FF\n");
/* do we match the binary file again */
dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
data_bin2 = dfu_firmware_write_data (firmware, &error);
g_assert_no_error (error);
g_assert (data_bin2 != NULL);
ret = fu_common_bytes_compare (data_bin, data_bin2, &error);
g_assert_no_error (error);
g_assert_true (ret);
}
static void
dfu_firmware_intel_hex_signed_func (void)
{
DfuElement *element;
DfuImage *image;
GBytes *data_sig;
const guint8 *data;
gboolean ret;
gsize len;
g_autofree gchar *filename_hex = NULL;
g_autoptr(DfuFirmware) firmware = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GFile) file_hex = NULL;
/* load a Intel hex32 file */
filename_hex = dfu_test_get_filename ("firmware.shex");
g_assert (filename_hex != NULL);
file_hex = g_file_new_for_path (filename_hex);
firmware = dfu_firmware_new ();
ret = dfu_firmware_parse_file (firmware, file_hex,
DFU_FIRMWARE_PARSE_FLAG_NONE,
&error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 144);
/* get the signed image element */
image = dfu_firmware_get_image_by_name (firmware, "signature");
g_assert (image != NULL);
element = dfu_image_get_element_default (image);
data_sig = dfu_element_get_contents (element);
g_assert (data_sig != NULL);
data = g_bytes_get_data (data_sig, &len);
g_assert_cmpint (len, ==, 8);
g_assert (data != NULL);
}
static gchar *
dfu_target_sectors_to_string (DfuTarget *target)
{
@ -794,7 +591,6 @@ main (int argc, char **argv)
g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
/* tests go here */
g_test_add_func ("/dfu/firmware{srec}", dfu_firmware_srec_func);
g_test_add_func ("/dfu/patch", dfu_patch_func);
g_test_add_func ("/dfu/patch{merges}", dfu_patch_merges_func);
g_test_add_func ("/dfu/patch{apply}", dfu_patch_apply_func);
@ -806,9 +602,6 @@ main (int argc, char **argv)
g_test_add_func ("/dfu/firmware{dfuse}", dfu_firmware_dfuse_func);
g_test_add_func ("/dfu/firmware{xdfu}", dfu_firmware_xdfu_func);
g_test_add_func ("/dfu/firmware{metadata}", dfu_firmware_metadata_func);
g_test_add_func ("/dfu/firmware{intel-hex-offset}", dfu_firmware_intel_hex_offset_func);
g_test_add_func ("/dfu/firmware{intel-hex}", dfu_firmware_intel_hex_func);
g_test_add_func ("/dfu/firmware{intel-hex-signed}", dfu_firmware_intel_hex_signed_func);
return g_test_run ();
}

Binary file not shown.

View File

@ -1 +0,0 @@
deadbeef

View File

@ -56,7 +56,10 @@ fu_ebitdo_device_send (FuEbitdoDevice *self,
hdr->cmd_len = GUINT16_TO_LE (in_len + 3);
hdr->cmd = cmd;
hdr->payload_len = GUINT16_TO_LE (in_len);
memcpy (packet + 0x08, in, in_len);
if (!fu_memcpy_safe (packet, sizeof(packet), 0x08, /* dst */
in, in_len, 0x0, /* src */
in_len, error))
return FALSE;
hdr->pkt_len = (guint8) (in_len + 7);
} else {
hdr->cmd_len = GUINT16_TO_LE (in_len + 1);
@ -145,9 +148,10 @@ fu_ebitdo_device_receive (FuEbitdoDevice *self,
hdr->payload_len);
return FALSE;
}
memcpy (out,
packet + sizeof(FuEbitdoPkt),
hdr->payload_len);
if (!fu_memcpy_safe (out, out_len, 0x0, /* dst */
packet, sizeof(packet), sizeof(FuEbitdoPkt), /* src */
hdr->payload_len, error))
return FALSE;
}
return TRUE;
}
@ -163,7 +167,10 @@ fu_ebitdo_device_receive (FuEbitdoDevice *self,
out_len);
return FALSE;
}
memcpy (out, packet + 1, 4);
if (!fu_memcpy_safe (out, out_len, 0x0, /* dst */
packet, sizeof(packet), 0x1, /* src */
4, error))
return FALSE;
}
return TRUE;
}
@ -181,9 +188,10 @@ fu_ebitdo_device_receive (FuEbitdoDevice *self,
hdr->cmd_len);
return FALSE;
}
memcpy (out,
packet + sizeof(FuEbitdoPkt) - 3,
hdr->cmd_len);
if (!fu_memcpy_safe (out, out_len, 0x0, /* dst */
packet, sizeof(packet), sizeof(FuEbitdoPkt) - 3, /* src */
hdr->cmd_len, error))
return FALSE;
}
return TRUE;
}
@ -348,7 +356,7 @@ fu_ebitdo_device_get_serial (FuEbitdoDevice *self)
static gboolean
fu_ebitdo_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
@ -358,6 +366,7 @@ fu_ebitdo_device_write_firmware (FuDevice *device,
const guint chunk_sz = 32;
guint32 payload_len;
guint32 serial_new[3];
g_autoptr(GBytes) fw = NULL;
g_autoptr(GError) error_local = NULL;
const guint32 app_key_index[16] = {
0x186976e5, 0xcac67acd, 0x38f27fee, 0x0a4948f1,
@ -408,6 +417,11 @@ fu_ebitdo_device_write_firmware (FuDevice *device,
return FALSE;
}
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* corrupt */
if (g_bytes_get_size (fw) < sizeof (FuEbitdoFirmwareHeader)) {
g_set_error_literal (error,

View File

@ -30,13 +30,12 @@ struct _FuFastbootDevice {
G_DEFINE_TYPE (FuFastbootDevice, fu_fastboot_device, FU_TYPE_USB_DEVICE)
static void
fu_fastboot_device_to_string (FuDevice *device, GString *str)
fu_fastboot_device_to_string (FuDevice *device, guint idt, GString *str)
{
FuFastbootDevice *self = FU_FASTBOOT_DEVICE (device);
g_string_append (str, " FuFastbootDevice:\n");
g_string_append_printf (str, " intf:\t0x%02x\n", (guint) self->intf_nr);
g_string_append_printf (str, " secure:\t%i\n", self->secure);
g_string_append_printf (str, " blocksz:\t%u\n", self->blocksz);
fu_common_string_append_kx (str, idt, "InterfaceNumber", self->intf_nr);
fu_common_string_append_kx (str, idt, "BlockSize", self->blocksz);
fu_common_string_append_kb (str, idt, "Secure", self->secure);
}
static gboolean
@ -595,11 +594,17 @@ fu_fastboot_device_write_qfil (FuDevice *device, FuArchive* archive, GError **er
static gboolean
fu_fastboot_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
g_autoptr(FuArchive) archive = NULL;
g_autoptr(GBytes) fw = NULL;
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* decompress entire archive ahead of time */
archive = fu_archive_new (fw, FU_ARCHIVE_FLAG_IGNORE_PATH, error);

View File

@ -8,8 +8,11 @@ subdir('dell-dock')
subdir('nitrokey')
subdir('rts54hid')
subdir('rts54hub')
subdir('solokey')
subdir('synaptics-cxaudio')
subdir('synaptics-prometheus')
subdir('test')
subdir('thelio-io')
subdir('udev')
subdir('unifying')
subdir('upower')
@ -56,6 +59,7 @@ endif
if get_option('plugin_uefi')
subdir('uefi')
subdir('uefi-recovery')
endif
if get_option('plugin_flashrom')

View File

@ -62,18 +62,13 @@ static guint signals [SIGNAL_LAST] = { 0 };
G_DEFINE_TYPE (FuMmDevice, fu_mm_device, FU_TYPE_DEVICE)
static void
fu_mm_device_to_string (FuDevice *device, GString *str)
fu_mm_device_to_string (FuDevice *device, guint idt, GString *str)
{
FuMmDevice *self = FU_MM_DEVICE (device);
g_string_append (str, " FuMmDevice:\n");
if (self->port_at != NULL) {
g_string_append_printf (str, " at-port:\t\t\t%s\n",
self->port_at);
}
if (self->port_qmi != NULL) {
g_string_append_printf (str, " qmi-port:\t\t\t%s\n",
self->port_qmi);
}
if (self->port_at != NULL)
fu_common_string_append_kv (str, idt, "AtPort", self->port_at);
if (self->port_qmi != NULL)
fu_common_string_append_kv (str, idt, "QmiPort", self->port_qmi);
}
const gchar *
@ -600,15 +595,21 @@ fu_mm_device_write_firmware_qmi_pdc (FuDevice *device, GBytes *fw, GArray **acti
static gboolean
fu_mm_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuMmDevice *self = FU_MM_DEVICE (device);
g_autoptr(FuDeviceLocker) locker = NULL;
g_autoptr(FuArchive) archive = NULL;
g_autoptr(GBytes) fw = NULL;
g_autoptr(GPtrArray) array = NULL;
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* lock device */
locker = fu_device_locker_new (device, error);
if (locker == NULL)

View File

@ -8,6 +8,7 @@
#include <string.h>
#include "fu-common.h"
#include "fu-qmi-pdc-updater.h"
#define FU_QMI_PDC_MAX_OPEN_ATTEMPTS 8
@ -343,6 +344,7 @@ fu_qmi_pdc_updater_load_config (WriteContext *ctx)
g_autoptr(GArray) chunk = NULL;
gsize full_size;
gsize chunk_size;
g_autoptr(GError) error = NULL;
input = qmi_message_pdc_load_config_input_new ();
qmi_message_pdc_load_config_input_set_token (input, ctx->token++, NULL);
@ -355,7 +357,12 @@ fu_qmi_pdc_updater_load_config (WriteContext *ctx)
chunk = g_array_sized_new (FALSE, FALSE, sizeof (guint8), chunk_size);
g_array_set_size (chunk, chunk_size);
memcpy (chunk->data, (const guint8 *)g_bytes_get_data (ctx->blob, NULL) + ctx->offset, chunk_size);
if (!fu_memcpy_safe ((guint8 *)chunk->data, chunk_size, 0x0, /* dst */
(const guint8 *)g_bytes_get_data (ctx->blob, NULL), /* src */
g_bytes_get_size (ctx->blob), ctx->offset,
chunk_size, &error)) {
g_critical ("failed to copy chunk: %s", error->message);
}
qmi_message_pdc_load_config_input_set_config_chunk (input,
QMI_PDC_CONFIGURATION_TYPE_SOFTWARE,

View File

@ -1,5 +1,9 @@
cargs = ['-DG_LOG_DOMAIN="FuPluginMm"']
install_data(['modem-manager.quirk'],
install_dir: join_paths(datadir, 'fwupd', 'quirks.d')
)
shared_module('fu_plugin_modem_manager',
fu_hash,
sources : [

View File

@ -0,0 +1,11 @@
# DW5821e
[DeviceInstanceId=USB\VID_413C&PID_81D7]
Summary = Dell DW5821e LTE modem
CounterpartGuid = USB\VID_413C&PID_81D6
# DW5821e in fastboot mode
[DeviceInstanceId=USB\VID_413C&PID_81D6]
Summary = Dell DW5821e LTE modem (fastboot)
CounterpartGuid = USB\VID_413C&PID_81D7

View File

@ -40,12 +40,11 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
#endif
static void
fu_nvme_device_to_string (FuDevice *device, GString *str)
fu_nvme_device_to_string (FuDevice *device, guint idt, GString *str)
{
FuNvmeDevice *self = FU_NVME_DEVICE (device);
g_string_append (str, " FuNvmeDevice:\n");
g_string_append_printf (str, " fd:\t\t\t%i\n", self->fd);
g_string_append_printf (str, " pci-depth:\t\t%u\n", self->pci_depth);
fu_common_string_append_ku (str, idt, "FD", (guint) self->fd);
fu_common_string_append_ku (str, idt, "PciDepth", self->pci_depth);
}
/* @addr_start and @addr_end are *inclusive* to match the NMVe specification */
@ -395,16 +394,22 @@ fu_nvme_device_close (FuDevice *device, GError **error)
static gboolean
fu_nvme_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuNvmeDevice *self = FU_NVME_DEVICE (device);
g_autoptr(GBytes) fw2 = NULL;
g_autoptr(GBytes) fw = NULL;
g_autoptr(GPtrArray) chunks = NULL;
guint64 block_size = self->write_block_size > 0 ?
self->write_block_size : 0x1000;
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* some vendors provide firmware files whose sizes are not multiples
* of blksz *and* the device won't accept blocks of different sizes */
if (fu_device_has_custom_flag (device, "force-align")) {

View File

@ -48,9 +48,12 @@ gboolean
fu_plugin_startup (FuPlugin *plugin, GError **error)
{
FuPluginData *data = fu_plugin_get_data (plugin);
GBytes *smbios_data = fu_plugin_get_smbios_data (plugin, REDFISH_SMBIOS_TABLE_TYPE);
g_autofree gchar *redfish_uri = NULL;
g_autofree gchar *ca_check = NULL;
g_autoptr(GBytes) smbios_data = NULL;
/* optional */
smbios_data = fu_plugin_get_smbios_data (plugin, REDFISH_SMBIOS_TABLE_TYPE);
/* read the conf file */
redfish_uri = fu_plugin_get_config_value (plugin, "Uri");

View File

@ -23,12 +23,11 @@ G_DEFINE_TYPE (FuRts54HidDevice, fu_rts54hid_device, FU_TYPE_USB_DEVICE)
#define FU_RTS54HID_DEVICE_TIMEOUT 1000 /* ms */
static void
fu_rts54hid_device_to_string (FuDevice *device, GString *str)
fu_rts54hid_device_to_string (FuDevice *device, guint idt, GString *str)
{
FuRts54HidDevice *self = FU_RTS54HID_DEVICE (device);
g_string_append (str, " FuRts54HidDevice:\n");
g_string_append_printf (str, " fw-auth: %i\n", self->fw_auth);
g_string_append_printf (str, " dual-bank: %i\n", self->dual_bank);
fu_common_string_append_kb (str, idt, "FwAuth", self->fw_auth);
fu_common_string_append_kb (str, idt, "DualBank", self->dual_bank);
}
gboolean
@ -149,7 +148,10 @@ fu_rts54hid_device_write_flash (FuRts54HidDevice *self,
g_return_val_if_fail (data_sz != 0, FALSE);
memcpy (buf, &cmd_buffer, sizeof(cmd_buffer));
memcpy (buf + FU_RTS54HID_CMD_BUFFER_OFFSET_DATA, data, data_sz);
if (!fu_memcpy_safe (buf, sizeof(buf), FU_RTS54HID_CMD_BUFFER_OFFSET_DATA, /* dst */
data, data_sz, 0x0, /* src */
data_sz, error))
return FALSE;
if (!fu_rts54hid_device_set_report (self, buf, sizeof(buf), error)) {
g_prefix_error (error, "failed to write flash @%08x: ", (guint) addr);
return FALSE;
@ -315,13 +317,19 @@ fu_rts54hid_device_close (FuUsbDevice *device, GError **error)
static gboolean
fu_rts54hid_device_write_firmware (FuDevice *device,
GBytes *fw,
FuFirmware *firmware,
FwupdInstallFlags flags,
GError **error)
{
FuRts54HidDevice *self = FU_RTS54HID_DEVICE (device);
g_autoptr(GBytes) fw = NULL;
g_autoptr(GPtrArray) chunks = NULL;
/* get default image */
fw = fu_firmware_get_image_default_bytes (firmware, error);
if (fw == NULL)
return FALSE;
/* set MCU to high clock rate for better ISP performance */
if (!fu_rts54hid_device_set_clock_mode (self, TRUE, error))
return FALSE;

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