mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-04 00:53:40 +00:00
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:
commit
fc705a8040
@ -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
17
.github/stale.yml
vendored
Normal 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
|
10
.lgtm.yml
10
.lgtm.yml
@ -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"
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
fwupd
|
||||
=====
|
||||
[](https://travis-ci.org/hughsie/fwupd)
|
||||
[](https://travis-ci.org/fwupd/fwupd)
|
||||
[](https://scan.coverity.com/projects/10744)
|
||||
|
||||
[](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
|
||||
----
|
||||
|
4
RELEASE
4
RELEASE
@ -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}"
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM fedora:29
|
||||
FROM fedora:30
|
||||
%%%OS%%%
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
|
@ -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
3
contrib/ci/abidiff.suppr
Normal file
@ -0,0 +1,3 @@
|
||||
[suppress_type]
|
||||
type_kind = enum
|
||||
changed_enumerators = FWUPD_STATUS_LAST
|
@ -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 isn’t available in Arch
|
||||
|
114
contrib/ci/check-abi
Executable file
114
contrib/ci/check-abi
Executable 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!')
|
@ -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>
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
5
data/motd/85-fwupd.motd.in
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f @motd_fullpath@ ]; then
|
||||
cat @motd_fullpath@
|
||||
fi
|
17
data/motd/README.md
Normal file
17
data/motd/README.md
Normal 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.
|
19
data/motd/fwupd-refresh.service.in
Normal file
19
data/motd/fwupd-refresh.service.in
Normal 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
|
10
data/motd/fwupd-refresh.timer
Normal file
10
data/motd/fwupd-refresh.timer
Normal 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
30
data/motd/meson.build
Normal 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
|
@ -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>
|
||||
|
@ -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
11
data/tests/firmware.shex
Normal file
@ -0,0 +1,11 @@
|
||||
:100000003DEF20F000000000FACF01F0FBCF02F03E
|
||||
:10001000E9CF03F0EACF04F0E1CF05F0E2CF06F03C
|
||||
:10002000D9CF07F0DACF08F0F3CF09F0F4CF0AF018
|
||||
:10003000F6CF0BF0F7CF0CF0F8CF0DF0F5CF0EF0B8
|
||||
:100040000EC0F5FF0DC0F8FF0CC0F7FF0BC0F6FFA8
|
||||
:100050000AC0F4FF09C0F3FF08C0DAFF07C0D9FFE8
|
||||
:1000600006C0E2FF05C0E1FF04C0EAFF03C0E9FFEC
|
||||
:1000700002C0FBFF01C0FAFF11003FEF20F00001BA
|
||||
:0800800042EF20F03DEF20F0FB
|
||||
:080000FD6465616462656566DB
|
||||
:00000001FF
|
14
debian/control.in
vendored
14
debian/control.in
vendored
@ -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
2
debian/copyright.in
vendored
@ -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
|
||||
|
1
debian/fwupd.install
vendored
1
debian/fwupd.install
vendored
@ -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
2
debian/rules
vendored
@ -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
|
||||
|
6
debian/signing-template/control
vendored
6
debian/signing-template/control
vendored
@ -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,
|
||||
|
2
debian/signing-template/copyright
vendored
2
debian/signing-template/copyright
vendored
@ -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
2
debian/watch
vendored
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
97
meson.build
97
meson.build
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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],
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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],
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
------------------
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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.
@ -1 +0,0 @@
|
||||
deadbeef
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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')
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 : [
|
||||
|
11
plugins/modem-manager/modem-manager.quirk
Normal file
11
plugins/modem-manager/modem-manager.quirk
Normal 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
|
||||
|
@ -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")) {
|
||||
|
@ -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");
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user