Codebase list fwupd / 824c323
merge 1.0.0 Mario Limonciello 6 years ago
328 changed file(s) with 26847 addition(s) and 26676 deletion(s). Raw diff Collapse all Expand all
0 To help us pinpoint your issue, please insert the output of the
1 following commands when ran on the system with the issue:
2
3 ```shell
4 $ fwupdgmr --version
5 **INSERT OUTPUT HERE**
6 ```
7
8 ```shell
9 $ fwupdmgr get-devices
10 **INSERT OUTPUT HERE**
11 ```
12
13 ```shell
14 $ efibootmgr -v
15 **INSERT OUTPUT HERE**
16 **This is only required if you use the UEFI plugin**
17 ```
18
19 ```shell
20 $ efivar -l | grep fw
21 **INSERT OUTPUT HERE**
22 **This is only required if you use the UEFI plugin**
23 ```
24
25 ```shell
26 $ tree /boot
27 **INSERT OUTPUT HERE**
28 **This is only required if you use the UEFI plugin**
29 **We're looking for any `.cap` files and the location of `fwupx64.efi`**
30 ```
31
32 Please answer the following questions:
33
34 - Operating system and version:
35 - How did you install fwupd (ex: `from source`, `pacman`, `apt-get`, etc):
36 - Have you tried rebooting?
37 - Are you using an NVMe disk?
38 - Is secure boot enabled (only for the UEFI plugin)?
55 - docker
66
77 env:
8 - OS=Fedora
9 - OS=Debian
10 - OS=Arch
8 - OS=fedora
9 - OS=debian
10 - OS=arch
11 - OS=debian-s390x
12 - OS=ubuntu-clang
1113
1214 install:
13 - if [[ "$OS" == "Fedora" ]]; then docker build -t fwupd-fedora -f contrib/ci/Dockerfile-fedora .; fi
14 - if [[ "$OS" == "Debian" ]]; then docker build -t fwupd-debian -f contrib/ci/Dockerfile-debian .; fi
15 - if [[ "$OS" == "Arch" ]]; then docker build -t fwupd-arch -f contrib/ci/Dockerfile-arch .; fi
15 - ./contrib/ci/generate_dockerfile.py; docker build -t fwupd-$OS -f contrib/ci/Dockerfile .
1616
1717 script:
18 - if [[ "$OS" == "Fedora" ]]; then docker run -e CI=true -t -v `pwd`:/build fwupd-fedora ./contrib/ci/build_and_install_rpms.sh; fi
19 - if [[ "$OS" == "Debian" ]]; then docker run -e CI=true -t -v `pwd`:/build fwupd-debian ./contrib/ci/build_and_install_debs.sh; fi
20 - if [[ "$OS" == "Arch" ]]; then docker run -e CI=true -t -v `pwd`:/build fwupd-arch ./contrib/ci/build_and_install_pkgs.sh; fi
18 - if [[ "$OS" == "fedora" ]]; then docker run -e CI=true -t -v `pwd`:/build fwupd-$OS ./contrib/ci/build_and_install_rpms.sh; fi
19 - if [[ "$OS" == "debian" ]]; then docker run -e CI=true -t -v `pwd`:/build fwupd-$OS ./contrib/ci/build_and_install_debs.sh; fi
20 - if [[ "$OS" == "ubuntu-clang" ]]; then docker run -e CC=clang -e CI=true -t -v `pwd`:/build fwupd-$OS ./contrib/ci/build_and_install_debs.sh; fi
21 - if [[ "$OS" == "arch" ]]; then docker run -e CI=true -t -v `pwd`:/build fwupd-$OS ./contrib/ci/build_and_install_pkgs.sh; fi
22 - if [[ "$OS" == "debian-s390x" ]]; then docker run -t -v `pwd`:/build fwupd-$OS ./contrib/ci/build_debian_s390x.sh; fi
0 # Contributor Covenant Code of Conduct
1
2 ## Our Pledge
3
4 In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
5
6 ## Our Standards
7
8 Examples of behavior that contributes to creating a positive environment include:
9
10 * Using welcoming and inclusive language
11 * Being respectful of differing viewpoints and experiences
12 * Gracefully accepting constructive criticism
13 * Focusing on what is best for the community
14 * Showing empathy towards other community members
15
16 Examples of unacceptable behavior by participants include:
17
18 * The use of sexualized language or imagery and unwelcome sexual attention or advances
19 * Trolling, insulting/derogatory comments, and personal or political attacks
20 * Public or private harassment
21 * Publishing others' private information, such as a physical or electronic address, without explicit permission
22 * Other conduct which could reasonably be considered inappropriate in a professional setting
23
24 ## Our Responsibilities
25
26 Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
27
28 Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
29
30 ## Scope
31
32 This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
33
34 ## Enforcement
35
36 Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at fwupd@googlegroups.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
37
38 Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
39
40 ## Attribution
41
42 This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
43
44 [homepage]: http://contributor-covenant.org
45 [version]: http://contributor-covenant.org/version/1/4/
0 Coding Style
1 ============
2
3 The coding style to respect in this project is very similar to most
4 GLib projects. In particular, the following rules are largely adapted
5 from the PackageKit Coding Style.
6
7 * 8-space tabs for indentation
8
9 * Prefer lines of less than <= 80 columns
10
11 * 1-space between function name and braces (both calls and macro
12 declarations)
13
14 * If function signature/call fits in a single line, do not break it
15 into multiple lines
16
17 * Prefer descriptive names over abbreviations (unless well-known)
18 and shortening of names. e.g `device` not `dev`
19
20 * Single statments inside if/else should not be enclosed by '{}'
21
22 * Use comments to explain why something is being done, but also avoid
23 over-documenting the obvious. Here is an example of useless comment:
24
25 // Fetch the document
26 fetch_the_document ();
27
28 * Comments should not start with a capital letter or end with a full stop and
29 should be C-style, not C++-style, e.g. `/* this */` not `// this`
30
31 * Each object should go in a separate .c file and be named according
32 to the class
33
34 * Use g_autoptr() and g_autofree whenever possible, and avoid `goto out`
35 error handling
36
37 * Failing methods should return FALSE with a suitable `GError` set
38
39 * Trailing whitespace is forbidden
40
41 * Pointers should be checked for NULL explicitly, e.g. `foo != NULL` not `!foo`
0 Version 1.0.0
1 ~~~~~~~~~~~~~
2 Released: 2017-10-09
3
4 Notes:
5 - This release breaks API and ABI to remove deprecated symbols
6 - libdfu is now not installed as a shared library
7
8 New Features:
9 - Add a human-readable title for each remote (Richard Hughes)
10 - Add a method to return a list of upgrades for a specific device (Richard Hughes)
11 - Add an 'Summary' and 'Icons' properties to each device (Richard Hughes)
12 - Add FuDeviceLocker to simplify device open/close lifecycles (Richard Hughes)
13 - Add functionality to blacklist Dell HW with problems (Mario Limonciello)
14 - Add fu_plugin_check_supported() (Richard Hughes)
15 - Add fwupd_remote_get_checksum() to use in client programs (Richard Hughes)
16 - Add ModifyRemote as an easy way to enable and disable remotes (Richard Hughes)
17 - Add the plugin documentation to the main gtk-doc (Richard Hughes)
18 - Allow plugins to depend on each other (Richard Hughes)
19 - Disable the fallback USB plugin (Richard Hughes)
20 - Parse the SMBIOS v2 and v3 DMI tables directly (Richard Hughes)
21 - Support uploading the UEFI firmware splash image (Richard Hughes)
22 - Use the intel-wmi-thunderbolt kernel module to force power (Mario Limonciello)
23
24 Bugfixes:
25 - Only run SMI to toggle host MST GPIO on Dell systems with host MST (Mario Limonciello)
26 - Disable unifying support if no CONFIG_HIDRAW support (Richard Hughes)
27 - Do not auto-open all USB devices at startup (Richard Hughes)
28 - Do not fail to load the daemon if cached metadata is invalid (Richard Hughes)
29 - Do not use system-specific infomation for UEFI PCI devices (Richard Hughes)
30 - Fix a crash when using fu_plugin_device_add_delay() (Richard Hughes)
31 - Fix the libdfu self test failure on s390 and ppc64 (Richard Hughes)
32 - Fix various printing issues with the progressbar (Richard Hughes)
33 - Generate the LD script from the GObject introspection data (Richard Hughes)
34 - Never fallback to an offline update from client code (Richard Hughes)
35 - Only set the Dell coldplug delay when we know we need it (Mario Limonciello)
36 - Prefer to use HWIDs to get DMI keys and DE table (Mario Limonciello)
37
038 Version 0.9.7
139 ~~~~~~~~~~~~~
240 Released: 2017-09-01
00 fwupd
11 =====
22 [![Build Status](https://travis-ci.org/hughsie/fwupd.png?branch=master)](https://travis-ci.org/hughsie/fwupd)
3 [![Coverity Scan Build Status](https://scan.coverity.com/projects/10744/badge.svg)](https://scan.coverity.com/projects/10744)
34
45 This project aims to make updating firmware on Linux automatic, safe and reliable.
56
11
22 1. Write NEWS entries for fwupd in the same format as usual.
33
4 git shortlog 0.9.6.. | grep -i -v trivial | grep -v Merge > NEWS.new
4 git shortlog 0.9.7.. | grep -i -v trivial | grep -v Merge > NEWS.new
55
6 Version 0.9.7
6 Version 1.0.0
77 ~~~~~~~~~~~~~
88 Released: 2017-xx-xx
99
2020 2. Commit changes to git:
2121
2222 # MAKE SURE THESE ARE CORRECT
23 export release_ver="0.9.7"
23 export release_ver="1.0.0"
2424
2525 git commit -a -m "Release fwupd ${release_ver}"
2626 git tag -s -f -m "Release fwupd ${release_ver}" "${release_ver}"
1414
1515 build() {
1616 cd ${pkgname}
17 if [ -n "$CI" ]; then
18 export CI="-Denable-werror=true \
19 -Denable-usb-fallback=true"
20 fi
1721 meson --prefix=/usr \
1822 --sysconfdir=/etc \
1923 --localstatedir=/var \
2024 --libexecdir=/usr/lib \
2125 --buildtype=plain \
26 $CI \
2227 ../build
2328
2429 ninja -v -C ../build
55 The build can be performed using Linux containers with [Docker](www.docker.com).
66
77 ## RPM packages
8 A Dockerfile for Fedora 25 is available here in `contrib`.
8 A Dockerfile for Fedora can be generated in `contrib`.
99
1010 To prepare the Docker container run this command:
11 ```OS=fedora ./generate_dockerfile.py; docker build -t fwupd-fedora -f contrib/ci/Dockerfile .```
1112
1213 `docker build -t fwupd-fedora -f contrib/ci/Dockerfile-fedora .`
1314
1819 RPMs will be made available in your working directory when complete.
1920
2021 ## DEB packages
21 A Dockerfile is available for Debian unstable.
22 A Dockerfile for Debian or Ubuntu can be generated in `contrib`.
2223
2324 To prepare the Docker container run this command:
2425
25 `docker build -t fwupd-debian -f contrib/ci/Dockerfile-debian .`
26 ```OS=debian ./generate_dockerfile.py; docker build -t fwupd-debian -f contrib/ci/Dockerfile .```
2627
2728 To build the DEBs run this command (from the root of your git checkout):
2829
3132 DEBs will be made available in your working directory when complete.
3233
3334 ## PKG packages
34 A Dockerfile is available for Arch Linux.
35 A Dockerfile for Arch can be generated in `contrib`.
3536
3637 To prepare the Docker container run this command:
3738
38 `docker build -t fwupd-arch -f contrib/ci/Dockerfile-arch .`
39 ```OS=arch ./generate_dockerfile.py; docker build -t fwupd-arch -f contrib/ci/Dockerfile .```
3940
4041 To build the PKGs run this command (from the root of your git checkout):
4142
+0
-34
contrib/ci/Dockerfile-arch less more
0 FROM archlinux/base
1 # set the locale
2 ENV LANG en_US.UTF-8
3 ENV LC_ALL en_US.UTF-8
4 # keep the package DB
5 RUN rm /usr/share/libalpm/hooks/package-cleanup.hook
6 # update the image, install devel packages
7 RUN pacman -Syu --noconfirm
8 RUN pacman -S --noconfirm base-devel
9 # runtime deps
10 RUN pacman -S --noconfirm \
11 appstream-glib \
12 colord \
13 fwupdate
14 # buildtime deps
15 RUN pacman -S --noconfirm \
16 adobe-source-han-sans-cn-fonts \
17 docbook-utils \
18 docbook-sgml \
19 gobject-introspection \
20 gtk-doc \
21 meson \
22 perl-sgmls \
23 python-cairo \
24 python-gobject \
25 python-pillow \
26 ttf-dejavu \
27 umockdev \
28 valgrind
29 # CI dep
30 RUN pacman -S --noconfirm git
31 # prepare the build environment
32 RUN mkdir /build
33 WORKDIR /build
0 FROM archlinux/base
1 ENV LANG en_US.UTF-8
2 ENV LC_ALL en_US.UTF-8
3 RUN rm /usr/share/libalpm/hooks/package-cleanup.hook
4 %%%INSTALL_DEPENDENCIES_COMMAND%%%
5 RUN mkdir /build
6 WORKDIR /build
+0
-60
contrib/ci/Dockerfile-debian less more
0 FROM debian:unstable
1
2 RUN apt-get update -qq
3 RUN apt-get install -yq --no-install-recommends \
4 debhelper \
5 devscripts \
6 fakeroot \
7 docbook-utils \
8 fontconfig \
9 fontconfig-config \
10 fonts-dejavu \
11 git \
12 gcab \
13 gettext \
14 gir1.2-appstreamglib-1.0 \
15 gir1.2-pango-1.0 \
16 gnutls-bin \
17 gnutls-dev \
18 gobject-introspection \
19 gtk-doc-tools \
20 texlive-fonts-recommended \
21 locales \
22 libappstream-glib-dev \
23 libarchive-dev \
24 libcairo-dev \
25 libcairo-gobject2 \
26 libcolord-dev \
27 libcolorhug-dev \
28 libefivar-dev \
29 libelf-dev \
30 libfreetype6-dev \
31 libfwup-dev \
32 libgcab-dev \
33 libgirepository1.0-dev \
34 libglib2.0-dev \
35 libgpgme11-dev \
36 libgudev-1.0-dev \
37 libgusb-dev \
38 libpolkit-gobject-1-dev \
39 libsmbios-dev \
40 libsoup2.4-dev \
41 libsqlite3-dev \
42 libtool-bin \
43 libumockdev-dev \
44 lintian \
45 meson \
46 pkg-config \
47 policykit-1 \
48 python3-gi-cairo \
49 python3-pil \
50 udev \
51 umockdev \
52 systemd \
53 valgrind
54 #deps needed only for installed tests
55 RUN apt-get install -yq --no-install-recommends \
56 gnome-desktop-testing dbus-x11 ca-certificates \
57 python3-requests
58 RUN mkdir /build
59 WORKDIR /build
0 FROM debian:testing
1 %%%ARCH_SPECIFIC_COMMAND%%%
2 %%%INSTALL_DEPENDENCIES_COMMAND%%%
3 RUN mkdir /build
4 WORKDIR /build
+0
-62
contrib/ci/Dockerfile-fedora less more
0 FROM fedora:26
1
2 ENV LANG en_US.UTF-8
3 ENV LANGUAGE en_US:en
4 ENV LC_ALL en_US.UTF-8
5
6 RUN dnf --enablerepo=updates-testing -y update
7 RUN dnf --enablerepo=updates-testing -y install \
8 adobe-source-han-sans-cn-fonts \
9 cairo-devel \
10 cairo-gobject-devel \
11 colord-devel \
12 dejavu-sans-fonts \
13 docbook-utils \
14 elfutils-libelf-devel \
15 freetype \
16 fontconfig \
17 fwupdate-devel \
18 git \
19 gcab \
20 gettext \
21 glib2-devel \
22 gobject-introspection-devel \
23 gpgme-devel \
24 gnutls-devel \
25 gnutls-utils \
26 gtk-doc \
27 jq \
28 libappstream-glib-devel \
29 libarchive-devel \
30 libgudev1-devel \
31 libgusb-devel \
32 libsmbios-devel \
33 libsoup-devel \
34 meson \
35 pango-devel \
36 polkit-devel \
37 python3 \
38 python3-cairo \
39 python3-gobject \
40 python3-pillow \
41 rpm-build \
42 redhat-rpm-config \
43 sqlite-devel \
44 systemd \
45 umockdev-devel \
46 valgrind \
47 valgrind-devel \
48 xz
49 #deps needed only for installed tests
50 RUN dnf --enablerepo=updates-testing -y install \
51 adobe-source-han-sans-cn-fonts \
52 ca-certificates \
53 dbus-x11 \
54 dconf \
55 gnome-desktop-testing \
56 polkit \
57 python3-gobject \
58 python3-requests \
59 gnupg2
60 RUN mkdir /build
61 WORKDIR /build
0 FROM fedora:26
1 ENV LANG en_US.UTF-8
2 ENV LANGUAGE en_US:en
3 ENV LC_ALL en_US.UTF-8
4 RUN dnf --enablerepo=updates-testing -y update
5 %%%INSTALL_DEPENDENCIES_COMMAND%%%
6 RUN mkdir /build
7 WORKDIR /build
+0
-60
contrib/ci/Dockerfile-ubuntu less more
0 FROM ubuntu:devel
1
2 RUN apt-get update -qq
3 RUN apt-get install -yq --no-install-recommends \
4 debhelper \
5 devscripts \
6 fakeroot \
7 docbook-utils \
8 fontconfig \
9 fontconfig-config \
10 fonts-dejavu \
11 git \
12 gcab \
13 gettext \
14 gir1.2-appstreamglib-1.0 \
15 gir1.2-pango-1.0 \
16 gnutls-bin \
17 gnutls-dev \
18 gobject-introspection \
19 gtk-doc-tools \
20 texlive-fonts-recommended \
21 locales \
22 libappstream-glib-dev \
23 libarchive-dev \
24 libcairo-dev \
25 libcairo-gobject2 \
26 libcolord-dev \
27 libcolorhug-dev \
28 libefivar-dev \
29 libelf-dev \
30 libfreetype6-dev \
31 libfwup-dev \
32 libgcab-dev \
33 libgirepository1.0-dev \
34 libglib2.0-dev \
35 libgpgme11-dev \
36 libgudev-1.0-dev \
37 libgusb-dev \
38 libpolkit-gobject-1-dev \
39 libsmbios-dev \
40 libsoup2.4-dev \
41 libsqlite3-dev \
42 libtool-bin \
43 libumockdev-dev \
44 lintian \
45 meson \
46 pkg-config \
47 policykit-1 \
48 python3-gi-cairo \
49 python3-pil \
50 udev \
51 umockdev \
52 systemd \
53 valgrind
54 #deps needed only for installed tests
55 RUN apt-get install -yq --no-install-recommends \
56 gnome-desktop-testing dbus-x11 ca-certificates \
57 python3-requests
58 RUN mkdir /build
59 WORKDIR /build
0 FROM ubuntu:devel
1 %%%ARCH_SPECIFIC_COMMAND%%%
2 %%%INSTALL_DEPENDENCIES_COMMAND%%%
3 RUN mkdir /build
4 WORKDIR /build
0 Continuous Integration
1 ======================
2 Continuous integration for fwupd is provided by [Travis CI](https://travis-ci.org/hughsie/fwupd).
3
4 By using Travis CI, builds are exercised across a variety of environments attempting to maximize code coverage.
5 For every commit or pull request 5 builds are performed:
6
7 Fedora
8 ------
9
10 * A fully packaged RPM build with all plugins enabled
11 * Compiled under gcc
12 * Tests with -Werror enabled
13 * Tests with the built in local test suite for all plugins.
14 * All packages are installed
15 * An installed testing run with the "test" plugin and pulling from LVFS.
16
17 Debian unstable (gcc)
18 ------
19
20 * A fully packaged DEB build with all plugins enabled
21 * Compiled under gcc
22 * Tests with -Werror enabled
23 * Tests with the built in local test suite for all plugins.
24 * All packages are installed
25 * An installed testing run with the "test" plugin and pulling from LVFS.
26 * All packages are removed
27
28 Ubuntu devel release (clang)
29 ------
30
31 * A fully packaged DEB build with all plugins enabled
32 * Compiled under clang
33 * Tests without -Werror enabled
34 * Tests with the built in local test suite for all plugins.
35 * All packages are installed
36 * An installed testing run with the "test" plugin and pulling from LVFS.
37 * All packages are removed
38
39 Debian unstable (cross compile s390x)
40 ------
41
42 * Not packaged
43 * Compiled under gcc
44 * Tests with -Werror enabled
45 * Runs local test suite using qemu-user
46
47 Arch Linux
48 ----------
49
50 * A fully packaged pkg build with all plugins enabled
51 * Compiled under gcc
52 * Tests with -Werror enabled
53 * Compile with the deprecated USB plugin enabled
54 * Tests with the built in local test suite for all plugins.
55 * All packages are installed
56
1414 mv contrib/debian .
1515 sed s/quilt/native/ debian/source/format -i
1616 EDITOR=/bin/true dch --create --package fwupd -v $VERSION "CI Build"
17 debuild --no-lintian
17 debuild --no-lintian --preserve-envvar CI --preserve-envvar CC
1818
1919 #check lintian output
2020 #suppress tags that are side effects of building in docker this way
2727 --suppress-tags changelog-should-mention-nmu \
2828 --suppress-tags debian-watch-file-in-native-package \
2929 --suppress-tags source-nmu-has-incorrect-version-number \
30 --suppress-tags no-symbols-control-file \
3031 --allow-root
3132
33 #if invoked outside of CI
34 if [ ! -f /.dockerenv ]; then
35 echo "Not running in a container, please manually install packages"
36 exit 0
37 fi
38
3239 #test the packages install
33 dpkg -i `ls ../*.deb | grep -v fwupd-tests`
40 dpkg -i `ls ../*.deb | grep -v 'fwupd-tests\|dbgsym'`
3441
3542 # run the installed tests
3643 if [ "$CI" = "true" ]; then
4350 #test the packages remove
4451 apt purge -y fwupd \
4552 fwupd-doc \
46 fwupd-dbgsym \
47 gir1.2-fwupd-1.0 \
48 libdfu1 \
49 libdfu1-dbgsym \
50 libdfu-dev \
51 libfwupd1 \
52 libfwupd1-dbgsym \
53 libfwupd2 \
5354 libfwupd-dev
66 mkdir -p build && pushd build
77 rm -rf *
88 meson .. \
9 -Denable-werror=true \
910 -Denable-doc=true \
1011 -Denable-man=true \
1112 -Denable-tests=true \
3334 #build RPM packages
3435 rpmbuild -ba build/fwupd.spec
3536
37 #if invoked outside of CI
38 if [ ! -f /.dockerenv ]; then
39 echo "Not running in a container, please manually install packages"
40 exit 0
41 fi
42
3643 #install RPM packages
37 dnf install -C -y $HOME/rpmbuild/RPMS/*/*.rpm
44 dnf install -y $HOME/rpmbuild/RPMS/*/*.rpm
3845
3946 cp $HOME/rpmbuild/RPMS/*/*.rpm .
4047
4148 # run the installed tests
4249 if [ "$CI" = "true" ]; then
43 sed "s,^EnableTestSuite=.*,EnableTestSuite=true," -i /etc/fwupd.conf
50 sed "s,^BlacklistPlugins=test,BlacklistPlugins=," -i /etc/fwupd/daemon.conf
4451 mkdir -p /run/dbus
4552 mkdir -p /var
4653 ln -s /var/run /run
+0
-20
contrib/ci/build_and_test.sh less more
0 #!/bin/sh
1 set -e
2 set -x
3
4 export LC_ALL=C.UTF-8
5 mkdir -p build && cd build
6 rm * -rf
7 meson .. \
8 -Denable-doc=true \
9 -Denable-man=true \
10 -Denable-tests=true \
11 -Denable-thunderbolt=true \
12 -Denable-uefi=true \
13 -Denable-dell=true \
14 -Denable-synaptics=true \
15 -Denable-colorhug=true $@
16 ninja -v || bash
17 ninja test -v
18 DESTDIR=/tmp/install-ninja ninja install
19 cd ..
0 #!/bin/sh
1 set -e
2 set -x
3
4 export LC_ALL=C.UTF-8
5 rm -rf build
6 mkdir -p build
7 cp contrib/ci/s390x_cross.txt build/
8 cd build
9 meson .. \
10 --cross-file s390x_cross.txt \
11 -Denable-werror=true \
12 -Denable-uefi=false \
13 -Denable-uefi-labels=false \
14 -Denable-dell=false \
15 -Denable-synaptics=false \
16 -Denable-introspection=false \
17 -Denable-doc=false \
18 -Denable-man=false
19 ninja -v
20 ninja test -v
21 cd ..
0 fedora, arch, debian, ubuntu-clang, debian-s390x,
1 , base-devel, , , ,
2 adobe-source-han-sans-cn-fonts, adobe-source-han-sans-cn-fonts, , , ,
3 , , , , binutils-multiarch
4 ca-certificates, , ca-certificates, ca-certificates, ,
5 , , , clang, ,
6 cairo-devel, , libcairo-dev, libcairo-dev, libcairo-dev:s390x,
7 cairo-gobject-devel, , libcairo-gobject2, libcairo-gobject2, libcairo-gobject2:s390x,
8 colord-devel, colord, libcolord-dev, libcolord-dev, libcolord-dev:s390x,
9 dejavu-sans-fonts, ttf-dejavu, fonts-dejavu, fonts-dejavu, ,
10 , , devscripts, devscripts, ,
11 , , debhelper, debhelper, ,
12 dbus-x11, , dbus-x11, dbus-x11, ,
13 dconf, , , , ,
14 docbook-utils, docbook-utils, docbook-utils, docbook-utils, ,
15 , docbook-sgml, , , ,
16 elfutils-libelf-devel, , libelf-dev, libelf-dev, libelf-dev:s390x,
17 , , fakeroot, fakeroot, ,
18 freetype, , libfreetype6-dev, libfreetype6-dev, libfreetype6-dev:s390x,
19 fontconfig, , fontconfig, fontconfig, ,
20 fwupdate-devel, fwupdate, libfwup-dev, libfwup-dev, ,
21 gcab, , gcab, gcab, gcab,
22 gettext, , gettext, gettext, gettext,
23 gnupg2, , , , ,
24 , , gir1.2-appstreamglib-1.0, gir1.2-appstreamglib-1.0, ,
25 , , , , gcc-multilib-s390x-linux-gnu,
26 git, git, git, git, git,
27 glib2-devel, , libglib2.0-dev, libglib2.0-dev, libglib2.0-dev:s390x,
28 gobject-introspection-devel, gobject-introspection, gobject-introspection, gobject-introspection, ,
29 gpgme-devel, , libgpgme11-dev, libgpgme11-dev, libgpgme-dev:s390x,
30 gnome-desktop-testing, , gnome-desktop-testing, gnome-desktop-testing, ,
31 gnutls-devel, , gnutls-dev, gnutls-dev, libgnutls28-dev:s390x,
32 , , gnutls-bin, gnutls-bin, gnutls-bin,
33 gnutls-utils, , , , ,
34 gtk-doc, gtk-doc, gtk-doc-tools, gtk-doc-tools, ,
35 jq, , , , ,
36 libappstream-glib-devel, appstream-glib, libappstream-glib-dev, libappstream-glib-dev, libappstream-glib-dev:s390x,
37 libarchive-devel, , libarchive-dev, libarchive-dev, libarchive-dev:s390x,,
38 , , libcolorhug-dev, libcolorhug-dev, libcolorhug-dev:s390x,
39 , , libefivar-dev, libefivar-dev, ,
40 , , libgcab-dev, libgcab-dev, libgcab-dev:s390x,
41 , , libgirepository1.0-dev, libgirepository1.0-dev, libgirepository1.0-dev,
42 libgudev1-devel, , libgudev-1.0-dev, libgudev-1.0-dev, libgudev-1.0-dev:s390x,
43 libgusb-devel, , libgusb-dev, libgusb-dev, libgusb-dev:s390x,
44 , , , , libicu-dev:s390x,
45 , , , , libidn2-0-dev:s390x,
46 libsmbios-devel, , libsmbios-dev, libsmbios-dev, ,
47 libsoup-devel, , libsoup2.4-dev, libsoup2.4-dev, libsoup2.4-dev:s390x,
48 , , libtool-bin, libtool-bin, ,
49 , , libumockdev-dev, libumockdev-dev, ,
50 , , , , libxml2-dev:s390x,
51 , , lintian, lintian, ,
52 , , locales, locales, locales,
53 meson, meson, meson, meson, meson,
54 pango-devel, , gir1.2-pango-1.0, gir1.2-pango-1.0, ,
55 , perl-sgmls, , , ,
56 , , pkg-config, pkg-config, ,
57 polkit, , policykit-1, policykit-1, policykit-1,
58 polkit-devel, , libpolkit-gobject-1-dev, libpolkit-gobject-1-dev, libpolkit-gobject-1-dev:s390x,
59 python3, , , , ,
60 python3-cairo, python-cairo, python3-gi-cairo, python3-gi-cairo, python3-gi-cairo,
61 python3-gobject, python-gobject, , , ,
62 python3-pillow, python-pillow, python3-pil, python3-pil, python3-pil,
63 python3-requests, , python3-requests, python3-requests, ,
64 , , , , qemu-user,
65 rpm-build, , , , ,
66 redhat-rpm-config, , , , ,
67 sqlite-devel, , libsqlite3-dev, libsqlite3-dev, libsqlite3-dev:s390x,
68 systemd, , systemd, systemd, systemd,
69 , , texlive-fonts-recommended, texlive-fonts-recommended, ,
70 , , udev, udev, udev,
71 umockdev-devel, umockdev, umockdev, umockdev, ,
72 valgrind, valgrind, valgrind, valgrind, ,
73 valgrind-devel, , , , ,
74 xz, , , , ,
0 #!/usr/bin/python3
1 #
2 # Copyright (C) 2017 Dell Inc.
3 #
4 # Licensed under the GNU General Public License Version 2
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #
20 import os
21 import sys
22
23 directory = os.path.dirname(sys.argv[0])
24 TARGET=os.getenv('OS')
25
26 if TARGET == '':
27 print("Missing OS environment variable")
28 sys.exit(1)
29
30 deps = []
31 with open (os.path.join(directory,"dependencies.txt"), 'r') as rfd:
32 header = rfd.readline().split(',')
33 pos = -1
34 for i in range(0,len(header)):
35 if header[i].strip() == TARGET:
36 pos = i
37 break
38 if pos == -1:
39 print("Unknown OS: %s" % TARGET)
40 sys.exit(1)
41 for line in rfd.readlines():
42 dep = line.split(',')[pos].strip()
43 if dep == '':
44 continue
45 deps.append(dep)
46
47 OS = TARGET
48 SUBOS = ''
49 split = TARGET.split('-')
50 if len(split) >= 2:
51 OS = split[0]
52 SUBOS = split[1]
53
54 input = os.path.join(directory, "Dockerfile-%s.in" % OS)
55 if not os.path.exists(input):
56 print("Missing input file %s for %s" % (input, OS))
57 sys.exit(1)
58
59 with open(input, 'r') as rfd:
60 lines = rfd.readlines()
61
62 out = os.path.join(directory, "Dockerfile")
63
64 with open(out, 'w') as wfd:
65 for line in lines:
66 if line == "%%%INSTALL_DEPENDENCIES_COMMAND%%%\n":
67 if OS == "fedora":
68 wfd.write("RUN dnf --enablerepo=updates-testing -y install \\\n")
69 elif OS == "debian" or OS == "ubuntu":
70 wfd.write("RUN apt update -qq && \\\n")
71 wfd.write("\tapt install -yq --no-install-recommends\\\n")
72 elif OS == "arch":
73 wfd.write("RUN pacman -Syu --noconfirm \\\n")
74 for i in range(0, len(deps)):
75 if i < len(deps)-1:
76 wfd.write("\t%s \\\n" % deps[i])
77 else:
78 wfd.write("\t%s \n" % deps[i])
79 elif line == "%%%ARCH_SPECIFIC_COMMAND%%%\n":
80 if OS == "debian" and SUBOS == "s390x":
81 #add sources
82 wfd.write('RUN cat /etc/apt/sources.list | sed "s/deb/deb-src/" >> /etc/apt/sources.list\n')
83 #add new architecture
84 wfd.write('RUN dpkg --add-architecture %s\n' % SUBOS)
85 else:
86 wfd.write(line)
0 [binaries]
1 c = 's390x-linux-gnu-gcc'
2 cpp = 's390x-linux-gnu-cpp'
3 ar = 's390x-linux-gnu-ar'
4 strip = 's390x-linux-gnu-strip'
5 pkgconfig = 's390x-linux-gnu-pkg-config'
6 exe_wrapper = 'qemu-s390x'
7
8 [host_machine]
9 system = 'linux'
10 cpu_family = 's390x'
11 cpu = 's390x'
12 endian = 'big'
7474 Requires(preun): systemd
7575 Requires(postun): systemd
7676
77 Requires: libdfu%{?_isa} = %{version}-%{release}
7877 Requires: glib2%{?_isa} >= %{glib2_version}
7978 Requires: libappstream-glib%{?_isa} >= %{libappstream_version}
8079 Requires: libgusb%{?_isa} >= %{libgusb_version}
8685
8786 Obsoletes: fwupd-sign < 0.1.6
8887 Obsoletes: libebitdo < 0.7.5-3
88 Obsoletes: libdfu < 0.9.8-1
8989
9090 %description
9191 fwupd is a daemon to allow session software to update device firmware.
9494 Summary: Development package for %{name}
9595 Requires: %{name}%{?_isa} = %{version}-%{release}
9696 Obsoletes: libebitdo-devel < 0.7.5-3
97 Obsoletes: libdfu-devel < 0.9.8-1
9798
9899 %description devel
99100 Files for development with %{name}.
100
101 %package -n libdfu
102 Summary: A library for DFU
103
104 %description -n libdfu
105 A library for updating USB devices using DFU.
106
107 %package -n libdfu-devel
108 Summary: Development package for libdfu
109 Requires: libdfu%{?_isa} = %{version}-%{release}
110
111 %description -n libdfu-devel
112 Files for development with libdfu.
113101
114102 %package labels
115103 Summary: Rendered labels for display during system firmware updates.
187175 /sbin/ldconfig
188176 %systemd_postun_with_restart fwupd.service
189177
190 %post -n libdfu -p /sbin/ldconfig
191 %postun -n libdfu -p /sbin/ldconfig
192
193178 %files -f %{name}.lang
194179 %doc README.md AUTHORS NEWS
195180 %license COPYING
196 %config(noreplace)%{_sysconfdir}/fwupd.conf
181 %config(noreplace)%{_sysconfdir}/fwupd/daemon.conf
197182 %dir %{_libexecdir}/fwupd
198183 %{_libexecdir}/fwupd/fwupd
184 %{_bindir}/dfu-tool
199185 %{_bindir}/fwupdmgr
200186 %dir %{_sysconfdir}/fwupd
201187 %dir %{_sysconfdir}/fwupd/remotes.d
212198 %{_datadir}/polkit-1/actions/org.freedesktop.fwupd.policy
213199 %{_datadir}/polkit-1/rules.d/org.freedesktop.fwupd.rules
214200 %{_datadir}/dbus-1/system-services/org.freedesktop.fwupd.service
201 %{_datadir}/man/man1/dfu-tool.1.gz
215202 %{_datadir}/man/man1/fwupdmgr.1.gz
216203 %{_datadir}/metainfo/org.freedesktop.fwupd.metainfo.xml
217204 %{_datadir}/fwupd/firmware-packager
221208 %dir %{_localstatedir}/lib/fwupd
222209 %{_localstatedir}/lib/fwupd/builder/README.md
223210 %{_libdir}/libfwupd*.so.*
224 %{_libdir}/girepository-1.0/Fwupd-1.0.typelib
211 %{_libdir}/girepository-1.0/Fwupd-2.0.typelib
225212 /usr/lib/udev/rules.d/*.rules
226 %dir %{_libdir}/fwupd-plugins-2
227 %{_libdir}/fwupd-plugins-2/libfu_plugin_altos.so
228 %{_libdir}/fwupd-plugins-2/libfu_plugin_amt.so
229 %{_libdir}/fwupd-plugins-2/libfu_plugin_colorhug.so
230 %if 0%{?have_dell}
231 %{_libdir}/fwupd-plugins-2/libfu_plugin_dell.so
232 %endif
233 %{_libdir}/fwupd-plugins-2/libfu_plugin_dfu.so
234 %{_libdir}/fwupd-plugins-2/libfu_plugin_ebitdo.so
235 %{_libdir}/fwupd-plugins-2/libfu_plugin_raspberrypi.so
236 %{_libdir}/fwupd-plugins-2/libfu_plugin_steelseries.so
237 %if 0%{?have_dell}
238 %{_libdir}/fwupd-plugins-2/libfu_plugin_synapticsmst.so
213 %dir %{_libdir}/fwupd-plugins-3
214 %{_libdir}/fwupd-plugins-3/libfu_plugin_altos.so
215 %{_libdir}/fwupd-plugins-3/libfu_plugin_amt.so
216 %{_libdir}/fwupd-plugins-3/libfu_plugin_colorhug.so
217 %if 0%{?have_dell}
218 %{_libdir}/fwupd-plugins-3/libfu_plugin_dell.so
219 %endif
220 %{_libdir}/fwupd-plugins-3/libfu_plugin_dfu.so
221 %{_libdir}/fwupd-plugins-3/libfu_plugin_ebitdo.so
222 %{_libdir}/fwupd-plugins-3/libfu_plugin_raspberrypi.so
223 %{_libdir}/fwupd-plugins-3/libfu_plugin_steelseries.so
224 %if 0%{?have_dell}
225 %{_libdir}/fwupd-plugins-3/libfu_plugin_synapticsmst.so
239226 %endif
240227 %if 0%{?enable_dummy}
241 %{_libdir}/fwupd-plugins-2/libfu_plugin_test.so
242 %endif
243 %{_libdir}/fwupd-plugins-2/libfu_plugin_thunderbolt.so
244 %{_libdir}/fwupd-plugins-2/libfu_plugin_udev.so
245 %if 0%{?have_uefi}
246 %{_libdir}/fwupd-plugins-2/libfu_plugin_uefi.so
247 %endif
248 %{_libdir}/fwupd-plugins-2/libfu_plugin_unifying.so
249 %{_libdir}/fwupd-plugins-2/libfu_plugin_upower.so
250 %{_libdir}/fwupd-plugins-2/libfu_plugin_usb.so
228 %{_libdir}/fwupd-plugins-3/libfu_plugin_test.so
229 %endif
230 %{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt.so
231 %{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt_power.so
232 %{_libdir}/fwupd-plugins-3/libfu_plugin_udev.so
233 %if 0%{?have_uefi}
234 %{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
235 %endif
236 %{_libdir}/fwupd-plugins-3/libfu_plugin_unifying.so
237 %{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so
251238 %ghost %{_localstatedir}/lib/fwupd/gnupg
252239
253240 %files devel
254 %{_datadir}/gir-1.0/Fwupd-1.0.gir
241 %{_datadir}/gir-1.0/Fwupd-2.0.gir
255242 %{_datadir}/gtk-doc/html/libfwupd
256243 %{_includedir}/fwupd-1
257244 %{_libdir}/libfwupd*.so
258245 %{_libdir}/pkgconfig/fwupd.pc
259
260 %files -n libdfu
261 %{_bindir}/dfu-tool
262 %{_datadir}/man/man1/dfu-tool.1.gz
263 %{_libdir}/girepository-1.0/Dfu-1.0.typelib
264 %{_libdir}/libdfu*.so.*
265
266 %files -n libdfu-devel
267 %{_datadir}/gir-1.0/Dfu-1.0.gir
268 %{_datadir}/gtk-doc/html/libdfu
269 %dir %{_includedir}/libdfu
270 %{_includedir}/dfu.h
271 %{_includedir}/libdfu/*.h
272 %{_libdir}/libdfu*.so
273 %{_libdir}/pkgconfig/dfu.pc
274246
275247 %files labels
276248 %if 0%{?have_uefi}
0 [fwupd]
1
2 # Allow blacklisting specific devices by their GUID
3 # Uses semicolons as delimiter
4 BlacklistDevices=
5
6 # Allow blacklisting specific plugins
7 # Uses semicolons as delimiter
8 BlacklistPlugins=test
+0
-20
data/fwupd.conf less more
0 [fwupd]
1
2 # The download URI to use for LVFS metadata -- this is only used as a
3 # fallback and clients should use FwupdRemote objects instead
4 DownloadURI=https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz
5
6 # If we should verify option ROM images
7 EnableOptionROM=true
8
9 # Allow blacklisting specific devices by their GUID
10 # Uses semicolons as delimiter
11 BlacklistDevices=
12
13 # Allow blacklisting specific plugins
14 # Uses semicolons as delimiter
15 BlacklistPlugins=
16
17 # Turns on support for running the test suite
18 # this will cause an extraneous "test" device to be present on the system
19 EnableTestSuite=false
1515 ProtectSystem=full
1616 RestrictAddressFamilies=AF_NETLINK AF_UNIX
1717 RestrictRealtime=yes
18 ReadWritePaths=@localstatedir@/lib/fwupd -@bootdir@
18 ReadWritePaths=@localstatedir@/lib/fwupd @sysconfdir@/fwupd/remotes.d -@bootdir@
19 SystemCallFilter=~@mount
88 import requests
99 import time
1010
11 gi.require_version('Fwupd', '1.0')
11 gi.require_version('Fwupd', '2.0')
1212
1313 from gi.repository import Fwupd
1414 from gi.repository import Gio
00 subdir('builder')
1 subdir('tests')
2 subdir('installed-tests')
31 subdir('pki')
42 subdir('remotes.d')
53
6 install_data(['fwupd.conf'],
7 install_dir : get_option('sysconfdir')
4 if get_option('enable-tests')
5 subdir('tests')
6 subdir('installed-tests')
7 endif
8
9 install_data(['daemon.conf'],
10 install_dir : join_paths(get_option('sysconfdir'), 'fwupd')
811 )
912
1013 install_data(['org.freedesktop.fwupd.metainfo.xml'],
3336 con2.set('localstatedir', join_paths(get_option('localstatedir')))
3437 con2.set('datadir', join_paths(get_option('datadir')))
3538 con2.set('bootdir', get_option('with-bootdir'))
39 con2.set('sysconfdir', default_sysconfdir)
3640
3741 # replace @libexecdir@
3842 configure_file(
5761 endif
5862
5963 if get_option('enable-systemd')
60 # replace @localstatedir@ and @bootdir@
64 # replace @localstatedir@, @sysconfdir@ and @bootdir@
6165 configure_file(
6266 input : 'fwupd.service.in',
6367 output : 'fwupd.service',
33 These are the steps to add vendor that is installed as part of an OSTree image:
44
55 * Change `/etc/fwupd/remotes.d/vendor.conf` to have `Enabled=true`
6 * Change `/etc/fwupd/remotes.d/vendor.conf` to have the correct `Title`
67 * Deploy the firmware to `/usr/share/fwupd/remotes.d/vendor/firmware`
78 * Deploy the metadata to `/usr/share/fwupd/remotes.d/vendor/vendor.xml`
89
11
22 # this remote provides metadata shipped with the fwupd package
33 Enabled=true
4 Title=Core
45 Keyring=none
56 MetadataURI=file://@datadir@/fwupd/remotes.d/fwupd/metadata.xml
11
22 # this remote provides metadata and firmware marked as 'testing' from the LVFS
33 Enabled=false
4 Title=Linux Vendor Firmware Service (testing)
45 Keyring=gpg
56 MetadataURI=https://s3.amazonaws.com/lvfsbucket/downloads/firmware-testing.xml.gz
67 Username=
11
22 # this remote provides metadata and firmware marked as 'stable' from the LVFS
33 Enabled=true
4 Title=Linux Vendor Firmware Service
45 Keyring=gpg
56 MetadataURI=https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz
67 OrderBefore=fwupd
22 # this remote provides metadata shipped by the OS vendor and can be found in
33 # /usr/share/fwupd/remotes.d/vendor and /usr/share/fwupd/remotes.d/vendor/firmware
44 Enabled=false
5 Title=Vendor
56 Keyring=none
67 MetadataURI=file://@datadir@/fwupd/remotes.d/vendor/vendor.xml.gz
Binary diff not shown
0 [fwupd Remote]
1 Enabled=true
2 MetadataURI=file:///tmp/fwupd-self-test/broken.xml.gz
0 [fwupd Remote]
1 Enabled=true
2 MetadataURI=file:///tmp/fwupd-self-test/stable.xml
0 [fwupd Remote]
1 Enabled=true
2 MetadataURI=file:///tmp/fwupd-self-test/testing.xml
4747 udev,
4848 valgrind[!mips !sparc64 !sh4 !ppc64 !powerpcspe !hppa !alpha !mips64el !armhf !armel !mipsel !m68k],
4949 systemd (>= 231)
50 Standards-Version: 4.0.0
50 Standards-Version: 4.1.0
5151 Section: admin
5252 Homepage: https://github.com/hughsie/fwupd
5353 Vcs-Git: https://anonscm.debian.org/git/uefi/fwupd.git
5454 Vcs-Browser: https://anonscm.debian.org/gitweb/?p=uefi/fwupd.git
5555
56 Package: libfwupd1
56 Package: libfwupd2
57 Section: libs
5758 Architecture: linux-any
5859 Depends: ${misc:Depends},
5960 ${shlibs:Depends}
6869 .
6970 This package provides the library used by the daemon.
7071
71 Package: libdfu1
72 Architecture: linux-any
73 Depends: ${misc:Depends},
74 ${gir:Depends},
75 ${shlibs:Depends}
76 Multi-Arch: same
77 Description: Firmware update daemon library for DFU support
78 fwupd is a daemon to allow session software to update device firmware.
79 You can either use a GUI software manager like GNOME Software to view and
80 apply updates, the command-line tool or the system D-Bus interface directly.
81 Currently, firmware updates using the UEFI capsule format and for the
82 ColorHug are supported. More formats may be supported in the future.
83 See <https://github.com/hughsie/fwupd> for details
84 .
85 This package provides the library used by the daemon for DFU support.
86
87 Package: libebitdo1
88 Architecture: linux-any
89 Depends: ${misc:Depends}
90 Multi-Arch: same
91 Priority: extra
92 Section: oldlibs
93 Description: Firmware update daemon library for 0bitdo support (transitional package)
94 This is a transitional package for 0bitdo support that was moved into a plugin.
95
9672 Package: fwupd
9773 Architecture: linux-any
9874 Depends: ${misc:Depends},
9975 ${shlibs:Depends}
10076 Recommends: fwupdate,
10177 python3
78 Breaks: gir1.2-dfu-1.0 (<< 0.9.7-1),
79 libdfu1 (<< 0.9.7-1),
80 libdfu-dev (<< 0.9.7-1)
81 Replaces: gir1.2-dfu-1.0 (<< 0.9.7-1),
82 libdfu1 (<< 0.9.7-1),
83 libdfu-dev (<< 0.9.7-1)
10284 Multi-Arch: foreign
10385 Description: Firmware update daemon
10486 fwupd is a daemon to allow session software to update device firmware.
152134 Package: libfwupd-dev
153135 Architecture: linux-any
154136 Multi-Arch: same
155 Depends: libfwupd1 (= ${binary:Version}),
156 gir1.2-fwupd-1.0 (= ${binary:Version}),
157 gir1.2-dfu-1.0 (= ${binary:Version}),
137 Depends: libfwupd2 (= ${binary:Version}),
138 gir1.2-fwupd-2.0 (= ${binary:Version}),
158139 ${misc:Depends}
159140 Breaks: fwupd-dev (<< 0.5.4-2~)
160141 Replaces: fwupd-dev (<< 0.5.4-2~)
169150 .
170151 This package provides the development files for libfwupd
171152
172 Package: gir1.2-fwupd-1.0
153 Package: gir1.2-fwupd-2.0
173154 Architecture: linux-any
174155 Multi-Arch: same
175156 Depends: ${misc:Depends},
176157 ${gir:Depends}
177 Breaks: libfwupd1 (<< 0.7.2-1~)
178 Replaces: libfwupd1 (<< 0.7.2-1~)
179158 Section: introspection
180159 Description: GObject introspection data for libfwupd
181160 This package provides the introspection data for libfwupd.
182161 .
183162 It can be used by packages using the GIRepository format to generate
184163 dynamic bindings.
185
186 Package: gir1.2-dfu-1.0
187 Architecture: linux-any
188 Multi-Arch: same
189 Depends: ${misc:Depends},
190 ${gir:Depends}
191 Breaks: libdfu1 (<< 0.9.5-1~)
192 Replaces: libdfu1 (<< 0.9.5-1~)
193 Section: introspection
194 Description: GObject introspection data for libdfu
195 This package provides the introspection data for libdfu.
196 .
197 It can be used by packages using the GIRepository format to generate
198 dynamic bindings.
199
200 Package: libdfu-dev
201 Architecture: linux-any
202 Multi-Arch: same
203 Depends: libdfu1 (= ${binary:Version}),
204 gir1.2-dfu-1.0 (= ${binary:Version}),
205 ${misc:Depends}
206 Section: libdevel
207 Description: development files for libdfu
208 fwupd is a daemon to allow session software to update device firmware.
209 You can either use a GUI software manager like GNOME Software to view and
210 apply updates, the command-line tool or the system D-Bus interface directly.
211 Currently, firmware updates using the UEFI capsule format and for the
212 ColorHug are supported. More formats may be supported in the future.
213 See <https://github.com/hughsie/fwupd> for details
214 .
215 This package provides the development files for libdfu
216
217 Package: libebitdo-dev
218 Architecture: linux-any
219 Multi-Arch: same
220 Depends: ${misc:Depends}
221 Priority: extra
222 Section: oldlibs
223 Description: development files for libebitdo (transitional package)
224 This is a transitional package for the 0bitdo support development patckage
225 that was moved into a plugin.
22 #find them. for more information see:
33 #https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872458
44 usr/share/installed-tests/*
5 usr/lib/*/fwupd-plugins-2/libfu_plugin_test.so
5 usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so
44
55 #only enable on installation not upgrade
66 if [ "$1" = configure ] && [ -z "$2" ]; then
7 if [ -f /etc/fwupd.conf ]; then
7 if [ -f /etc/fwupd/daemon.conf ]; then
88 if [ "$CI" = "true" ]; then
9 sed "s,^EnableTestSuite=.*,EnableTestSuite=true," -i /etc/fwupd.conf
9 sed "s,^BlacklistPlugins=test,BlacklistPlugins=," -i /etc/fwupd/daemon.conf
1010 else
11 echo "To enable test suite, modify /etc/fwupd.conf"
11 echo "To enable test suite, modify /etc/fwupd/daemon.conf"
1212 fi
1313 fi
1414 fi
33 #DEBHELPER#
44
55 if [ "$1" = remove -o "$1" = purge ]; then
6 if [ -f /etc/fwupd.conf ]; then
6 if [ -f /etc/fwupd/daemon.conf ]; then
77 if [ "$CI" = "true" ]; then
8 sed "s,^EnableTestSuite=.*,EnableTestSuite=false," -i /etc/fwupd.conf
8 sed "s,^BlacklistPlugins=,BlacklistPlugins=test," -i /etc/fwupd/daemon.conf
99 else
10 echo "To disable test suite, modify /etc/fwupd.conf"
10 echo "To disable test suite, modify /etc/fwupd/daemon.conf"
1111 fi
1212 fi
1313 fi
1010 lib/systemd/system/*
1111 var/lib/fwupd
1212 lib/udev/rules.d/*
13 data/fwupd.conf etc
13 data/daemon.conf etc/fwupd
1414 debian/fwupd.pkla /var/lib/polkit-1/localauthority/10-vendor.d
1515 usr/lib/*/fwupd-plugins-*/*.so
1616 debian/lintian/fwupd usr/share/lintian/overrides
0 #!/bin/sh
1 set -e
2
3 #DEBHELPER#
4
5 if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
6 dpkg-maintscript-helper rm_conffile \
7 /etc/fwupd.conf 1.0.0~ -- "$@"
8 fi
66 rm -rf /var/lib/fwupd/gnupg
77 rm -f /var/cache/app-info/xmls/fwupd.xml
88 fi
9
10 if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
11 dpkg-maintscript-helper rm_conffile \
12 /etc/fwupd.conf 1.0.0~ -- "$@"
13 fi
0 #!/bin/sh
1 set -e
2
3 #DEBHELPER#
4
5 if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
6 dpkg-maintscript-helper rm_conffile \
7 /etc/fwupd.conf 1.0.0~ -- "$@"
8 fi
+0
-1
debian/gir1.2-dfu-1.0.install less more
0 usr/lib/*/girepository-1.0/Dfu-1.0.typelib
+0
-1
debian/gir1.2-fwupd-1.0.install less more
0 usr/lib/*/girepository-1.0/Fwupd-1.0.typelib
0 usr/lib/*/girepository-1.0/Fwupd-2.0.typelib
+0
-5
debian/libdfu-dev.install less more
0 usr/include/libdfu/*
1 usr/include/dfu.h
2 usr/lib/*/libdfu*.so
3 usr/lib/*/pkgconfig/dfu.pc
4 usr/share/gir-1.0/Dfu*.gir
+0
-2
debian/libdfu1.install less more
0 usr/lib/*/libdfu*.so.*
1
+0
-164
debian/libdfu1.symbols less more
0 libdfu.so.1 libdfu1 #MINVER#
1 dfu_action_to_string@Base 0.7.5
2 dfu_cipher_decrypt_devo@Base 0.7.3
3 dfu_cipher_decrypt_xtea@Base 0.7.3
4 dfu_cipher_encrypt_devo@Base 0.7.3
5 dfu_cipher_encrypt_xtea@Base 0.7.3
6 dfu_cipher_kind_to_string@Base 0.6.3
7 dfu_context_enumerate@Base 0.6.3
8 dfu_context_get_device_by_platform_id@Base 0.6.3
9 dfu_context_get_device_by_vid_pid@Base 0.6.3
10 dfu_context_get_device_default@Base 0.6.3
11 dfu_context_get_devices@Base 0.6.3
12 dfu_context_get_timeout@Base 0.6.3
13 dfu_context_get_type@Base 0.6.3
14 dfu_context_new@Base 0.6.3
15 dfu_context_new_with_context@Base 0.8.0
16 dfu_context_set_timeout@Base 0.6.3
17 dfu_device_abort@Base 0.6.3
18 dfu_device_attach@Base 0.6.3
19 dfu_device_can_download@Base 0.6.3
20 dfu_device_can_upload@Base 0.6.3
21 dfu_device_clear_status@Base 0.6.3
22 dfu_device_close@Base 0.6.3
23 dfu_device_detach@Base 0.6.3
24 dfu_device_download@Base 0.6.3
25 dfu_device_ensure_interface@Base 0.7.2
26 dfu_device_error_fixup@Base 0.6.3
27 dfu_device_get_display_name@Base 0.6.3
28 dfu_device_get_download_timeout@Base 0.6.3
29 dfu_device_get_interface@Base 0.6.3
30 dfu_device_get_mode@Base 0.6.3
31 dfu_device_get_platform_id@Base 0.6.3
32 dfu_device_get_quirks_as_string@Base 0.6.3
33 dfu_device_get_runtime_pid@Base 0.6.3
34 dfu_device_get_runtime_release@Base 0.6.3
35 dfu_device_get_runtime_vid@Base 0.6.3
36 dfu_device_get_serial_number@Base 0.7.3
37 dfu_device_get_state@Base 0.6.3
38 dfu_device_get_status@Base 0.6.3
39 dfu_device_get_target_by_alt_name@Base 0.6.3
40 dfu_device_get_target_by_alt_setting@Base 0.6.3
41 dfu_device_get_targets@Base 0.6.3
42 dfu_device_get_timeout@Base 0.6.3
43 dfu_device_get_transfer_size@Base 0.6.3
44 dfu_device_get_type@Base 0.6.3
45 dfu_device_get_usb_dev@Base 0.6.3
46 dfu_device_get_version@Base 0.7.2
47 dfu_device_has_attribute@Base 0.6.3
48 dfu_device_has_dfuse_support@Base 0.6.3
49 dfu_device_has_quirk@Base 0.6.3
50 dfu_device_new@Base 0.6.3
51 dfu_device_open@Base 0.6.3
52 dfu_device_refresh@Base 0.6.3
53 dfu_device_reset@Base 0.6.3
54 dfu_device_set_new_usb_dev@Base 0.6.3
55 dfu_device_set_timeout@Base 0.6.3
56 dfu_device_set_transfer_size@Base 0.6.3
57 dfu_device_upload@Base 0.6.3
58 dfu_device_wait_for_replug@Base 0.6.3
59 dfu_element_get_address@Base 0.6.3
60 dfu_element_get_contents@Base 0.6.3
61 dfu_element_get_type@Base 0.6.3
62 dfu_element_new@Base 0.6.3
63 dfu_element_set_address@Base 0.6.3
64 dfu_element_set_contents@Base 0.6.3
65 dfu_element_set_padding_value@Base 0.7.3
66 dfu_element_set_target_size@Base 0.6.3
67 dfu_element_to_string@Base 0.6.3
68 dfu_error_quark@Base 0.6.3
69 dfu_firmware_add_image@Base 0.6.3
70 dfu_firmware_add_symbol@Base 0.7.4
71 dfu_firmware_detect_dfu@Base 0.7.3
72 dfu_firmware_detect_elf@Base 0.7.3
73 dfu_firmware_detect_ihex@Base 0.7.3
74 dfu_firmware_detect_raw@Base 0.7.3
75 dfu_firmware_format_from_string@Base 0.7.3
76 dfu_firmware_format_to_string@Base 0.6.3
77 dfu_firmware_from_dfu@Base 0.7.3
78 dfu_firmware_from_dfuse@Base 0.7.3
79 dfu_firmware_from_elf@Base 0.7.3
80 dfu_firmware_from_ihex@Base 0.7.3
81 dfu_firmware_from_metadata@Base 0.7.3
82 dfu_firmware_from_raw@Base 0.7.3
83 dfu_firmware_get_cipher_kind@Base 0.6.3
84 dfu_firmware_get_format@Base 0.6.3
85 dfu_firmware_get_image@Base 0.6.3
86 dfu_firmware_get_image_by_name@Base 0.6.3
87 dfu_firmware_get_image_default@Base 0.6.3
88 dfu_firmware_get_images@Base 0.6.3
89 dfu_firmware_get_metadata@Base 0.6.3
90 dfu_firmware_get_metadata_table@Base 0.7.3
91 dfu_firmware_get_pid@Base 0.6.3
92 dfu_firmware_get_release@Base 0.6.3
93 dfu_firmware_get_size@Base 0.6.3
94 dfu_firmware_get_symbols@Base 0.7.4
95 dfu_firmware_get_type@Base 0.6.3
96 dfu_firmware_get_vid@Base 0.6.3
97 dfu_firmware_lookup_symbol@Base 0.7.4
98 dfu_firmware_new@Base 0.6.3
99 dfu_firmware_parse_data@Base 0.6.3
100 dfu_firmware_parse_file@Base 0.6.3
101 dfu_firmware_remove_metadata@Base 0.6.3
102 dfu_firmware_set_cipher_kind@Base 0.7.3
103 dfu_firmware_set_format@Base 0.6.3
104 dfu_firmware_set_metadata@Base 0.6.3
105 dfu_firmware_set_pid@Base 0.6.3
106 dfu_firmware_set_release@Base 0.6.3
107 dfu_firmware_set_vid@Base 0.6.3
108 dfu_firmware_to_dfu@Base 0.7.3
109 dfu_firmware_to_dfuse@Base 0.7.3
110 dfu_firmware_to_elf@Base 0.7.3
111 dfu_firmware_to_ihex@Base 0.7.3
112 dfu_firmware_to_metadata@Base 0.7.3
113 dfu_firmware_to_raw@Base 0.7.3
114 dfu_firmware_to_string@Base 0.6.3
115 dfu_firmware_write_data@Base 0.6.3
116 dfu_firmware_write_file@Base 0.6.3
117 dfu_image_add_element@Base 0.6.3
118 dfu_image_get_alt_setting@Base 0.6.3
119 dfu_image_get_element@Base 0.6.3
120 dfu_image_get_element_default@Base 0.7.0
121 dfu_image_get_elements@Base 0.6.3
122 dfu_image_get_name@Base 0.6.3
123 dfu_image_get_size@Base 0.6.3
124 dfu_image_get_type@Base 0.6.3
125 dfu_image_new@Base 0.6.3
126 dfu_image_set_alt_setting@Base 0.6.3
127 dfu_image_set_name@Base 0.6.3
128 dfu_image_to_string@Base 0.6.3
129 dfu_mode_to_string@Base 0.6.3
130 dfu_patch_apply@Base 0.9.6
131 dfu_patch_create@Base 0.9.6
132 dfu_patch_export@Base 0.9.6
133 dfu_patch_get_checksum_new@Base 0.9.6
134 dfu_patch_get_checksum_old@Base 0.9.6
135 dfu_patch_get_type@Base 0.9.6
136 dfu_patch_import@Base 0.9.6
137 dfu_patch_new@Base 0.9.6
138 dfu_patch_to_string@Base 0.9.6
139 dfu_sector_get_address@Base 0.6.3
140 dfu_sector_get_id@Base 0.6.3
141 dfu_sector_get_number@Base 0.7.5
142 dfu_sector_get_size@Base 0.6.3
143 dfu_sector_get_size_left@Base 0.6.3
144 dfu_sector_get_type@Base 0.6.3
145 dfu_sector_get_zone@Base 0.7.5
146 dfu_sector_has_cap@Base 0.6.3
147 dfu_sector_new@Base 0.6.3
148 dfu_sector_to_string@Base 0.6.3
149 dfu_state_to_string@Base 0.6.3
150 dfu_status_to_string@Base 0.6.3
151 dfu_target_download@Base 0.6.3
152 dfu_target_download_chunk@Base 0.7.5
153 dfu_target_get_alt_name@Base 0.6.3
154 dfu_target_get_alt_name_for_display@Base 0.7.5
155 dfu_target_get_alt_setting@Base 0.6.3
156 dfu_target_get_cipher_kind@Base 0.6.3
157 dfu_target_get_sectors@Base 0.6.3
158 dfu_target_get_type@Base 0.6.3
159 dfu_target_new@Base 0.6.3
160 dfu_target_parse_sectors@Base 0.6.3
161 dfu_target_upload@Base 0.6.3
162 dfu_target_upload_chunk@Base 0.6.3
163 dfu_version_to_string@Base 0.7.2
+0
-1
debian/libfwupd1.install less more
0 usr/lib/*/libfwup*.so.*
+0
-226
debian/libfwupd1.symbols less more
0 libfwupd.so.1 libfwupd1 #MINVER#
1 fwupd_checksum_format_for_display@Base 0.9.3
2 fwupd_checksum_get_best@Base 0.9.3
3 fwupd_checksum_get_by_kind@Base 0.9.3
4 fwupd_checksum_guess_kind@Base 0.9.3
5 fwupd_client_clear_results@Base 0.7.0
6 fwupd_client_connect@Base 0.7.2
7 fwupd_client_get_daemon_version@Base 0.9.6
8 fwupd_client_get_details@Base 0.7.0
9 fwupd_client_get_details_local@Base 0.7.2
10 fwupd_client_get_device_by_id@Base 0.9.3
11 fwupd_client_get_devices@Base 0.7.0
12 fwupd_client_get_devices_simple@Base 0.9.3
13 fwupd_client_get_percentage@Base 0.7.3
14 fwupd_client_get_releases@Base 0.9.3
15 fwupd_client_get_remote_by_id@Base 0.9.3
16 fwupd_client_get_remotes@Base 0.9.3
17 fwupd_client_get_results@Base 0.7.0
18 fwupd_client_get_status@Base 0.7.3
19 fwupd_client_get_type@Base 0.7.0
20 fwupd_client_get_updates@Base 0.7.0
21 fwupd_client_install@Base 0.7.0
22 fwupd_client_new@Base 0.7.0
23 fwupd_client_unlock@Base 0.7.0
24 fwupd_client_update_metadata@Base 0.7.0
25 fwupd_client_update_metadata_with_id@Base 0.9.3
26 fwupd_client_verify@Base 0.7.0
27 fwupd_client_verify_update@Base 0.8.0
28 fwupd_device_add_checksum@Base 0.9.3
29 fwupd_device_add_flag@Base 0.9.3
30 fwupd_device_add_guid@Base 0.9.3
31 fwupd_device_flag_from_string@Base 0.7.0
32 fwupd_device_flag_to_string@Base 0.7.0
33 fwupd_device_from_key_value@Base 0.9.3
34 fwupd_device_get_checksums@Base 0.9.3
35 fwupd_device_get_created@Base 0.9.3
36 fwupd_device_get_description@Base 0.9.3
37 fwupd_device_get_flags@Base 0.9.3
38 fwupd_device_get_flashes_left@Base 0.9.3
39 fwupd_device_get_guid_default@Base 0.9.3
40 fwupd_device_get_guids@Base 0.9.3
41 fwupd_device_get_id@Base 0.9.3
42 fwupd_device_get_modified@Base 0.9.3
43 fwupd_device_get_name@Base 0.9.3
44 fwupd_device_get_provider@Base 0.9.3
45 fwupd_device_get_summary@Base 0.9.3
46 fwupd_device_get_type@Base 0.9.3
47 fwupd_device_get_vendor@Base 0.9.3
48 fwupd_device_get_vendor_id@Base 0.9.3
49 fwupd_device_get_version@Base 0.9.3
50 fwupd_device_get_version_bootloader@Base 0.9.3
51 fwupd_device_get_version_lowest@Base 0.9.3
52 fwupd_device_has_flag@Base 0.9.3
53 fwupd_device_has_guid@Base 0.9.3
54 fwupd_device_new@Base 0.9.3
55 fwupd_device_new_from_data@Base 0.9.3
56 fwupd_device_remove_flag@Base 0.9.3
57 fwupd_device_set_created@Base 0.9.3
58 fwupd_device_set_description@Base 0.9.3
59 fwupd_device_set_flags@Base 0.9.3
60 fwupd_device_set_flashes_left@Base 0.9.3
61 fwupd_device_set_id@Base 0.9.3
62 fwupd_device_set_modified@Base 0.9.3
63 fwupd_device_set_name@Base 0.9.3
64 fwupd_device_set_provider@Base 0.9.3
65 fwupd_device_set_summary@Base 0.9.3
66 fwupd_device_set_vendor@Base 0.9.3
67 fwupd_device_set_vendor_id@Base 0.9.3
68 fwupd_device_set_version@Base 0.9.3
69 fwupd_device_set_version_bootloader@Base 0.9.3
70 fwupd_device_set_version_lowest@Base 0.9.3
71 fwupd_device_to_data@Base 0.9.3
72 fwupd_device_to_string@Base 0.9.3
73 fwupd_device_to_variant_builder@Base 0.9.3
74 fwupd_error_from_string@Base 0.7.0
75 fwupd_error_quark@Base 0.6.3
76 fwupd_error_to_string@Base 0.7.0
77 fwupd_keyring_kind_from_string@Base 0.9.7
78 fwupd_keyring_kind_to_string@Base 0.9.7
79 fwupd_release_add_checksum@Base 0.9.3
80 fwupd_release_from_key_value@Base 0.9.3
81 fwupd_release_get_appstream_id@Base 0.9.3
82 fwupd_release_get_checksums@Base 0.9.3
83 fwupd_release_get_description@Base 0.9.3
84 fwupd_release_get_filename@Base 0.9.3
85 fwupd_release_get_homepage@Base 0.9.3
86 fwupd_release_get_license@Base 0.9.3
87 fwupd_release_get_name@Base 0.9.3
88 fwupd_release_get_remote_id@Base 0.9.3
89 fwupd_release_get_size@Base 0.9.3
90 fwupd_release_get_summary@Base 0.9.3
91 fwupd_release_get_type@Base 0.9.3
92 fwupd_release_get_uri@Base 0.9.3
93 fwupd_release_get_vendor@Base 0.9.3
94 fwupd_release_get_version@Base 0.9.3
95 fwupd_release_new@Base 0.9.3
96 fwupd_release_new_from_data@Base 0.9.3
97 fwupd_release_set_appstream_id@Base 0.9.3
98 fwupd_release_set_description@Base 0.9.3
99 fwupd_release_set_filename@Base 0.9.3
100 fwupd_release_set_homepage@Base 0.9.3
101 fwupd_release_set_license@Base 0.9.3
102 fwupd_release_set_name@Base 0.9.3
103 fwupd_release_set_remote_id@Base 0.9.3
104 fwupd_release_set_size@Base 0.9.3
105 fwupd_release_set_summary@Base 0.9.3
106 fwupd_release_set_uri@Base 0.9.3
107 fwupd_release_set_vendor@Base 0.9.3
108 fwupd_release_set_version@Base 0.9.3
109 fwupd_release_to_data@Base 0.9.3
110 fwupd_release_to_string@Base 0.9.3
111 fwupd_release_to_variant_builder@Base 0.9.3
112 fwupd_remote_build_firmware_uri@Base 0.9.7
113 fwupd_remote_build_uri@Base 0.9.3
114 fwupd_remote_get_age@Base 0.9.5
115 fwupd_remote_get_enabled@Base 0.9.3
116 fwupd_remote_get_filename@Base 0.9.3
117 fwupd_remote_get_filename_asc@Base 0.9.3
118 fwupd_remote_get_filename_cache@Base 0.9.5
119 fwupd_remote_get_filename_cache_sig@Base 0.9.7
120 fwupd_remote_get_firmware_base_uri@Base 0.9.7
121 fwupd_remote_get_id@Base 0.9.3
122 fwupd_remote_get_keyring_kind@Base 0.9.7
123 fwupd_remote_get_kind@Base 0.9.6
124 fwupd_remote_get_metadata_uri@Base 0.9.7
125 fwupd_remote_get_metadata_uri_sig@Base 0.9.7
126 fwupd_remote_get_order_after@Base 0.9.5
127 fwupd_remote_get_order_before@Base 0.9.5
128 fwupd_remote_get_password@Base 0.9.5
129 fwupd_remote_get_priority@Base 0.9.5
130 fwupd_remote_get_type@Base 0.9.3
131 fwupd_remote_get_uri@Base 0.9.3
132 fwupd_remote_get_uri_asc@Base 0.9.3
133 fwupd_remote_get_username@Base 0.9.5
134 fwupd_remote_kind_from_string@Base 0.9.6
135 fwupd_remote_kind_to_string@Base 0.9.6
136 fwupd_remote_load_from_filename@Base 0.9.3
137 fwupd_remote_new@Base 0.9.3
138 fwupd_remote_new_from_data@Base 0.9.5
139 fwupd_remote_set_mtime@Base 0.9.5
140 fwupd_remote_set_priority@Base 0.9.5
141 fwupd_remote_to_data@Base 0.9.5
142 fwupd_result_add_device_flag@Base 0.7.0
143 fwupd_result_add_guid@Base 0.7.2
144 fwupd_result_get_device@Base 0.9.3
145 fwupd_result_get_device_checksum@Base 0.7.0
146 fwupd_result_get_device_checksum_kind@Base 0.7.0
147 fwupd_result_get_device_created@Base 0.7.0
148 fwupd_result_get_device_description@Base 0.7.0
149 fwupd_result_get_device_flags@Base 0.7.0
150 fwupd_result_get_device_flashes_left@Base 0.7.2
151 fwupd_result_get_device_id@Base 0.7.0
152 fwupd_result_get_device_modified@Base 0.7.0
153 fwupd_result_get_device_name@Base 0.7.0
154 fwupd_result_get_device_provider@Base 0.7.0
155 fwupd_result_get_device_vendor@Base 0.7.0
156 fwupd_result_get_device_version@Base 0.7.0
157 fwupd_result_get_device_version_bootloader@Base 0.8.0
158 fwupd_result_get_device_version_lowest@Base 0.7.0
159 fwupd_result_get_guid@Base 0.7.0
160 fwupd_result_get_guid_default@Base 0.7.2
161 fwupd_result_get_guids@Base 0.7.2
162 fwupd_result_get_release@Base 0.9.3
163 fwupd_result_get_type@Base 0.7.0
164 fwupd_result_get_unique_id@Base 0.7.3
165 fwupd_result_get_update_checksum@Base 0.7.0
166 fwupd_result_get_update_checksum_kind@Base 0.7.0
167 fwupd_result_get_update_description@Base 0.7.0
168 fwupd_result_get_update_error@Base 0.7.0
169 fwupd_result_get_update_filename@Base 0.7.0
170 fwupd_result_get_update_homepage@Base 0.7.0
171 fwupd_result_get_update_id@Base 0.7.0
172 fwupd_result_get_update_license@Base 0.7.0
173 fwupd_result_get_update_name@Base 0.7.0
174 fwupd_result_get_update_size@Base 0.7.0
175 fwupd_result_get_update_state@Base 0.7.0
176 fwupd_result_get_update_summary@Base 0.7.0
177 fwupd_result_get_update_trust_flags@Base 0.7.0
178 fwupd_result_get_update_uri@Base 0.7.0
179 fwupd_result_get_update_vendor@Base 0.7.0
180 fwupd_result_get_update_version@Base 0.7.0
181 fwupd_result_has_device_flag@Base 0.7.0
182 fwupd_result_has_guid@Base 0.7.2
183 fwupd_result_new@Base 0.7.0
184 fwupd_result_new_from_data@Base 0.7.0
185 fwupd_result_remove_device_flag@Base 0.7.3
186 fwupd_result_set_device_checksum@Base 0.7.0
187 fwupd_result_set_device_checksum_kind@Base 0.7.0
188 fwupd_result_set_device_created@Base 0.7.0
189 fwupd_result_set_device_description@Base 0.7.0
190 fwupd_result_set_device_flags@Base 0.7.0
191 fwupd_result_set_device_flashes_left@Base 0.7.2
192 fwupd_result_set_device_id@Base 0.7.0
193 fwupd_result_set_device_modified@Base 0.7.0
194 fwupd_result_set_device_name@Base 0.7.0
195 fwupd_result_set_device_provider@Base 0.7.0
196 fwupd_result_set_device_vendor@Base 0.7.0
197 fwupd_result_set_device_version@Base 0.7.0
198 fwupd_result_set_device_version_bootloader@Base 0.8.0
199 fwupd_result_set_device_version_lowest@Base 0.7.0
200 fwupd_result_set_guid@Base 0.7.0
201 fwupd_result_set_unique_id@Base 0.7.3
202 fwupd_result_set_update_checksum@Base 0.7.0
203 fwupd_result_set_update_checksum_kind@Base 0.7.0
204 fwupd_result_set_update_description@Base 0.7.0
205 fwupd_result_set_update_error@Base 0.7.0
206 fwupd_result_set_update_filename@Base 0.7.0
207 fwupd_result_set_update_homepage@Base 0.7.0
208 fwupd_result_set_update_id@Base 0.7.0
209 fwupd_result_set_update_license@Base 0.7.0
210 fwupd_result_set_update_name@Base 0.7.0
211 fwupd_result_set_update_size@Base 0.7.0
212 fwupd_result_set_update_state@Base 0.7.0
213 fwupd_result_set_update_summary@Base 0.7.0
214 fwupd_result_set_update_trust_flags@Base 0.7.0
215 fwupd_result_set_update_uri@Base 0.7.0
216 fwupd_result_set_update_vendor@Base 0.7.0
217 fwupd_result_set_update_version@Base 0.7.0
218 fwupd_result_to_data@Base 0.7.0
219 fwupd_result_to_string@Base 0.7.0
220 fwupd_status_from_string@Base 0.6.3
221 fwupd_status_to_string@Base 0.6.3
222 fwupd_trust_flag_from_string@Base 0.7.0
223 fwupd_trust_flag_to_string@Base 0.7.0
224 fwupd_update_state_from_string@Base 0.7.0
225 fwupd_update_state_to_string@Base 0.7.0
0 usr/lib/*/libfwup*.so.*
0 libfwupd.so.1 libfwupd1 #MINVER#
1 fwupd_checksum_format_for_display@Base 0.9.3
2 fwupd_checksum_get_best@Base 0.9.3
3 fwupd_checksum_get_by_kind@Base 0.9.3
4 fwupd_checksum_guess_kind@Base 0.9.3
5 fwupd_client_clear_results@Base 0.7.0
6 fwupd_client_connect@Base 0.7.2
7 fwupd_client_get_daemon_version@Base 0.9.6
8 fwupd_client_get_details@Base 0.7.0
9 fwupd_client_get_details_local@Base 0.7.2
10 fwupd_client_get_device_by_id@Base 0.9.3
11 fwupd_client_get_devices@Base 0.7.0
12 fwupd_client_get_devices_simple@Base 0.9.3
13 fwupd_client_get_percentage@Base 0.7.3
14 fwupd_client_get_releases@Base 0.9.3
15 fwupd_client_get_remote_by_id@Base 0.9.3
16 fwupd_client_get_remotes@Base 0.9.3
17 fwupd_client_get_results@Base 0.7.0
18 fwupd_client_get_status@Base 0.7.3
19 fwupd_client_get_type@Base 0.7.0
20 fwupd_client_get_updates@Base 0.7.0
21 fwupd_client_install@Base 0.7.0
22 fwupd_client_new@Base 0.7.0
23 fwupd_client_unlock@Base 0.7.0
24 fwupd_client_update_metadata@Base 0.7.0
25 fwupd_client_update_metadata_with_id@Base 0.9.3
26 fwupd_client_verify@Base 0.7.0
27 fwupd_client_verify_update@Base 0.8.0
28 fwupd_device_add_checksum@Base 0.9.3
29 fwupd_device_add_flag@Base 0.9.3
30 fwupd_device_add_guid@Base 0.9.3
31 fwupd_device_flag_from_string@Base 0.7.0
32 fwupd_device_flag_to_string@Base 0.7.0
33 fwupd_device_from_key_value@Base 0.9.3
34 fwupd_device_get_checksums@Base 0.9.3
35 fwupd_device_get_created@Base 0.9.3
36 fwupd_device_get_description@Base 0.9.3
37 fwupd_device_get_flags@Base 0.9.3
38 fwupd_device_get_flashes_left@Base 0.9.3
39 fwupd_device_get_guid_default@Base 0.9.3
40 fwupd_device_get_guids@Base 0.9.3
41 fwupd_device_get_id@Base 0.9.3
42 fwupd_device_get_modified@Base 0.9.3
43 fwupd_device_get_name@Base 0.9.3
44 fwupd_device_get_provider@Base 0.9.3
45 fwupd_device_get_summary@Base 0.9.3
46 fwupd_device_get_type@Base 0.9.3
47 fwupd_device_get_vendor@Base 0.9.3
48 fwupd_device_get_vendor_id@Base 0.9.3
49 fwupd_device_get_version@Base 0.9.3
50 fwupd_device_get_version_bootloader@Base 0.9.3
51 fwupd_device_get_version_lowest@Base 0.9.3
52 fwupd_device_has_flag@Base 0.9.3
53 fwupd_device_has_guid@Base 0.9.3
54 fwupd_device_new@Base 0.9.3
55 fwupd_device_new_from_data@Base 0.9.3
56 fwupd_device_remove_flag@Base 0.9.3
57 fwupd_device_set_created@Base 0.9.3
58 fwupd_device_set_description@Base 0.9.3
59 fwupd_device_set_flags@Base 0.9.3
60 fwupd_device_set_flashes_left@Base 0.9.3
61 fwupd_device_set_id@Base 0.9.3
62 fwupd_device_set_modified@Base 0.9.3
63 fwupd_device_set_name@Base 0.9.3
64 fwupd_device_set_provider@Base 0.9.3
65 fwupd_device_set_summary@Base 0.9.3
66 fwupd_device_set_vendor@Base 0.9.3
67 fwupd_device_set_vendor_id@Base 0.9.3
68 fwupd_device_set_version@Base 0.9.3
69 fwupd_device_set_version_bootloader@Base 0.9.3
70 fwupd_device_set_version_lowest@Base 0.9.3
71 fwupd_device_to_data@Base 0.9.3
72 fwupd_device_to_string@Base 0.9.3
73 fwupd_device_to_variant_builder@Base 0.9.3
74 fwupd_error_from_string@Base 0.7.0
75 fwupd_error_quark@Base 0.6.3
76 fwupd_error_to_string@Base 0.7.0
77 fwupd_keyring_kind_from_string@Base 0.9.7
78 fwupd_keyring_kind_to_string@Base 0.9.7
79 fwupd_release_add_checksum@Base 0.9.3
80 fwupd_release_from_key_value@Base 0.9.3
81 fwupd_release_get_appstream_id@Base 0.9.3
82 fwupd_release_get_checksums@Base 0.9.3
83 fwupd_release_get_description@Base 0.9.3
84 fwupd_release_get_filename@Base 0.9.3
85 fwupd_release_get_homepage@Base 0.9.3
86 fwupd_release_get_license@Base 0.9.3
87 fwupd_release_get_name@Base 0.9.3
88 fwupd_release_get_remote_id@Base 0.9.3
89 fwupd_release_get_size@Base 0.9.3
90 fwupd_release_get_summary@Base 0.9.3
91 fwupd_release_get_type@Base 0.9.3
92 fwupd_release_get_uri@Base 0.9.3
93 fwupd_release_get_vendor@Base 0.9.3
94 fwupd_release_get_version@Base 0.9.3
95 fwupd_release_new@Base 0.9.3
96 fwupd_release_new_from_data@Base 0.9.3
97 fwupd_release_set_appstream_id@Base 0.9.3
98 fwupd_release_set_description@Base 0.9.3
99 fwupd_release_set_filename@Base 0.9.3
100 fwupd_release_set_homepage@Base 0.9.3
101 fwupd_release_set_license@Base 0.9.3
102 fwupd_release_set_name@Base 0.9.3
103 fwupd_release_set_remote_id@Base 0.9.3
104 fwupd_release_set_size@Base 0.9.3
105 fwupd_release_set_summary@Base 0.9.3
106 fwupd_release_set_uri@Base 0.9.3
107 fwupd_release_set_vendor@Base 0.9.3
108 fwupd_release_set_version@Base 0.9.3
109 fwupd_release_to_data@Base 0.9.3
110 fwupd_release_to_string@Base 0.9.3
111 fwupd_release_to_variant_builder@Base 0.9.3
112 fwupd_remote_build_firmware_uri@Base 0.9.7
113 fwupd_remote_build_uri@Base 0.9.3
114 fwupd_remote_get_age@Base 0.9.5
115 fwupd_remote_get_enabled@Base 0.9.3
116 fwupd_remote_get_filename@Base 0.9.3
117 fwupd_remote_get_filename_asc@Base 0.9.3
118 fwupd_remote_get_filename_cache@Base 0.9.5
119 fwupd_remote_get_filename_cache_sig@Base 0.9.7
120 fwupd_remote_get_firmware_base_uri@Base 0.9.7
121 fwupd_remote_get_id@Base 0.9.3
122 fwupd_remote_get_keyring_kind@Base 0.9.7
123 fwupd_remote_get_kind@Base 0.9.6
124 fwupd_remote_get_metadata_uri@Base 0.9.7
125 fwupd_remote_get_metadata_uri_sig@Base 0.9.7
126 fwupd_remote_get_order_after@Base 0.9.5
127 fwupd_remote_get_order_before@Base 0.9.5
128 fwupd_remote_get_password@Base 0.9.5
129 fwupd_remote_get_priority@Base 0.9.5
130 fwupd_remote_get_type@Base 0.9.3
131 fwupd_remote_get_uri@Base 0.9.3
132 fwupd_remote_get_uri_asc@Base 0.9.3
133 fwupd_remote_get_username@Base 0.9.5
134 fwupd_remote_kind_from_string@Base 0.9.6
135 fwupd_remote_kind_to_string@Base 0.9.6
136 fwupd_remote_load_from_filename@Base 0.9.3
137 fwupd_remote_new@Base 0.9.3
138 fwupd_remote_new_from_data@Base 0.9.5
139 fwupd_remote_set_mtime@Base 0.9.5
140 fwupd_remote_set_priority@Base 0.9.5
141 fwupd_remote_to_data@Base 0.9.5
142 fwupd_result_add_device_flag@Base 0.7.0
143 fwupd_result_add_guid@Base 0.7.2
144 fwupd_result_get_device@Base 0.9.3
145 fwupd_result_get_device_checksum@Base 0.7.0
146 fwupd_result_get_device_checksum_kind@Base 0.7.0
147 fwupd_result_get_device_created@Base 0.7.0
148 fwupd_result_get_device_description@Base 0.7.0
149 fwupd_result_get_device_flags@Base 0.7.0
150 fwupd_result_get_device_flashes_left@Base 0.7.2
151 fwupd_result_get_device_id@Base 0.7.0
152 fwupd_result_get_device_modified@Base 0.7.0
153 fwupd_result_get_device_name@Base 0.7.0
154 fwupd_result_get_device_provider@Base 0.7.0
155 fwupd_result_get_device_vendor@Base 0.7.0
156 fwupd_result_get_device_version@Base 0.7.0
157 fwupd_result_get_device_version_bootloader@Base 0.8.0
158 fwupd_result_get_device_version_lowest@Base 0.7.0
159 fwupd_result_get_guid@Base 0.7.0
160 fwupd_result_get_guid_default@Base 0.7.2
161 fwupd_result_get_guids@Base 0.7.2
162 fwupd_result_get_release@Base 0.9.3
163 fwupd_result_get_type@Base 0.7.0
164 fwupd_result_get_unique_id@Base 0.7.3
165 fwupd_result_get_update_checksum@Base 0.7.0
166 fwupd_result_get_update_checksum_kind@Base 0.7.0
167 fwupd_result_get_update_description@Base 0.7.0
168 fwupd_result_get_update_error@Base 0.7.0
169 fwupd_result_get_update_filename@Base 0.7.0
170 fwupd_result_get_update_homepage@Base 0.7.0
171 fwupd_result_get_update_id@Base 0.7.0
172 fwupd_result_get_update_license@Base 0.7.0
173 fwupd_result_get_update_name@Base 0.7.0
174 fwupd_result_get_update_size@Base 0.7.0
175 fwupd_result_get_update_state@Base 0.7.0
176 fwupd_result_get_update_summary@Base 0.7.0
177 fwupd_result_get_update_trust_flags@Base 0.7.0
178 fwupd_result_get_update_uri@Base 0.7.0
179 fwupd_result_get_update_vendor@Base 0.7.0
180 fwupd_result_get_update_version@Base 0.7.0
181 fwupd_result_has_device_flag@Base 0.7.0
182 fwupd_result_has_guid@Base 0.7.2
183 fwupd_result_new@Base 0.7.0
184 fwupd_result_new_from_data@Base 0.7.0
185 fwupd_result_remove_device_flag@Base 0.7.3
186 fwupd_result_set_device_checksum@Base 0.7.0
187 fwupd_result_set_device_checksum_kind@Base 0.7.0
188 fwupd_result_set_device_created@Base 0.7.0
189 fwupd_result_set_device_description@Base 0.7.0
190 fwupd_result_set_device_flags@Base 0.7.0
191 fwupd_result_set_device_flashes_left@Base 0.7.2
192 fwupd_result_set_device_id@Base 0.7.0
193 fwupd_result_set_device_modified@Base 0.7.0
194 fwupd_result_set_device_name@Base 0.7.0
195 fwupd_result_set_device_provider@Base 0.7.0
196 fwupd_result_set_device_vendor@Base 0.7.0
197 fwupd_result_set_device_version@Base 0.7.0
198 fwupd_result_set_device_version_bootloader@Base 0.8.0
199 fwupd_result_set_device_version_lowest@Base 0.7.0
200 fwupd_result_set_guid@Base 0.7.0
201 fwupd_result_set_unique_id@Base 0.7.3
202 fwupd_result_set_update_checksum@Base 0.7.0
203 fwupd_result_set_update_checksum_kind@Base 0.7.0
204 fwupd_result_set_update_description@Base 0.7.0
205 fwupd_result_set_update_error@Base 0.7.0
206 fwupd_result_set_update_filename@Base 0.7.0
207 fwupd_result_set_update_homepage@Base 0.7.0
208 fwupd_result_set_update_id@Base 0.7.0
209 fwupd_result_set_update_license@Base 0.7.0
210 fwupd_result_set_update_name@Base 0.7.0
211 fwupd_result_set_update_size@Base 0.7.0
212 fwupd_result_set_update_state@Base 0.7.0
213 fwupd_result_set_update_summary@Base 0.7.0
214 fwupd_result_set_update_trust_flags@Base 0.7.0
215 fwupd_result_set_update_uri@Base 0.7.0
216 fwupd_result_set_update_vendor@Base 0.7.0
217 fwupd_result_set_update_version@Base 0.7.0
218 fwupd_result_to_data@Base 0.7.0
219 fwupd_result_to_string@Base 0.7.0
220 fwupd_status_from_string@Base 0.6.3
221 fwupd_status_to_string@Base 0.6.3
222 fwupd_trust_flag_from_string@Base 0.7.0
223 fwupd_trust_flag_to_string@Base 0.7.0
224 fwupd_update_state_from_string@Base 0.7.0
225 fwupd_update_state_to_string@Base 0.7.0
66 #GPGME needs this for proper building on 32 bit archs
77 ifeq "$(DEB_HOST_ARCH_BITS)" "32"
88 export DEB_CFLAGS_MAINT_APPEND = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
9 endif
10
11 ifneq ($(CI),)
12 export CI=-Denable-werror=true
913 endif
1014
1115 %:
2529 else \
2630 export DELL="-Denable-dell=false -Denable-synaptics=false"; \
2731 fi; \
28 dh_auto_configure -- $$UEFI $$DELL -Denable-dummy=true --libexecdir=/usr/lib
32 dh_auto_configure -- $$UEFI $$DELL $$CI -Denable-dummy=true --libexecdir=/usr/lib
2933
3034 override_dh_install:
3135 find debian/tmp/usr -type f -name "*a" -print | xargs rm -f
3438 dh_missing --fail-missing
3539
3640 #this is placed in fwupd-tests
37 rm -f debian/fwupd/usr/lib/*/fwupd-plugins-2/libfu_plugin_test.so
41 rm -f debian/fwupd/usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so
3842
3943 override_dh_strip_nondeterminism:
4044 dh_strip_nondeterminism -Xfirmware-example.xml.gz
0 #this isn't used in any of the binaries, only for fuzz testing
1 #the interface for libdfu
2 fwupd source: source-is-missing libdfu/fuzzing/firmware.elf
3 fwupd source: source-contains-prebuilt-binary libdfu/fuzzing/firmware.elf
4
50 #github doesn't have these
61 fwupd source: debian-watch-may-check-gpg-signature
00 #!/bin/sh
11 set -e
2 service dbus restart
2 CI=true dpkg-reconfigure fwupd-tests
3 /usr/sbin/service dbus restart
34 gnome-desktop-testing-runner fwupd
+0
-6
docs/libdfu/clean.sh less more
0 rm -f *.txt
1 rm -rf html/
2 rm -rf xml/
3 rm -rf tmpl/
4 rm -f *.stamp
5
+0
-90
docs/libdfu/libdfu-docs.xml less more
0 <?xml version="1.0"?>
1 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
2 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
3 [
4 <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
5 ]>
6 <book id="index">
7 <bookinfo>
8 <title>libdfu Reference Manual</title>
9 </bookinfo>
10
11 <reference id="intro">
12 <title>About libdfu</title>
13 <partintro>
14 <para>
15 libdfu is a library for updating firmware on DFU-capable devices.
16 <ulink url="https://en.wikipedia.org/wiki/USB#DFU">DFU</ulink>
17 is a standardised protocol used on many millions of devices
18 to safely update device firmware by the user.
19 Is is designed to be easy to implement in device bootloaders and
20 also easy to support in native host drivers.
21 Flashing firmware using DFU is supported in Windows, Linux and OS-X.
22 </para>
23 <para>
24 Updating firmware on a device is typically done using
25 <ulink url="http://www.fwupd.org/">fwupd</ulink> or by a session
26 application like GNOME Software.
27 You can also use <ulink url="http://dfu-util.sourceforge.net/">dfu-util</ulink>
28 which may support mode device types than <command>dfu-tool</command>
29 supplied by fwupd.
30 </para>
31 <para>
32 <command>libdfu</command> provides a medium-level API which is
33 available for all languages that support GObject Introspection.
34 It supports cancellation using <varname>GCancellable</varname>
35 and erro reporting using <varname>GError</varname>.
36 To download a device using the API it is as simple as getting
37 a <varname>GUsbDevice</varname> and then doing something like
38 this:
39 </para>
40 <programlisting>
41 dfu_firmware = dfu_firmware_new ();
42 if (!dfu_firmware_parse_data (dfu_firmware, blob_fw,
43 DFU_FIRMWARE_PARSE_FLAG_NONE, error))
44 return FALSE;
45 dfu_device = dfu_device_new (dev);
46 if (!dfu_device_download (dfu_device, dfu_firmware,
47 DFU_TARGET_TRANSFER_FLAG_DETACH |
48 DFU_TARGET_TRANSFER_FLAG_VERIFY |
49 DFU_TARGET_TRANSFER_FLAG_BOOT_RUNTIME,
50 cancelleable,
51 _progress_cb, userdata,
52 error))
53 return FALSE;
54 </programlisting>
55 <para>
56 You can read more about DFU in the <ulink url="http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf">official specification</ulink>.
57 </para>
58 </partintro>
59 </reference>
60
61 <reference id="libdfu">
62 <title>libdfu</title>
63 <partintro>
64 <para>
65 Functionality exported by libdfu.
66 </para>
67 </partintro>
68 <xi:include href="xml/dfu-context.xml"/>
69 <xi:include href="xml/dfu-device.xml"/>
70 <xi:include href="xml/dfu-firmware.xml"/>
71 <xi:include href="xml/dfu-image.xml"/>
72 <xi:include href="xml/dfu-element.xml"/>
73 <xi:include href="xml/dfu-sector.xml"/>
74 <xi:include href="xml/dfu-target.xml"/>
75 <xi:include href="xml/dfu-common.xml"/>
76 <xi:include href="xml/dfu-error.xml"/>
77 </reference>
78
79 <index id="api-index-full">
80 <title>API Index</title>
81 <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
82 </index>
83
84 <index id="deprecated-api-index" role="deprecated">
85 <title>Index of deprecated API</title>
86 <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
87 </index>
88 <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
89 </book>
+0
-7
docs/libdfu/libdfu.types less more
0 dfu_context_get_type
1 dfu_device_get_type
2 dfu_element_get_type
3 dfu_firmware_get_type
4 dfu_image_get_type
5 dfu_target_get_type
6 dfu_sector_get_type
+0
-9
docs/libdfu/meson.build less more
0 gnome.gtkdoc(
1 'libdfu',
2 src_dir : [
3 join_paths(meson.source_root(), 'libdfu'),
4 join_paths(meson.build_root(), 'libdfu'),
5 ],
6 main_xml : 'libdfu-docs.xml',
7 install : true
8 )
+0
-1
docs/libfwupd/clean.sh less more
0 ../libdfu/clean.sh
0 rm -f *.txt
1 rm -rf html/
2 rm -rf xml/
3 rm -rf tmpl/
4 rm -f *.stamp
55 ]>
66 <book id="index">
77 <bookinfo>
8 <title>libfwupd Reference Manual</title>
8 <title>fwupd Reference Manual</title>
99 </bookinfo>
1010
1111 <reference id="intro">
12 <title>About libfwupd</title>
12 <title>About fwupd</title>
1313 <partintro>
1414 <para>
15 libfwupd is a library for querying the fwupd daemon.
15 fwupd is a daemon for updating firmware.
1616 </para>
1717 </partintro>
1818 </reference>
2121 <title>libfwupd</title>
2222 <partintro>
2323 <para>
24 Functionality exported by libfwupd.
24 Functionality exported by libfwupd for client applications.
2525 </para>
2626 </partintro>
2727 <xi:include href="xml/fwupd-client.xml"/>
2828 <xi:include href="xml/fwupd-device.xml"/>
29 <xi:include href="xml/fwupd-release.xml"/>
30 <xi:include href="xml/fwupd-remote.xml"/>
2931 <xi:include href="xml/fwupd-error.xml"/>
3032 <xi:include href="xml/fwupd-enums.xml"/>
31 <xi:include href="xml/fwupd-release.xml"/>
32 <xi:include href="xml/fwupd-remote.xml"/>
33 <xi:include href="xml/fwupd-result.xml"/>
3433 <xi:include href="xml/fwupd-version.xml"/>
34 </reference>
35
36 <reference id="plugin-reference">
37 <title>Plugin Reference</title>
38 <partintro>
39 <para>
40 Functionality available to plugins.
41 </para>
42 </partintro>
43 <xi:include href="xml/fu-plugin.xml"/>
44 <xi:include href="xml/fu-device.xml"/>
45 <xi:include href="xml/fu-device-locker.xml"/>
46 <xi:include href="xml/fu-common.xml"/>
47 <xi:include href="xml/fu-device-metadata.xml"/>
3548 </reference>
3649
3750 <index id="api-index-full">
11 'libfwupd',
22 src_dir : [
33 join_paths(meson.source_root(), 'libfwupd'),
4 join_paths(meson.source_root(), 'src'),
45 join_paths(meson.build_root(), 'libfwupd'),
6 join_paths(meson.build_root(), 'src'),
57 ],
68 main_xml : 'libfwupd-docs.xml',
79 install : true
+0
-464
docs/man/dfu-tool.sgml less more
0 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
1 <!-- Please adjust the date whenever revising the manpage. -->
2 <!ENTITY date "<date>26 February,2015</date>">
3 <!ENTITY package "dfu-tool">
4 <!ENTITY gnu "<acronym>GNU</acronym>">
5 <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
6 ]>
7
8 <refentry>
9 <refentryinfo>
10 <address>
11 <email>richard@hughsie.com</email>;
12 </address>
13 <author>
14 <firstname>Richard</firstname>
15 <surname>Hughes</surname>
16 </author>
17 <copyright>
18 <year>2015</year>
19 <holder>Richard Hughes</holder>
20 </copyright>
21 &date;
22 </refentryinfo>
23 <refmeta>
24 <refentrytitle>dfu-tool</refentrytitle>
25 <manvolnum>1</manvolnum>
26 </refmeta>
27 <refnamediv>
28 <refname>&package;</refname>
29 <refpurpose>Device Firmware Upgrade Tool</refpurpose>
30 </refnamediv>
31 <refsynopsisdiv>
32 <cmdsynopsis>
33 <command>&package;</command>
34 <arg><option>--verbose</option></arg>
35 <arg><option>--version</option></arg>
36 <arg><option>--force</option></arg>
37 <arg><option>--device=VID:PID</option></arg>
38 <arg><option>--transfer-size=BYTES</option></arg>
39 </cmdsynopsis>
40 </refsynopsisdiv>
41 <refsect1>
42 <title>DESCRIPTION</title>
43 <para>
44 This manual page documents briefly the <command>&package;</command> command.
45 </para>
46 <para>
47 <command>&package;</command> allows a user to write various kinds of
48 firmware onto devices supporting the USB Device Firmware Upgrade protocol.
49 This tool can be used to switch the device from the normal runtime mode
50 to `DFU mode' which allows the user to read and write firmware.
51 Either the whole device can be written in one operation, or individual
52 `targets' can be specified with the alternative name or number.
53 </para>
54 <para>
55 <command>&package;</command> uses the <literal>libdfu</literal> shared
56 library to perform actions.
57 All synchronous actions can be safely cancelled and on failure will return
58 errors with both a type and a full textual description.
59 libdfu supports DFU 1.0, DFU 1.1 and the ST DfuSe vendor extension, and
60 handles many device `quirks' necessary for the real-world implementations
61 of <acronym>DFU</acronym>.
62 </para>
63 <para>
64 Additionally <command>&package;</command> can be used to convert firmware
65 from various different formats, or to modify details about the elements,
66 images and metadata contained inside the firmware file.
67 For example, you can easily convert DFU 1.1 firmware into the
68 vendor-specific DfuSe format, convert a Intel HEX file into a raw file
69 padded to a specific size, or add new copyright and licensing information
70 to an existing file.
71 Fields such as the vendor and product IDs can be changed, and the firmware
72 elements can be encrypted and decrypted using various different methods.
73 Merging two DfuSe files together is also possible, although specifying
74 different alt-setting numbers before merging is a good idea to avoid
75 confusion.
76 </para>
77 <para>
78 Although <command>&package;</command> tries to provide a large number of
79 easy-to-use commands, it may only be possible to do certain operations
80 using the <literal>libdfu</literal> library directly.
81 This is easier than it sounds, as the library is built with GObject
82 Introspection support making it usable in many languages such as C,
83 Javascript and Python.
84 Furthermore, using the library is a good idea if you want to perform
85 multiple operations on large firmware files, for instance,
86 converting from an Intel HEX file, padding to a certain size, setting
87 vendor and adding licensing information and then saving to a remote
88 location.
89 </para>
90 </refsect1>
91 <refsect1>
92 <title>OPTIONS</title>
93 <para>
94 This program follows the usual &gnu; command line syntax,
95 with long options starting with two dashes (<literal>-</literal>).
96 A summary of options is included below.
97 </para>
98 <variablelist>
99 <varlistentry>
100 <term>
101 <option>--help</option>
102 </term>
103 <listitem>
104 <para>Show summary of all the commands available for use.</para>
105 </listitem>
106 </varlistentry>
107 <varlistentry>
108 <term>
109 <option>--version</option>
110 </term>
111 <listitem>
112 <para>Show the version of <command>&package;</command> installed.</para>
113 </listitem>
114 </varlistentry>
115 <varlistentry>
116 <term>
117 <option>--verbose</option>
118 </term>
119 <listitem>
120 <para>Show extra debugging information.</para>
121 </listitem>
122 </varlistentry>
123 <varlistentry>
124 <term>
125 <option>--device=VID:PID</option>
126 </term>
127 <listitem>
128 <para>
129 If multiple DFU-capable devices are attached you can specify the
130 specific vendor and product ID of the DFU device you want to query.
131 </para>
132 </listitem>
133 </varlistentry>
134 <varlistentry>
135 <term>
136 <option>--transfer-size=BYTES</option>
137 </term>
138 <listitem>
139 <para>
140 Manually override the size of each USB transfer, which you may want
141 for unreliable hardware or when the device lies about the maximum
142 packet size it accepts.
143 </para>
144 </listitem>
145 </varlistentry>
146 <varlistentry>
147 <term>
148 <option>--force</option>
149 </term>
150 <listitem>
151 <para>
152 Force the operation, disregarding warnings or sanity checks like
153 file CRC and checksums.
154 This is useful if you really know what you are doing, or in the
155 specialised case of fuzz-testing libdfu.
156 </para>
157 </listitem>
158 </varlistentry>
159 </variablelist>
160 </refsect1>
161 <refsect1>
162 <title>DEVICE COMMANDS</title>
163 <para>
164 These commands are used to interface with DFU-capable devices.
165 </para>
166 <variablelist>
167 <varlistentry>
168 <term>
169 <option>list</option>
170 </term>
171 <listitem>
172 <para>
173 This command lists currently attached DFU capable devices.
174 Some devices do not support the official DFU <literal>runtime</literal>
175 mode and thus do not support auto-discovery using this command.
176 For those devices, putting the device into DFU mode manually (e.g. by
177 holding a button down when rebooting the device) will make it show
178 up here.
179 </para>
180 </listitem>
181 </varlistentry>
182 <varlistentry>
183 <term>
184 <option>detach</option>
185 </term>
186 <listitem>
187 <para>
188 This command detaches the currently attached DFU capable device into
189 a special programming mode.
190 Whilst the device is in this special <acronym>DFU</acronym> mode it
191 can not be used as a normal device.
192 For example, a printer will not accept documents when in DFU mode.
193 </para>
194 </listitem>
195 </varlistentry>
196 <varlistentry>
197 <term>
198 <option>attach</option>
199 </term>
200 <listitem>
201 <para>
202 This command attaches a DFU capable device back to runtime so it can
203 be used as a normal device.
204 Some devices do not support attaching, and need to be manually
205 disconnected and connected before changing modes.
206 </para>
207 </listitem>
208 </varlistentry>
209 <varlistentry>
210 <term>
211 <option>watch</option>
212 </term>
213 <listitem>
214 <para>
215 This command watches DFU devices being hotplugged and can be used to
216 verify <literal>libdfu</literal> matches up the runtime and DFU modes
217 when attaching and detaching.
218 Use <option>CTRL+C</option> to make this command quit.
219 </para>
220 </listitem>
221 </varlistentry>
222 <varlistentry>
223 <term>
224 <option>read FILENAME</option>
225 </term>
226 <listitem>
227 <para>
228 This command uploads all the firmware from device into a file.
229 If the device has multiple partitions exported as different alternative
230 sections then they will all be read into a multi-image DfuSe-format
231 file.
232 If you just want the contents of one partition, <option>read-alt</option>
233 is the command you want.
234 </para>
235 </listitem>
236 </varlistentry>
237 <varlistentry>
238 <term>
239 <option>read-alt FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID</option>
240 </term>
241 <listitem>
242 <para>
243 This command uploads firmware from one partition into a file.
244 You can specify the partition by either the ALT-ID or ALT-NAME if set.
245 </para>
246 <para>e.g. <command>&package; read-alt backup.dfu SRAM</command></para>
247 </listitem>
248 </varlistentry>
249 <varlistentry>
250 <term>
251 <option>write</option>
252 </term>
253 <listitem>
254 <para>
255 This command downloads firmware from a file into all possible
256 partitions of a device.
257 If you only want to write one partition, <option>write-alt</option>
258 is the command you want.
259 </para>
260 </listitem>
261 </varlistentry>
262 <varlistentry>
263 <term>
264 <option>write-alt FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID [IMAGE-ALT-NAME|IMAGE-ALT-ID]</option>
265 </term>
266 <listitem>
267 <para>
268 This command downloads firmware from the file into one partition.
269 You can specify the partition by either the ALT-ID or ALT-NAME if set.
270 </para>
271 <para>e.g. <command>&package; write-alt sram.dfu SRAM __SRAM</command></para>
272 </listitem>
273 </varlistentry>
274 </variablelist>
275 </refsect1>
276 <refsect1>
277 <title>FIRMWARE COMMANDS</title>
278 <para>
279 These commands are used to read and modify existing firmware files.
280 </para>
281 <variablelist>
282 <varlistentry>
283 <term>
284 <option>dump FILENAME</option>
285 </term>
286 <listitem>
287 <para>
288 This command dumps all know details about a firmware file.
289 The complete memory map is shown, along with any metadata or vendor
290 information about the firmware file.
291 </para>
292 </listitem>
293 </varlistentry>
294 <varlistentry>
295 <term>
296 <option>convert FORMAT FILE-IN FILE-OUT [SIZE]</option>
297 </term>
298 <listitem>
299 <para>
300 This command converts the firmware from one format to another, optionally
301 padding to a certain size.
302 Possible values for the destination <option>FORMAT</option> include:
303 <literal>raw</literal>, <literal>ihex</literal>,
304 <literal>dfu</literal> and <literal>dfuse</literal>.
305 The <option>FILE-IN</option> and <option>FILE-OUT</option> values can
306 be the same if the source file is to be overwritten.
307 Although padding increases the file size with no apparent advantages
308 it can be used to support devices that do not store the runtime image
309 size and where validation of the written firmware is required.
310 </para>
311 <para>e.g. <command>&package; convert dfu firmware.hex firmware.dfu 8000</command></para>
312 </listitem>
313 </varlistentry>
314 <varlistentry>
315 <term>
316 <option>encrypt FILENAME-IN FILENAME-OUT TYPE KEY</option>
317 </term>
318 <listitem>
319 <para>
320 This command encrypts firmware data.
321 Only the image contents are actually modified, the DFU footer and
322 DfuSe header are left unaltered.
323 Possible values for the destination <option>TYPE</option> include:
324 <literal>xtea</literal> and <literal>nop</literal>.
325 If the <option>KEY</option> is not of the required length it is used
326 as an input to a hash function which can produce a key of the
327 required size.
328 </para>
329 <para>e.g. <command>&package; encrypt firmware.dfu firmware.xdfu xtea deadbeef</command></para>
330 </listitem>
331 </varlistentry>
332 <varlistentry>
333 <term>
334 <option>decrypt FILENAME-IN FILENAME-OUT TYPE KEY</option>
335 </term>
336 <listitem>
337 <para>
338 This command decrypts firmware data.
339 Only the image contents are actually modified, the DFU footer and
340 DfuSe header are left unaltered.
341 Possible values for the destination <option>TYPE</option> include:
342 <literal>xtea</literal> and <literal>nop</literal>.
343 If the <option>KEY</option> is not of the required length it is used
344 as an input to a hash function which can produce a key of the
345 required size.
346 </para>
347 <para>e.g. <command>&package; decrypt firmware.xdfu firmware.dfu xtea deadbeef</command></para>
348 </listitem>
349 </varlistentry>
350 <varlistentry>
351 <term>
352 <option>merge FILE-OUT FILE1 FILE2 [FILE3...]</option>
353 </term>
354 <listitem>
355 <para>
356 This command merges multiple firmware files into one file.
357 Although you can merge files with the same ALT-ID or ALT-NAME this
358 probably isn't what you want to do.
359 </para>
360 <para>e.g. <command>&package; merge combined.dfu lib.dfu app.dfu</command></para>
361 </listitem>
362 </varlistentry>
363 <varlistentry>
364 <term>
365 <option>set-alt-setting FILE ALT-ID</option>
366 </term>
367 <listitem>
368 <para>
369 This command modifies the alternative number on firmware file.
370 </para>
371 <para>e.g. <command>&package; set-alt-setting firmware.dfu 1</command></para>
372 </listitem>
373 </varlistentry>
374 <varlistentry>
375 <term>
376 <option>set-alt-setting-name</option>
377 </term>
378 <listitem>
379 <para>
380 This command modifies the alternative name on firmware file.
381 </para>
382 <para>e.g. <command>&package; set-alt-setting-name firmware.dfu SRAM</command></para>
383 </listitem>
384 </varlistentry>
385 <varlistentry>
386 <term>
387 <option>set-metadata FILE KEY VALUE</option>
388 </term>
389 <listitem>
390 <para>
391 This command adds or modifies existing metadata on a firmware file.
392 NOTE: There is only very limited metadata storage space in DFU files,
393 so keys and values should be kept as short as possible.
394 In particular, the <literal>License</literal> value should be
395 specified in SPDX format.
396 </para>
397 <para>e.g. <command>&package; set-metadata firmware.dfu Licence GPL-2.0+</command></para>
398 </listitem>
399 </varlistentry>
400 <varlistentry>
401 <term>
402 <option>set-vendor FILE VID</option>
403 </term>
404 <listitem>
405 <para>
406 This command sets vendor ID on a firmware file that will be used to
407 match specific devices.
408 Values of <literal>ffff</literal> will match any device vendor.
409 </para>
410 <para>e.g. <command>&package; set-vendor firmware.dfu 273f</command></para>
411 </listitem>
412 </varlistentry>
413 <varlistentry>
414 <term>
415 <option>set-product FILE PID</option>
416 </term>
417 <listitem>
418 <para>
419 This command sets the product ID on a firmware file that will be used to
420 match specific devices.
421 Values of <literal>ffff</literal> will match any device product.
422 </para>
423 <para>e.g. <command>&package; set-product firmware.dfu 1004</command></para>
424 </listitem>
425 </varlistentry>
426 <varlistentry>
427 <term>
428 <option>set-release FILE RELEASE</option>
429 </term>
430 <listitem>
431 <para>
432 This command sets the release version on firmware file that will be used to
433 match specific devices.
434 Values of <literal>ffff</literal> will match any device release.
435 </para>
436 <para>e.g. <command>&package; set-release firmware.dfu ffff</command></para>
437 </listitem>
438 </varlistentry>
439 </variablelist>
440 </refsect1>
441 <refsect1>
442 <title>AUTHOR</title>
443 <para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
444 </para>
445 </refsect1>
446 </refentry>
447
448 <!-- Keep this comment at the end of the file
449 Local variables:
450 mode: sgml
451 sgml-omittag:t
452 sgml-shorttag:t
453 sgml-minimize-attributes:nil
454 sgml-always-quote-attributes:t
455 sgml-indent-step:2
456 sgml-indent-data:t
457 sgml-parent-document:nil
458 sgml-default-dtd-file:nil
459 sgml-exposed-tags:nil
460 sgml-local-catalogs:nil
461 sgml-local-ecat-files:nil
462 End:
463 -->
+0
-248
docs/man/fwupdmgr.sgml less more
0 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
1 <!-- Please adjust the date whenever revising the manpage. -->
2 <!ENTITY date "<date>26 February,2015</date>">
3 <!ENTITY package "fwupdmgr">
4 <!ENTITY gnu "<acronym>GNU</acronym>">
5 <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
6 ]>
7
8 <refentry>
9 <refentryinfo>
10 <address>
11 <email>richard@hughsie.com</email>;
12 </address>
13 <author>
14 <firstname>Richard</firstname>
15 <surname>Hughes</surname>
16 </author>
17 <copyright>
18 <year>2015</year>
19 <holder>Richard Hughes</holder>
20 </copyright>
21 &date;
22 </refentryinfo>
23 <refmeta>
24 <refentrytitle>fwupdmgr</refentrytitle>
25 <manvolnum>1</manvolnum>
26 </refmeta>
27 <refnamediv>
28 <refname>&package;</refname>
29 <refpurpose>fwupd client tool</refpurpose>
30 </refnamediv>
31 <refsynopsisdiv>
32 <cmdsynopsis>
33 <command>&package;</command>
34 <arg><option>options</option></arg>
35 <arg>COMMAND</arg>
36 </cmdsynopsis>
37 </refsynopsisdiv>
38 <refsect1>
39 <title>DESCRIPTION</title>
40 <para>
41 This manual page documents briefly the <command>&package;</command> command.
42 </para>
43 <para>
44 <command>&package;</command> allows an administrator to update firmware.
45 </para>
46 </refsect1>
47 <refsect1>
48 <title>OPTIONS</title>
49 <para>
50 This program follows the usual &gnu; command line syntax,
51 with long options starting with two dashes (`-'). A summary of
52 options is included below.
53 </para>
54 <variablelist>
55 <varlistentry>
56 <term>
57 <option>--help</option>
58 </term>
59 <listitem>
60 <para>Show summary of options.</para>
61 </listitem>
62 </varlistentry>
63 <varlistentry>
64 <term>
65 <option>--verbose</option>
66 </term>
67 <listitem>
68 <para>Show extra debugging information.</para>
69 </listitem>
70 </varlistentry>
71 <varlistentry>
72 <term>
73 <option>--allow-reinstall</option>
74 </term>
75 <listitem>
76 <para>Allow re-installing existing firmware versions.</para>
77 </listitem>
78 </varlistentry>
79 <varlistentry>
80 <term>
81 <option>--allow-older</option>
82 </term>
83 <listitem>
84 <para>Allow downgrading firmware versions.</para>
85 </listitem>
86 </varlistentry>
87 <varlistentry>
88 <term>
89 <option>--offline</option>
90 </term>
91 <listitem>
92 <para>Schedule installation for next reboot when possible.</para>
93 </listitem>
94 </varlistentry>
95 <varlistentry>
96 <term>
97 <option>--force</option>
98 </term>
99 <listitem>
100 <para>Override plugin warning.</para>
101 </listitem>
102 </varlistentry>
103 </variablelist>
104 </refsect1>
105 <refsect1>
106 <title>COMMANDS</title>
107 <para>
108 This program takes commands with a variable number of arguments.
109 </para>
110 <variablelist>
111 <varlistentry>
112 <term>
113 <option>get-details</option>
114 </term>
115 <listitem>
116 <para>Gets details about a firmware file.</para>
117 </listitem>
118 </varlistentry>
119 <varlistentry>
120 <term>
121 <option>get-devices</option>
122 </term>
123 <listitem>
124 <para>Get the list of hardware that supports firmware updates.</para>
125 </listitem>
126 </varlistentry>
127 <varlistentry>
128 <term>
129 <option>get-updates</option>
130 </term>
131 <listitem>
132 <para>Gets the list of updates for connected hardware.</para>
133 </listitem>
134 </varlistentry>
135 <varlistentry>
136 <term>
137 <option>update</option>
138 </term>
139 <listitem>
140 <para>Updates all firmware to latest versions available.</para>
141 </listitem>
142 </varlistentry>
143 <varlistentry>
144 <term>
145 <option>install</option>
146 </term>
147 <listitem>
148 <para>Install a firmware file on this hardware.</para>
149 </listitem>
150 </varlistentry>
151 <varlistentry>
152 <term>
153 <option>install-prepared</option>
154 </term>
155 <listitem>
156 <para>Install prepared updates now.</para>
157 </listitem>
158 </varlistentry>
159 <varlistentry>
160 <term>
161 <option>clear-results</option>
162 </term>
163 <listitem>
164 <para>Clears the results from the last update.</para>
165 </listitem>
166 </varlistentry>
167 <varlistentry>
168 <term>
169 <option>dump-rom</option>
170 </term>
171 <listitem>
172 <para>Dump the ROM checksum.</para>
173 </listitem>
174 </varlistentry>
175 <varlistentry>
176 <term>
177 <option>monitor</option>
178 </term>
179 <listitem>
180 <para>Monitor the daemon for events.</para>
181 </listitem>
182 </varlistentry>
183 <varlistentry>
184 <term>
185 <option>unlock</option>
186 </term>
187 <listitem>
188 <para>Unlocks the devicefor firmware access.</para>
189 </listitem>
190 </varlistentry>
191 <varlistentry>
192 <term>
193 <option>verify</option>
194 </term>
195 <listitem>
196 <para>Gets the cryptographic hash of the dumped firmware.</para>
197 </listitem>
198 </varlistentry>
199 <varlistentry>
200 <term>
201 <option>verify-update</option>
202 </term>
203 <listitem>
204 <para>Update the stored metadata with current ROM contents.</para>
205 </listitem>
206 </varlistentry>
207 <varlistentry>
208 <term>
209 <option>refresh</option>
210 </term>
211 <listitem>
212 <para>Refresh metadata from remote server.</para>
213 </listitem>
214 </varlistentry>
215 <varlistentry>
216 <term>
217 <option>get-results</option>
218 </term>
219 <listitem>
220 <para>Gets the results from the last update.</para>
221 </listitem>
222 </varlistentry>
223 </variablelist>
224 </refsect1>
225 <refsect1>
226 <title>AUTHOR</title>
227 <para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
228 </para>
229 </refsect1>
230 </refentry>
231
232 <!-- Keep this comment at the end of the file
233 Local variables:
234 mode: sgml
235 sgml-omittag:t
236 sgml-shorttag:t
237 sgml-minimize-attributes:nil
238 sgml-always-quote-attributes:t
239 sgml-indent-step:2
240 sgml-indent-data:t
241 sgml-parent-document:nil
242 sgml-default-dtd-file:nil
243 sgml-exposed-tags:nil
244 sgml-local-catalogs:nil
245 sgml-local-ecat-files:nil
246 End:
247 -->
+0
-21
docs/man/meson.build less more
0 docbook2man = find_program('docbook2man')
1 custom_target('fwupdmgr-man',
2 input : 'fwupdmgr.sgml',
3 output : 'fwupdmgr.1',
4 command : [
5 docbook2man, '@INPUT@',
6 '--output', meson.current_build_dir(),
7 ],
8 install : true,
9 install_dir : join_paths(get_option('mandir'), 'man1'),
10 )
11 custom_target('dfu-tool-man',
12 input : 'dfu-tool.sgml',
13 output : 'dfu-tool.1',
14 command : [
15 docbook2man, '@INPUT@',
16 '--output', meson.current_build_dir(),
17 ],
18 install : true,
19 install_dir : join_paths(get_option('mandir'), 'man1'),
20 )
00 if get_option('enable-doc')
1 subdir('libdfu')
21 subdir('libfwupd')
32 endif
4 if get_option('enable-man')
5 subdir('man')
6 endif
+0
-122
libdfu/dfu-cipher-devo.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-cipher-devo.h"
26 #include "dfu-error.h"
27
28 /* this is not really a cipher, more just obfuscation and is specific to the
29 * Walkera Devo line of RC controllers */
30
31 static gboolean
32 dfu_tool_parse_devo_key (const gchar *key, guint8 *offset, GError **error)
33 {
34 gchar *endptr;
35 guint64 tmp;
36
37 tmp = g_ascii_strtoull (key, &endptr, 10);
38 if (tmp > 0xff || endptr[0] != '\0') {
39 g_set_error (error,
40 DFU_ERROR,
41 DFU_ERROR_INTERNAL,
42 "Failed to parse offset value '%s'", key);
43 return FALSE;
44 }
45
46 /* success */
47 if (offset != NULL)
48 *offset = (guint8) tmp;
49 g_debug ("using devo offset %u", (guint) tmp);
50 return TRUE;
51 }
52
53 /**
54 * dfu_cipher_decrypt_devo: (skip)
55 * @key: a XTEA key
56 * @data: data to parse
57 * @length: length of @data
58 * @error: a #GError, or %NULL
59 *
60 * Decrypt a buffer using DEVO obfuscation.
61 *
62 * Returns: %TRUE for success
63 **/
64 gboolean
65 dfu_cipher_decrypt_devo (const gchar *key,
66 guint8 *data,
67 guint32 length,
68 GError **error)
69 {
70 guint8 offset;
71 guint32 i;
72
73 if (!dfu_tool_parse_devo_key (key, &offset, error))
74 return FALSE;
75
76 /* no words for how stupid this cipher is */
77 for (i = 0; i < length; i++) {
78 guint8 val = data[i];
79 if (val >= 0x80 + offset && val <= 0xcf)
80 data[i] -= offset;
81 else if (val >= 0x80 && val < 0x80 + offset)
82 data[i] += (0x50 - offset);
83 }
84
85 return TRUE;
86 }
87
88 /**
89 * dfu_cipher_encrypt_devo: (skip)
90 * @key: a XTEA key
91 * @data: data to parse
92 * @length: length of @data
93 * @error: a #GError, or %NULL
94 *
95 * Encrypt a buffer using DEVO obfuscation.
96 *
97 * Returns: %TRUE for success
98 **/
99 gboolean
100 dfu_cipher_encrypt_devo (const gchar *key,
101 guint8 *data,
102 guint32 length,
103 GError **error)
104 {
105 guint8 offset;
106 guint32 i;
107
108 if (!dfu_tool_parse_devo_key (key, &offset, error))
109 return FALSE;
110
111 /* no words for how stupid this cipher is */
112 for (i = 0; i < length; i++) {
113 guint8 val = data[i];
114 if (val >= 0x80 && val <= 0xcf - offset)
115 data[i] += offset;
116 else if (val >= 0xd0 - offset && val < 0xd0)
117 data[i] -= (0x50 - offset);
118 }
119
120 return TRUE;
121 }
+0
-41
libdfu/dfu-cipher-devo.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_DEVO_H
22 #define __DFU_FORMAT_DEVO_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 gboolean dfu_cipher_encrypt_devo (const gchar *key,
30 guint8 *data,
31 guint32 length,
32 GError **error);
33 gboolean dfu_cipher_decrypt_devo (const gchar *key,
34 guint8 *data,
35 guint32 length,
36 GError **error);
37
38 G_END_DECLS
39
40 #endif /* __DFU_FORMAT_DEVO_H */
+0
-223
libdfu/dfu-cipher-xtea.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-cipher-xtea.h"
26 #include "dfu-error.h"
27
28 #define XTEA_DELTA 0x9e3779b9
29 #define XTEA_NUM_ROUNDS 32
30
31 static gboolean
32 dfu_tool_parse_xtea_key (const gchar *key, guint32 *keys, GError **error)
33 {
34 guint i;
35 gsize key_len;
36
37 /* too long */
38 key_len = strlen (key);
39 if (key_len > 32) {
40 g_set_error (error,
41 DFU_ERROR,
42 DFU_ERROR_NOT_SUPPORTED,
43 "Key string too long at %" G_GSIZE_FORMAT " chars, max 16",
44 key_len);
45 return FALSE;
46 }
47
48 /* parse 4x32b values or generate a hash */
49 if (key_len == 32) {
50 for (i = 0; i < 4; i++) {
51 gchar buf[] = "xxxxxxxx";
52 gchar *endptr;
53 guint64 tmp;
54
55 /* copy to 4-char buf (with NUL) */
56 memcpy (buf, key + i*8, 8);
57 tmp = g_ascii_strtoull (buf, &endptr, 16);
58 if (endptr && endptr[0] != '\0') {
59 g_set_error (error,
60 DFU_ERROR,
61 DFU_ERROR_NOT_SUPPORTED,
62 "Failed to parse key '%s'", key);
63 return FALSE;
64 }
65 keys[3-i] = (guint32) tmp;
66 }
67 } else {
68 gsize buf_len = 16;
69 g_autoptr(GChecksum) csum = NULL;
70 csum = g_checksum_new (G_CHECKSUM_MD5);
71 g_checksum_update (csum, (const guchar *) key, (gssize) key_len);
72 g_checksum_get_digest (csum, (guint8 *) keys, &buf_len);
73 g_assert (buf_len == 16);
74 }
75
76 /* success */
77 g_debug ("using XTEA key %04x%04x%04x%04x",
78 keys[3], keys[2], keys[1], keys[0]);
79 return TRUE;
80 }
81
82 /**
83 * dfu_cipher_decrypt_xtea: (skip)
84 * @key: a XTEA key
85 * @data: data to parse
86 * @length: length of @data
87 * @error: a #GError, or %NULL
88 *
89 * Decrypt a buffer using XTEA.
90 *
91 * Returns: %TRUE for success
92 **/
93 gboolean
94 dfu_cipher_decrypt_xtea (const gchar *key,
95 guint8 *data,
96 guint32 length,
97 GError **error)
98 {
99 guint32 sum;
100 guint32 v0;
101 guint32 v1;
102 guint8 i;
103 guint j;
104 guint32 chunks = length / 4;
105 guint32 keys[4];
106 g_autofree guint32 *tmp = NULL;
107
108 /* sanity check */
109 if (length < 8) {
110 g_set_error (error,
111 DFU_ERROR,
112 DFU_ERROR_NOT_SUPPORTED,
113 "8 bytes data required, got %" G_GUINT32_FORMAT,
114 length);
115 return FALSE;
116 }
117 if (length % 4 != 0) {
118 g_set_error (error,
119 DFU_ERROR,
120 DFU_ERROR_NOT_SUPPORTED,
121 "Multiples of 4 bytes required, got %" G_GUINT32_FORMAT,
122 length);
123 return FALSE;
124 }
125
126 /* parse key */
127 if (!dfu_tool_parse_xtea_key (key, keys, error))
128 return FALSE;
129
130 /* allocate a buffer that can be addressed in 4-byte chunks */
131 tmp = g_new0 (guint32, chunks);
132 memcpy (tmp, data, length);
133
134 /* process buffer using XTEA keys */
135 for (j = 0; j < chunks; j += 2) {
136 v0 = tmp[j];
137 v1 = tmp[j+1];
138 sum = XTEA_DELTA * XTEA_NUM_ROUNDS;
139 for (i = 0; i < XTEA_NUM_ROUNDS; i++) {
140 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keys[(sum >> 11) & 3]);
141 sum -= XTEA_DELTA;
142 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keys[sum & 3]);
143 }
144 tmp[j] = v0;
145 tmp[j+1] = v1;
146 }
147
148 /* copy the temp buffer back to data */
149 memcpy (data, tmp, length);
150 return TRUE;
151 }
152
153 /**
154 * dfu_cipher_encrypt_xtea: (skip)
155 * @key: a XTEA key
156 * @data: data to parse
157 * @length: length of @data
158 * @error: a #GError, or %NULL
159 *
160 * Encrypt a buffer using XTEA.
161 *
162 * Returns: %TRUE for success
163 **/
164 gboolean
165 dfu_cipher_encrypt_xtea (const gchar *key,
166 guint8 *data,
167 guint32 length,
168 GError **error)
169 {
170 guint32 sum;
171 guint32 v0;
172 guint32 v1;
173 guint8 i;
174 guint j;
175 guint32 chunks = length / 4;
176 guint32 keys[4];
177 g_autofree guint32 *tmp = NULL;
178
179 /* sanity check */
180 if (length < 8) {
181 g_set_error (error,
182 DFU_ERROR,
183 DFU_ERROR_NOT_SUPPORTED,
184 "8 bytes data required, got %" G_GUINT32_FORMAT,
185 length);
186 return FALSE;
187 }
188 if (length % 4 != 0) {
189 g_set_error (error,
190 DFU_ERROR,
191 DFU_ERROR_NOT_SUPPORTED,
192 "Multiples of 4 bytes required, got %" G_GUINT32_FORMAT,
193 length);
194 return FALSE;
195 }
196
197 /* parse key */
198 if (!dfu_tool_parse_xtea_key (key, keys, error))
199 return FALSE;
200
201 /* allocate a buffer that can be addressed in 4-byte chunks */
202 tmp = g_new0 (guint32, chunks);
203 memcpy (tmp, data, length);
204
205 /* process buffer using XTEA keys */
206 for (j = 0; j < chunks; j += 2) {
207 sum = 0;
208 v0 = tmp[j];
209 v1 = tmp[j+1];
210 for (i = 0; i < XTEA_NUM_ROUNDS; i++) {
211 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keys[sum & 3]);
212 sum += XTEA_DELTA;
213 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keys[(sum >> 11) & 3]);
214 }
215 tmp[j] = v0;
216 tmp[j+1] = v1;
217 }
218
219 /* copy the temp buffer back to data */
220 memcpy (data, tmp, length);
221 return TRUE;
222 }
+0
-41
libdfu/dfu-cipher-xtea.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_XTEA_H
22 #define __DFU_FORMAT_XTEA_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 gboolean dfu_cipher_encrypt_xtea (const gchar *key,
30 guint8 *data,
31 guint32 length,
32 GError **error);
33 gboolean dfu_cipher_decrypt_xtea (const gchar *key,
34 guint8 *data,
35 guint32 length,
36 GError **error);
37
38 G_END_DECLS
39
40 #endif /* __DFU_FORMAT_XTEA_H */
+0
-213
libdfu/dfu-common.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-common
23 * @short_description: Common functions for DFU
24 *
25 * These helper objects allow converting from enum values to strings.
26 */
27
28 #include "config.h"
29
30 #include "dfu-common.h"
31
32 /**
33 * dfu_state_to_string:
34 * @state: a #DfuState, e.g. %DFU_STATE_DFU_MANIFEST
35 *
36 * Converts an enumerated value to a string.
37 *
38 * Return value: a string
39 *
40 * Since: 0.5.4
41 **/
42 const gchar *
43 dfu_state_to_string (DfuState state)
44 {
45 if (state == DFU_STATE_APP_IDLE)
46 return "appIDLE";
47 if (state == DFU_STATE_APP_DETACH)
48 return "appDETACH";
49 if (state == DFU_STATE_DFU_IDLE)
50 return "dfuIDLE";
51 if (state == DFU_STATE_DFU_DNLOAD_SYNC)
52 return "dfuDNLOAD-SYNC";
53 if (state == DFU_STATE_DFU_DNBUSY)
54 return "dfuDNBUSY";
55 if (state == DFU_STATE_DFU_DNLOAD_IDLE)
56 return "dfuDNLOAD-IDLE";
57 if (state == DFU_STATE_DFU_MANIFEST_SYNC)
58 return "dfuMANIFEST-SYNC";
59 if (state == DFU_STATE_DFU_MANIFEST)
60 return "dfuMANIFEST";
61 if (state == DFU_STATE_DFU_MANIFEST_WAIT_RESET)
62 return "dfuMANIFEST-WAIT-RESET";
63 if (state == DFU_STATE_DFU_UPLOAD_IDLE)
64 return "dfuUPLOAD-IDLE";
65 if (state == DFU_STATE_DFU_ERROR)
66 return "dfuERROR";
67 return NULL;
68 }
69
70 /**
71 * dfu_status_to_string:
72 * @status: a #DfuStatus, e.g. %DFU_STATUS_ERR_ERASE
73 *
74 * Converts an enumerated value to a string.
75 *
76 * Return value: a string
77 *
78 * Since: 0.5.4
79 **/
80 const gchar *
81 dfu_status_to_string (DfuStatus status)
82 {
83 if (status == DFU_STATUS_OK)
84 return "OK";
85 if (status == DFU_STATUS_ERR_TARGET)
86 return "errTARGET";
87 if (status == DFU_STATUS_ERR_FILE)
88 return "errFILE";
89 if (status == DFU_STATUS_ERR_WRITE)
90 return "errwrite";
91 if (status == DFU_STATUS_ERR_ERASE)
92 return "errERASE";
93 if (status == DFU_STATUS_ERR_CHECK_ERASED)
94 return "errCHECK_ERASED";
95 if (status == DFU_STATUS_ERR_PROG)
96 return "errPROG";
97 if (status == DFU_STATUS_ERR_VERIFY)
98 return "errVERIFY";
99 if (status == DFU_STATUS_ERR_ADDRESS)
100 return "errADDRESS";
101 if (status == DFU_STATUS_ERR_NOTDONE)
102 return "errNOTDONE";
103 if (status == DFU_STATUS_ERR_FIRMWARE)
104 return "errFIRMWARE";
105 if (status == DFU_STATUS_ERR_VENDOR)
106 return "errVENDOR";
107 if (status == DFU_STATUS_ERR_USBR)
108 return "errUSBR";
109 if (status == DFU_STATUS_ERR_POR)
110 return "errPOR";
111 if (status == DFU_STATUS_ERR_UNKNOWN)
112 return "errUNKNOWN";
113 if (status == DFU_STATUS_ERR_STALLDPKT)
114 return "errSTALLDPKT";
115 return NULL;
116 }
117
118 /**
119 * dfu_mode_to_string:
120 * @mode: a #DfuMode, e.g. %DFU_MODE_RUNTIME
121 *
122 * Converts an enumerated value to a string.
123 *
124 * Return value: a string
125 *
126 * Since: 0.5.4
127 **/
128 const gchar *
129 dfu_mode_to_string (DfuMode mode)
130 {
131 if (mode == DFU_MODE_RUNTIME)
132 return "runtime";
133 if (mode == DFU_MODE_DFU)
134 return "DFU";
135 return NULL;
136 }
137
138 /**
139 * dfu_cipher_kind_to_string:
140 * @cipher_kind: a #DfuCipherKind, e.g. %DFU_CIPHER_KIND_XTEA
141 *
142 * Converts an enumerated value to a string.
143 *
144 * Return value: a string
145 *
146 * Since: 0.5.4
147 **/
148 const gchar *
149 dfu_cipher_kind_to_string (DfuCipherKind cipher_kind)
150 {
151 if (cipher_kind == DFU_CIPHER_KIND_NONE)
152 return "none";
153 if (cipher_kind == DFU_CIPHER_KIND_XTEA)
154 return "xtea";
155 if (cipher_kind == DFU_CIPHER_KIND_DEVO)
156 return "devo";
157 if (cipher_kind == DFU_CIPHER_KIND_RSA)
158 return "rsa";
159 return NULL;
160 }
161
162 /**
163 * dfu_version_to_string:
164 * @version: a #DfuVersion, e.g. %DFU_VERSION_DFU_1_1
165 *
166 * Converts an enumerated value to a string.
167 *
168 * Return value: a string
169 *
170 * Since: 0.7.2
171 **/
172 const gchar *
173 dfu_version_to_string (DfuVersion version)
174 {
175 if (version == DFU_VERSION_DFU_1_0)
176 return "1.0";
177 if (version == DFU_VERSION_DFU_1_1)
178 return "1.1";
179 if (version == DFU_VERSION_DFUSE)
180 return "DfuSe";
181 return NULL;
182 }
183
184 /**
185 * dfu_action_to_string:
186 * @action: a #DfuAction, e.g. %DFU_ACTION_VERIFY
187 *
188 * Converts an enumerated value to a string.
189 *
190 * Return value: a string
191 *
192 * Since: 0.7.5
193 **/
194 const gchar *
195 dfu_action_to_string (DfuAction action)
196 {
197 if (action == DFU_ACTION_IDLE)
198 return "idle";
199 if (action == DFU_ACTION_READ)
200 return "read";
201 if (action == DFU_ACTION_WRITE)
202 return "write";
203 if (action == DFU_ACTION_VERIFY)
204 return "verify";
205 if (action == DFU_ACTION_ERASE)
206 return "erase";
207 if (action == DFU_ACTION_DETACH)
208 return "detach";
209 if (action == DFU_ACTION_ATTACH)
210 return "attach";
211 return NULL;
212 }
+0
-219
libdfu/dfu-common.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_COMMON_H
22 #define __DFU_COMMON_H
23
24 #include <glib.h>
25 #include <gusb.h>
26
27 G_BEGIN_DECLS
28
29 /**
30 * DfuRequest:
31 * @DFU_REQUEST_DETACH: Detach
32 * @DFU_REQUEST_DNLOAD: Download host-to-device
33 * @DFU_REQUEST_UPLOAD: Upload device-to-host
34 * @DFU_REQUEST_GETSTATUS: Get the device status
35 * @DFU_REQUEST_CLRSTATUS: Clear the device status
36 * @DFU_REQUEST_GETSTATE: Get the last set state
37 * @DFU_REQUEST_ABORT: Abort the current transfer
38 *
39 * The DFU request kinds.
40 **/
41 typedef enum {
42 DFU_REQUEST_DETACH = 0x00,
43 DFU_REQUEST_DNLOAD = 0x01,
44 DFU_REQUEST_UPLOAD = 0x02,
45 DFU_REQUEST_GETSTATUS = 0x03,
46 DFU_REQUEST_CLRSTATUS = 0x04,
47 DFU_REQUEST_GETSTATE = 0x05,
48 DFU_REQUEST_ABORT = 0x06,
49 /*< private >*/
50 DFU_REQUEST_LAST
51 } DfuRequest;
52
53 /**
54 * DfuStatus:
55 * @DFU_STATUS_OK: No error condition is present
56 * @DFU_STATUS_ERR_TARGET: File is not targeted for use by this device
57 * @DFU_STATUS_ERR_FILE: File is for this device but fails a verification test
58 * @DFU_STATUS_ERR_WRITE: Device is unable to write memory
59 * @DFU_STATUS_ERR_ERASE: Memory erase function failed
60 * @DFU_STATUS_ERR_CHECK_ERASED: Memory erase check failed
61 * @DFU_STATUS_ERR_PROG: Program memory function failed
62 * @DFU_STATUS_ERR_VERIFY: Programmed memory failed verification
63 * @DFU_STATUS_ERR_ADDRESS: Cannot program memory due to received address that isout of range
64 * @DFU_STATUS_ERR_NOTDONE: Received DFU_DNLOAD with wLength = 0 but data is incomplete
65 * @DFU_STATUS_ERR_FIRMWARE: Device firmware is corrupt
66 * @DFU_STATUS_ERR_VENDOR: iString indicates a vendor-specific error
67 * @DFU_STATUS_ERR_USBR: Device detected unexpected USB reset signaling
68 * @DFU_STATUS_ERR_POR: Device detected unexpected power on reset
69 * @DFU_STATUS_ERR_UNKNOWN: Something unexpected went wrong
70 * @DFU_STATUS_ERR_STALLDPKT: Device stalled an unexpected request
71 *
72 * The status enumerated kind.
73 **/
74 typedef enum {
75 DFU_STATUS_OK = 0x00,
76 DFU_STATUS_ERR_TARGET = 0x01,
77 DFU_STATUS_ERR_FILE = 0x02,
78 DFU_STATUS_ERR_WRITE = 0x03,
79 DFU_STATUS_ERR_ERASE = 0x04,
80 DFU_STATUS_ERR_CHECK_ERASED = 0x05,
81 DFU_STATUS_ERR_PROG = 0x06,
82 DFU_STATUS_ERR_VERIFY = 0x07,
83 DFU_STATUS_ERR_ADDRESS = 0x08,
84 DFU_STATUS_ERR_NOTDONE = 0x09,
85 DFU_STATUS_ERR_FIRMWARE = 0x0a,
86 DFU_STATUS_ERR_VENDOR = 0x0b,
87 DFU_STATUS_ERR_USBR = 0x0c,
88 DFU_STATUS_ERR_POR = 0x0d,
89 DFU_STATUS_ERR_UNKNOWN = 0x0e,
90 DFU_STATUS_ERR_STALLDPKT = 0x0f,
91 /*< private >*/
92 DFU_STATUS_LAST
93 } DfuStatus;
94
95 /**
96 * DfuState:
97 * @DFU_STATE_APP_IDLE: State 0
98 * @DFU_STATE_APP_DETACH: State 1
99 * @DFU_STATE_DFU_IDLE: State 2
100 * @DFU_STATE_DFU_DNLOAD_SYNC: State 3
101 * @DFU_STATE_DFU_DNBUSY: State 4
102 * @DFU_STATE_DFU_DNLOAD_IDLE: State 5
103 * @DFU_STATE_DFU_MANIFEST_SYNC: State 6
104 * @DFU_STATE_DFU_MANIFEST: State 7
105 * @DFU_STATE_DFU_MANIFEST_WAIT_RESET: State 8
106 * @DFU_STATE_DFU_UPLOAD_IDLE: State 9
107 * @DFU_STATE_DFU_ERROR: State 10
108 *
109 * The state enumerated kind.
110 **/
111 typedef enum {
112 DFU_STATE_APP_IDLE = 0x00,
113 DFU_STATE_APP_DETACH = 0x01,
114 DFU_STATE_DFU_IDLE = 0x02,
115 DFU_STATE_DFU_DNLOAD_SYNC = 0x03,
116 DFU_STATE_DFU_DNBUSY = 0x04,
117 DFU_STATE_DFU_DNLOAD_IDLE = 0x05,
118 DFU_STATE_DFU_MANIFEST_SYNC = 0x06,
119 DFU_STATE_DFU_MANIFEST = 0x07,
120 DFU_STATE_DFU_MANIFEST_WAIT_RESET = 0x08,
121 DFU_STATE_DFU_UPLOAD_IDLE = 0x09,
122 DFU_STATE_DFU_ERROR = 0x0a,
123 /*< private >*/
124 DFU_STATE_LAST
125 } DfuState;
126
127 /**
128 * DfuMode:
129 * @DFU_MODE_UNKNOWN: Unknown mode
130 * @DFU_MODE_RUNTIME: Runtime mode
131 * @DFU_MODE_DFU: Bootloader mode
132 *
133 * The mode enumerated kind.
134 **/
135 typedef enum {
136 DFU_MODE_UNKNOWN,
137 DFU_MODE_RUNTIME,
138 DFU_MODE_DFU,
139 /*< private >*/
140 DFU_MODE_LAST
141 } DfuMode;
142
143 /**
144 * DfuCipherKind:
145 * @DFU_CIPHER_KIND_NONE: No cipher detected
146 * @DFU_CIPHER_KIND_XTEA: XTEA cipher detected
147 * @DFU_CIPHER_KIND_DEVO: DEVO cipher detected
148 * @DFU_CIPHER_KIND_RSA: RSA cipher detected
149 *
150 * The type of cipher used for transfering the firmware.
151 **/
152 typedef enum {
153 DFU_CIPHER_KIND_NONE,
154 DFU_CIPHER_KIND_XTEA,
155 DFU_CIPHER_KIND_DEVO,
156 DFU_CIPHER_KIND_RSA,
157 /*< private >*/
158 DFU_CIPHER_KIND_LAST
159 } DfuCipherKind;
160
161 /**
162 * DfuVersion:
163 * @DFU_VERSION_UNKNOWN: Format unknown
164 * @DFU_VERSION_DFU_1_0: DFU 1.0
165 * @DFU_VERSION_DFU_1_1: DFU 1.1
166 * @DFU_VERSION_DFUSE: DfuSe
167 *
168 * The known versions of the DFU standard in BCD format.
169 **/
170 typedef enum {
171 DFU_VERSION_UNKNOWN = 0,
172 DFU_VERSION_DFU_1_0 = 0x0100,
173 DFU_VERSION_DFU_1_1 = 0x0110,
174 DFU_VERSION_DFUSE = 0x011a,
175 /*< private >*/
176 DFU_VERSION_LAST
177 } DfuVersion;
178
179 /**
180 * DfuAction:
181 * @DFU_ACTION_UNKNOWN: No progress state
182 * @DFU_ACTION_IDLE: Device is idle
183 * @DFU_ACTION_READ: Reading from the device
184 * @DFU_ACTION_WRITE: Writing to the device
185 * @DFU_ACTION_VERIFY: Verifying the write
186 * @DFU_ACTION_ERASE: Erasing the device
187 * @DFU_ACTION_DETACH: Detach into DFU mode
188 * @DFU_ACTION_ATTACH: Attach into APP mode
189 *
190 * The device DFU attributes.
191 **/
192 typedef enum {
193 DFU_ACTION_UNKNOWN, /* Since: 0.7.5 */
194 DFU_ACTION_IDLE, /* Since: 0.7.5 */
195 DFU_ACTION_READ, /* Since: 0.7.5 */
196 DFU_ACTION_WRITE, /* Since: 0.7.5 */
197 DFU_ACTION_VERIFY, /* Since: 0.7.5 */
198 DFU_ACTION_ERASE, /* Since: 0.7.5 */
199 DFU_ACTION_DETACH, /* Since: 0.7.5 */
200 DFU_ACTION_ATTACH, /* Since: 0.7.5 */
201 /*< private >*/
202 DFU_ACTION_LAST
203 } DfuAction;
204
205 #define DFU_METADATA_KEY_LICENSE "License"
206 #define DFU_METADATA_KEY_COPYRIGHT "Copyright"
207 #define DFU_METADATA_KEY_CIPHER_KIND "CipherKind"
208
209 const gchar *dfu_state_to_string (DfuState state);
210 const gchar *dfu_status_to_string (DfuStatus status);
211 const gchar *dfu_mode_to_string (DfuMode mode);
212 const gchar *dfu_cipher_kind_to_string (DfuCipherKind cipher_kind);
213 const gchar *dfu_version_to_string (DfuVersion version);
214 const gchar *dfu_action_to_string (DfuAction action);
215
216 G_END_DECLS
217
218 #endif /* __DFU_COMMON_H */
+0
-586
libdfu/dfu-context.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-context
23 * @short_description: A system context for managing DFU-capable devices
24 *
25 * This object allows discovering and monitoring hotpluggable DFU devices.
26 *
27 * When using #DfuContext the device is given some time to re-enumerate after a
28 * detach or reset. This allows client programs to continue using the #DfuDevice
29 * without dealing with the device hotplug and the #GUsbDevice changing.
30 * Using this object may be easier than using GUsbContext directly.
31 *
32 * Please be aware that after device detach or reset the number of #DfuTarget
33 * objects may be different and so need to be re-requested.
34 *
35 * See also: #DfuDevice, #DfuTarget
36 */
37
38 #include "config.h"
39
40 #include "dfu-device-private.h"
41 #include "dfu-error.h"
42 #include "dfu-context.h"
43
44 static void dfu_context_finalize (GObject *object);
45
46 typedef struct {
47 GUsbContext *usb_ctx;
48 GPtrArray *devices; /* of DfuContextItem */
49 guint timeout; /* in ms */
50 } DfuContextPrivate;
51
52 typedef struct {
53 DfuContext *context; /* not refcounted */
54 DfuDevice *device; /* not refcounted */
55 guint timeout_id;
56 gulong state_change_id;
57 } DfuContextItem;
58
59 enum {
60 SIGNAL_DEVICE_ADDED,
61 SIGNAL_DEVICE_REMOVED,
62 SIGNAL_DEVICE_CHANGED,
63 SIGNAL_LAST
64 };
65
66 static guint signals [SIGNAL_LAST] = { 0 };
67
68 G_DEFINE_TYPE_WITH_PRIVATE (DfuContext, dfu_context, G_TYPE_OBJECT)
69 #define GET_PRIVATE(o) (dfu_context_get_instance_private (o))
70
71 static void
72 dfu_context_device_free (DfuContextItem *item)
73 {
74 if (item->timeout_id > 0)
75 g_source_remove (item->timeout_id);
76 if (item->timeout_id > 0) {
77 g_signal_handler_disconnect (item->device,
78 item->state_change_id);
79 }
80 g_object_unref (item->device);
81 g_free (item);
82 }
83
84 static void
85 dfu_context_class_init (DfuContextClass *klass)
86 {
87 GObjectClass *object_class = G_OBJECT_CLASS (klass);
88
89 /**
90 * DfuContext::device-added:
91 * @context: the #DfuContext instance that emitted the signal
92 * @device: the #DfuDevice
93 *
94 * The ::device-added signal is emitted when a new DFU device is connected.
95 *
96 * Since: 0.5.4
97 **/
98 signals [SIGNAL_DEVICE_ADDED] =
99 g_signal_new ("device-added",
100 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
101 G_STRUCT_OFFSET (DfuContextClass, device_added),
102 NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
103 G_TYPE_NONE, 1, DFU_TYPE_DEVICE);
104
105 /**
106 * DfuContext::device-removed:
107 * @context: the #DfuContext instance that emitted the signal
108 * @device: the #DfuDevice
109 *
110 * The ::device-removed signal is emitted when a DFU device is removed.
111 *
112 * Since: 0.5.4
113 **/
114 signals [SIGNAL_DEVICE_REMOVED] =
115 g_signal_new ("device-removed",
116 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
117 G_STRUCT_OFFSET (DfuContextClass, device_removed),
118 NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
119 G_TYPE_NONE, 1, DFU_TYPE_DEVICE);
120
121 /**
122 * DfuContext::device-changed:
123 * @context: the #DfuContext instance that emitted the signal
124 * @device: the #DfuDevice
125 *
126 * The ::device-changed signal is emitted when a DFU device is changed,
127 * typically when it has detached or been reset.
128 *
129 * Since: 0.5.4
130 **/
131 signals [SIGNAL_DEVICE_CHANGED] =
132 g_signal_new ("device-changed",
133 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
134 G_STRUCT_OFFSET (DfuContextClass, device_changed),
135 NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
136 G_TYPE_NONE, 1, DFU_TYPE_DEVICE);
137
138 object_class->finalize = dfu_context_finalize;
139 }
140
141 static gchar *
142 dfu_context_get_device_id (DfuDevice *device)
143 {
144 GUsbDevice *dev;
145 dev = dfu_device_get_usb_dev (device);
146 if (dev == NULL)
147 return g_strdup (dfu_device_get_platform_id (device));
148 return g_strdup_printf ("%04x:%04x [%s]",
149 g_usb_device_get_vid (dev),
150 g_usb_device_get_pid (dev),
151 g_usb_device_get_platform_id (dev));
152 }
153
154 static DfuContextItem *
155 dfu_context_find_item_by_platform_id (DfuContext *context, const gchar *platform_id)
156 {
157 DfuContextPrivate *priv = GET_PRIVATE (context);
158 DfuContextItem *item;
159 guint i;
160
161 /* do we have this device */
162 for (i = 0; i < priv->devices->len; i++) {
163 item = g_ptr_array_index (priv->devices, i);
164 if (g_strcmp0 (dfu_device_get_platform_id (item->device), platform_id) == 0)
165 return item;
166 }
167 return NULL;
168 }
169
170 static void
171 dfu_context_remove_item (DfuContextItem *item)
172 {
173 DfuContextPrivate *priv = GET_PRIVATE (item->context);
174 g_autofree gchar *device_id = NULL;
175
176 /* log something */
177 device_id = dfu_context_get_device_id (item->device);
178 g_debug ("%s was removed", device_id);
179
180 g_signal_emit (item->context, signals[SIGNAL_DEVICE_REMOVED], 0, item->device);
181 g_ptr_array_remove (priv->devices, item);
182 }
183
184 static gboolean
185 dfu_context_device_timeout_cb (gpointer user_data)
186 {
187 DfuContextItem *item = (DfuContextItem *) user_data;
188 g_autofree gchar *device_id = NULL;
189
190 /* bad firmware? */
191 device_id = dfu_context_get_device_id (item->device);
192 g_debug ("%s did not come back as a DFU capable device", device_id);
193 dfu_context_remove_item (item);
194 return FALSE;
195 }
196
197 static void
198 dfu_context_device_state_cb (DfuDevice *device, DfuState state, DfuContext *context)
199 {
200 g_autofree gchar *device_id = NULL;
201 device_id = dfu_context_get_device_id (device);
202 g_debug ("%s state now: %s", device_id, dfu_state_to_string (state));
203 g_signal_emit (context, signals[SIGNAL_DEVICE_CHANGED], 0, device);
204 }
205
206 static void
207 dfu_context_device_added_cb (GUsbContext *usb_context,
208 GUsbDevice *usb_device,
209 DfuContext *context)
210 {
211 DfuContextPrivate *priv = GET_PRIVATE (context);
212 DfuDevice *device;
213 DfuContextItem *item;
214 const gchar *platform_id;
215 g_autofree gchar *device_id = NULL;
216 g_autoptr(GError) error = NULL;
217
218 /* are we waiting for this device to come back? */
219 platform_id = g_usb_device_get_platform_id (usb_device);
220 item = dfu_context_find_item_by_platform_id (context, platform_id);
221 if (item != NULL) {
222 device_id = dfu_context_get_device_id (item->device);
223 if (item->timeout_id > 0) {
224 g_debug ("cancelling the remove timeout");
225 g_source_remove (item->timeout_id);
226 item->timeout_id = 0;
227 }
228
229 /* try and be helpful; we may be a daemon like fwupd watching a
230 * DFU device after dfu-tool or dfu-util has detached the
231 * device on th command line */
232 if (!dfu_device_set_new_usb_dev (item->device, usb_device, NULL, &error))
233 g_warning ("Failed to set new device: %s", error->message);
234
235 /* inform the UI */
236 g_signal_emit (context, signals[SIGNAL_DEVICE_CHANGED], 0, item->device);
237 g_debug ("device %s came back", device_id);
238 return;
239 }
240
241 /* is this a DFU-capable device */
242 device = dfu_device_new (usb_device);
243 if (device == NULL) {
244 g_debug ("device was not DFU capable");
245 return;
246 }
247
248 /* add */
249 item = g_new0 (DfuContextItem, 1);
250 item->context = context;
251 item->device = device;
252 item->state_change_id =
253 g_signal_connect (item->device, "state-changed",
254 G_CALLBACK (dfu_context_device_state_cb), context);
255 g_ptr_array_add (priv->devices, item);
256 g_signal_emit (context, signals[SIGNAL_DEVICE_ADDED], 0, device);
257 device_id = dfu_context_get_device_id (item->device);
258 g_debug ("device %s was added", device_id);
259 }
260
261 static void
262 dfu_context_device_removed_cb (GUsbContext *usb_context,
263 GUsbDevice *usb_device,
264 DfuContext *context)
265 {
266 DfuContextPrivate *priv = GET_PRIVATE (context);
267 DfuContextItem *item;
268 const gchar *platform_id;
269
270 /* find the item */
271 platform_id = g_usb_device_get_platform_id (usb_device);
272 item = dfu_context_find_item_by_platform_id (context, platform_id);
273 if (item == NULL)
274 return;
275
276 /* mark the backing USB device as invalid */
277 dfu_device_set_new_usb_dev (item->device, NULL, NULL, NULL);
278
279 /* this item has just detached */
280 if (item->timeout_id > 0)
281 g_source_remove (item->timeout_id);
282 item->timeout_id =
283 g_timeout_add (priv->timeout, dfu_context_device_timeout_cb, item);
284 }
285
286 static void
287 dfu_context_set_usb_context (DfuContext *context, GUsbContext *usb_ctx)
288 {
289 DfuContextPrivate *priv = GET_PRIVATE (context);
290 priv->usb_ctx = g_object_ref (usb_ctx);
291 g_signal_connect (priv->usb_ctx, "device-added",
292 G_CALLBACK (dfu_context_device_added_cb), context);
293 g_signal_connect (priv->usb_ctx, "device-removed",
294 G_CALLBACK (dfu_context_device_removed_cb), context);
295 }
296
297 static void
298 dfu_context_init (DfuContext *context)
299 {
300 DfuContextPrivate *priv = GET_PRIVATE (context);
301 priv->timeout = 5000;
302 priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_context_device_free);
303 }
304
305 static void
306 dfu_context_finalize (GObject *object)
307 {
308 DfuContext *context = DFU_CONTEXT (object);
309 DfuContextPrivate *priv = GET_PRIVATE (context);
310
311 g_ptr_array_unref (priv->devices);
312 g_object_unref (priv->usb_ctx);
313
314 G_OBJECT_CLASS (dfu_context_parent_class)->finalize (object);
315 }
316
317 /**
318 * dfu_context_new:
319 *
320 * Creates a new DFU context object.
321 *
322 * Return value: a new #DfuContext
323 *
324 * Since: 0.5.4
325 **/
326 DfuContext *
327 dfu_context_new (void)
328 {
329 DfuContext *context;
330 g_autoptr(GUsbContext) usb_ctx = g_usb_context_new (NULL);
331 context = g_object_new (DFU_TYPE_CONTEXT, NULL);
332 dfu_context_set_usb_context (context, usb_ctx);
333 return context;
334 }
335
336 /**
337 * dfu_context_new_with_context:
338 * @usb_ctx: a #DfuContext
339 *
340 * Creates a new DFU context object.
341 *
342 * Return value: a new #DfuContext
343 *
344 * Since: 0.7.6
345 **/
346 DfuContext *
347 dfu_context_new_with_context (GUsbContext *usb_ctx)
348 {
349 DfuContext *context;
350 g_return_val_if_fail (G_USB_IS_CONTEXT (usb_ctx), NULL);
351 context = g_object_new (DFU_TYPE_CONTEXT, NULL);
352 dfu_context_set_usb_context (context, usb_ctx);
353 return context;
354 }
355
356 /**
357 * dfu_context_get_timeout:
358 * @context: a #DfuContext
359 *
360 * Gets the wait-for-replug timeout.
361 *
362 * Return value: value in milliseconds
363 *
364 * Since: 0.5.4
365 **/
366 guint
367 dfu_context_get_timeout (DfuContext *context)
368 {
369 DfuContextPrivate *priv = GET_PRIVATE (context);
370 g_return_val_if_fail (DFU_IS_CONTEXT (context), 0);
371 return priv->timeout;
372 }
373
374
375 /**
376 * dfu_context_set_timeout:
377 * @context: a #DfuContext
378 * @timeout: a timeout in milliseconds
379 *
380 * Sets the wait-for-replug timeout.
381 * This is the longest we will wait for a device to re-enumerate after
382 * disconnecting. Using longer values will result in any UI not updating in a
383 * good time, but using too short values will result in devices being removed
384 * and re-added as different #DfuDevice's.
385 *
386 * Since: 0.5.4
387 **/
388 void
389 dfu_context_set_timeout (DfuContext *context, guint timeout)
390 {
391 DfuContextPrivate *priv = GET_PRIVATE (context);
392 g_return_if_fail (DFU_IS_CONTEXT (context));
393 priv->timeout = timeout;
394 }
395
396
397 /**
398 * dfu_context_enumerate:
399 * @context: a #DfuContext
400 * @error: a #GError, or %NULL
401 *
402 * Opens a DFU-capable context.
403 *
404 * Return value: %TRUE for success
405 *
406 * Since: 0.5.4
407 **/
408 gboolean
409 dfu_context_enumerate (DfuContext *context, GError **error)
410 {
411 DfuContextPrivate *priv = GET_PRIVATE (context);
412 g_return_val_if_fail (DFU_IS_CONTEXT (context), FALSE);
413 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
414 g_usb_context_enumerate (priv->usb_ctx);
415 return TRUE;
416 }
417
418 /**
419 * dfu_context_get_devices:
420 * @context: a #DfuContext
421 *
422 * Gets all the DFU-capable devices on the system.
423 *
424 * Return value: (element-type DfuDevice) (transfer container): array of devices
425 *
426 * Since: 0.5.4
427 **/
428 GPtrArray *
429 dfu_context_get_devices (DfuContext *context)
430 {
431 DfuContextPrivate *priv = GET_PRIVATE (context);
432 DfuContextItem *item;
433 GPtrArray *devices;
434 guint i;
435
436 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
437
438 devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
439 for (i = 0; i < priv->devices->len; i++) {
440 item = g_ptr_array_index (priv->devices, i);
441 g_ptr_array_add (devices, g_object_ref (item->device));
442 }
443 return devices;
444 }
445
446 /**
447 * dfu_context_get_device_by_vid_pid:
448 * @context: a #DfuContext
449 * @vid: a vendor ID
450 * @pid: a product ID
451 * @error: a #GError, or %NULL
452 *
453 * Finds a device in the context with a specific vendor:product ID.
454 * An error is returned if more than one device matches.
455 *
456 * Return value: (transfer full): a #DfuDevice for success, or %NULL for an error
457 *
458 * Since: 0.5.4
459 **/
460 DfuDevice *
461 dfu_context_get_device_by_vid_pid (DfuContext *context,
462 guint16 vid, guint16 pid,
463 GError **error)
464 {
465 DfuContextPrivate *priv = GET_PRIVATE (context);
466 DfuContextItem *item;
467 DfuDevice *device = NULL;
468 GUsbDevice *dev;
469 guint i;
470
471 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
472 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
473
474 /* search all devices */
475 for (i = 0; i < priv->devices->len; i++) {
476
477 /* match */
478 item = g_ptr_array_index (priv->devices, i);
479 dev = dfu_device_get_usb_dev (item->device);
480 if (g_usb_device_get_vid (dev) == vid &&
481 g_usb_device_get_pid (dev) == pid) {
482 if (device != NULL) {
483 g_set_error (error,
484 DFU_ERROR,
485 DFU_ERROR_INVALID_DEVICE,
486 "multiple device matches for %04x:%04x",
487 vid, pid);
488 return NULL;
489 }
490 device = item->device;
491 continue;
492 }
493 }
494 if (device == NULL) {
495 g_set_error (error,
496 DFU_ERROR,
497 DFU_ERROR_NOT_FOUND,
498 "no device matches for %04x:%04x",
499 vid, pid);
500 return NULL;
501 }
502 return g_object_ref (device);
503 }
504
505 /**
506 * dfu_context_get_device_by_platform_id:
507 * @context: a #DfuContext
508 * @platform_id: a platform ID
509 * @error: a #GError, or %NULL
510 *
511 * Finds a device in the context with a specific platform ID.
512 *
513 * Return value: (transfer full): a #DfuDevice for success, or %NULL for an error
514 *
515 * Since: 0.5.4
516 **/
517 DfuDevice *
518 dfu_context_get_device_by_platform_id (DfuContext *context,
519 const gchar *platform_id,
520 GError **error)
521 {
522 DfuContextPrivate *priv = GET_PRIVATE (context);
523 DfuContextItem *item;
524 guint i;
525
526 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
527 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
528
529 /* search all devices */
530 for (i = 0; i < priv->devices->len; i++) {
531 item = g_ptr_array_index (priv->devices, i);
532 if (g_strcmp0 (dfu_device_get_platform_id (item->device),
533 platform_id) == 0) {
534 return g_object_ref (item->device);
535 }
536 }
537 g_set_error (error,
538 DFU_ERROR,
539 DFU_ERROR_NOT_FOUND,
540 "no device matches for %s",
541 platform_id);
542 return NULL;
543 }
544
545 /**
546 * dfu_context_get_device_default:
547 * @context: a #DfuContext
548 * @error: a #GError, or %NULL
549 *
550 * Gets the default device in the context.
551 * An error is returned if more than one device exists.
552 *
553 * Return value: (transfer full): a #DfuDevice for success, or %NULL for an error
554 *
555 * Since: 0.5.4
556 **/
557 DfuDevice *
558 dfu_context_get_device_default (DfuContext *context, GError **error)
559 {
560 DfuContextPrivate *priv = GET_PRIVATE (context);
561 DfuContextItem *item;
562
563 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
564 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
565
566 /* none */
567 if (priv->devices->len == 0) {
568 g_set_error_literal (error,
569 DFU_ERROR,
570 DFU_ERROR_NOT_FOUND,
571 "no attached DFU device");
572 return NULL;
573 }
574
575 /* multiple */
576 if (priv->devices->len > 1) {
577 g_set_error_literal (error,
578 DFU_ERROR,
579 DFU_ERROR_INVALID_DEVICE,
580 "more than one attached DFU device");
581 return NULL;
582 }
583 item = g_ptr_array_index (priv->devices, 0);
584 return g_object_ref (item->device);
585 }
+0
-78
libdfu/dfu-context.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_CONTEXT_H
22 #define __DFU_CONTEXT_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-device.h"
29
30 G_BEGIN_DECLS
31
32 #define DFU_TYPE_CONTEXT (dfu_context_get_type ())
33 G_DECLARE_DERIVABLE_TYPE (DfuContext, dfu_context, DFU, CONTEXT, GObject)
34
35 struct _DfuContextClass
36 {
37 GObjectClass parent_class;
38 void (*device_added) (DfuContext *context,
39 DfuDevice *device);
40 void (*device_removed) (DfuContext *context,
41 DfuDevice *device);
42 void (*device_changed) (DfuContext *context,
43 DfuDevice *device);
44 /*< private >*/
45 /* Padding for future expansion */
46 void (*_dfu_context_reserved1) (void);
47 void (*_dfu_context_reserved2) (void);
48 void (*_dfu_context_reserved3) (void);
49 void (*_dfu_context_reserved4) (void);
50 void (*_dfu_context_reserved5) (void);
51 void (*_dfu_context_reserved6) (void);
52 void (*_dfu_context_reserved7) (void);
53 void (*_dfu_context_reserved8) (void);
54 void (*_dfu_context_reserved9) (void);
55 };
56
57 DfuContext *dfu_context_new (void);
58 DfuContext *dfu_context_new_with_context (GUsbContext *usb_ctx);
59 gboolean dfu_context_enumerate (DfuContext *context,
60 GError **error);
61 GPtrArray *dfu_context_get_devices (DfuContext *context);
62 guint dfu_context_get_timeout (DfuContext *context);
63 void dfu_context_set_timeout (DfuContext *context,
64 guint timeout);
65 DfuDevice *dfu_context_get_device_by_vid_pid (DfuContext *context,
66 guint16 vid,
67 guint16 pid,
68 GError **error);
69 DfuDevice *dfu_context_get_device_by_platform_id (DfuContext *context,
70 const gchar *platform_id,
71 GError **error);
72 DfuDevice *dfu_context_get_device_default (DfuContext *context,
73 GError **error);
74
75 G_END_DECLS
76
77 #endif /* __DFU_CONTEXT_H */
+0
-54
libdfu/dfu-device-private.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_DEVICE_PRIVATE_H
22 #define __DFU_DEVICE_PRIVATE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-device.h"
29
30 G_BEGIN_DECLS
31
32 #define DFU_DEVICE_REPLUG_TIMEOUT 5000 /* ms */
33
34 GUsbDevice *dfu_device_get_usb_dev (DfuDevice *device);
35
36 gboolean dfu_device_has_dfuse_support (DfuDevice *device);
37
38 void dfu_device_error_fixup (DfuDevice *device,
39 GCancellable *cancellable,
40 GError **error);
41 guint dfu_device_get_download_timeout (DfuDevice *device);
42 gchar *dfu_device_get_quirks_as_string (DfuDevice *device);
43 gboolean dfu_device_set_new_usb_dev (DfuDevice *device,
44 GUsbDevice *dev,
45 GCancellable *cancellable,
46 GError **error);
47 gboolean dfu_device_ensure_interface (DfuDevice *device,
48 GCancellable *cancellable,
49 GError **error);
50
51 G_END_DECLS
52
53 #endif /* __DFU_DEVICE_PRIVATE_H */
+0
-2257
libdfu/dfu-device.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-device
23 * @short_description: Object representing a DFU-capable device
24 *
25 * This object allows two things:
26 *
27 * - Downloading from the host to the device, optionally with
28 * verification using a DFU or DfuSe firmware file.
29 *
30 * - Uploading from the device to the host to a DFU or DfuSe firmware
31 * file. The file format is chosen automatically, with DfuSe being
32 * chosen if the device contains more than one target.
33 *
34 * See also: #DfuTarget, #DfuFirmware
35 */
36
37 #include "config.h"
38
39 #include <string.h>
40
41 #include "dfu-common.h"
42 #include "dfu-device-private.h"
43 #include "dfu-error.h"
44 #include "dfu-target-private.h"
45
46 static void dfu_device_finalize (GObject *object);
47
48 typedef struct {
49 DfuDeviceAttributes attributes;
50 DfuDeviceQuirks quirks;
51 DfuMode mode;
52 DfuState state;
53 DfuStatus status;
54 DfuAction action_last;
55 GPtrArray *targets;
56 GUsbDevice *dev;
57 gboolean open_new_dev; /* if set new GUsbDevice */
58 gboolean dfuse_supported;
59 gboolean done_upload_or_download;
60 gboolean claimed_interface;
61 gchar *display_name;
62 gchar *serial_number;
63 gchar *platform_id;
64 guint16 version;
65 guint16 runtime_pid;
66 guint16 runtime_vid;
67 guint16 runtime_release;
68 guint16 transfer_size;
69 guint8 iface_number;
70 guint dnload_timeout;
71 guint timeout_ms;
72 } DfuDevicePrivate;
73
74 enum {
75 SIGNAL_STATUS_CHANGED,
76 SIGNAL_STATE_CHANGED,
77 SIGNAL_PERCENTAGE_CHANGED,
78 SIGNAL_ACTION_CHANGED,
79 SIGNAL_LAST
80 };
81
82 static guint signals [SIGNAL_LAST] = { 0 };
83
84 G_DEFINE_TYPE_WITH_PRIVATE (DfuDevice, dfu_device, G_TYPE_OBJECT)
85 #define GET_PRIVATE(o) (dfu_device_get_instance_private (o))
86
87 static void
88 dfu_device_class_init (DfuDeviceClass *klass)
89 {
90 GObjectClass *object_class = G_OBJECT_CLASS (klass);
91
92 /**
93 * DfuDevice::status-changed:
94 * @device: the #DfuDevice instance that emitted the signal
95 * @status: the new #DfuStatus
96 *
97 * The ::status-changed signal is emitted when the status changes.
98 *
99 * Since: 0.5.4
100 **/
101 signals [SIGNAL_STATUS_CHANGED] =
102 g_signal_new ("status-changed",
103 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
104 G_STRUCT_OFFSET (DfuDeviceClass, status_changed),
105 NULL, NULL, g_cclosure_marshal_VOID__UINT,
106 G_TYPE_NONE, 1, G_TYPE_UINT);
107
108 /**
109 * DfuDevice::state-changed:
110 * @device: the #DfuDevice instance that emitted the signal
111 * @state: the new #DfuState
112 *
113 * The ::state-changed signal is emitted when the state changes.
114 *
115 * Since: 0.5.4
116 **/
117 signals [SIGNAL_STATE_CHANGED] =
118 g_signal_new ("state-changed",
119 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
120 G_STRUCT_OFFSET (DfuDeviceClass, state_changed),
121 NULL, NULL, g_cclosure_marshal_VOID__UINT,
122 G_TYPE_NONE, 1, G_TYPE_UINT);
123
124 /**
125 * DfuDevice::percentage-changed:
126 * @device: the #DfuDevice instance that emitted the signal
127 * @percentage: the new percentage
128 *
129 * The ::percentage-changed signal is emitted when the percentage changes.
130 *
131 * Since: 0.5.4
132 **/
133 signals [SIGNAL_PERCENTAGE_CHANGED] =
134 g_signal_new ("percentage-changed",
135 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
136 G_STRUCT_OFFSET (DfuDeviceClass, percentage_changed),
137 NULL, NULL, g_cclosure_marshal_VOID__UINT,
138 G_TYPE_NONE, 1, G_TYPE_UINT);
139
140 /**
141 * DfuDevice::action-changed:
142 * @device: the #DfuDevice instance that emitted the signal
143 * @action: the new #DfuAction
144 *
145 * The ::action-changed signal is emitted when the high level action changes.
146 *
147 * Since: 0.7.5
148 **/
149 signals [SIGNAL_ACTION_CHANGED] =
150 g_signal_new ("action-changed",
151 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
152 G_STRUCT_OFFSET (DfuDeviceClass, action_changed),
153 NULL, NULL, g_cclosure_marshal_VOID__UINT,
154 G_TYPE_NONE, 1, G_TYPE_UINT);
155
156 object_class->finalize = dfu_device_finalize;
157 }
158
159 static void
160 dfu_device_init (DfuDevice *device)
161 {
162 DfuDevicePrivate *priv = GET_PRIVATE (device);
163 priv->iface_number = 0xff;
164 priv->runtime_pid = 0xffff;
165 priv->runtime_vid = 0xffff;
166 priv->runtime_release = 0xffff;
167 priv->state = DFU_STATE_APP_IDLE;
168 priv->status = DFU_STATUS_OK;
169 priv->targets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
170 priv->timeout_ms = 1500;
171 priv->transfer_size = 64;
172 }
173
174 static void
175 dfu_device_set_action (DfuDevice *device, DfuAction action)
176 {
177 DfuDevicePrivate *priv = GET_PRIVATE (device);
178 if (action == priv->action_last)
179 return;
180 g_signal_emit (device, signals[SIGNAL_ACTION_CHANGED], 0, action);
181 priv->action_last = action;
182 }
183
184 /**
185 * dfu_device_get_transfer_size:
186 * @device: a #GUsbDevice
187 *
188 * Gets the transfer size in bytes.
189 *
190 * Return value: packet size, or 0 for unknown
191 *
192 * Since: 0.5.4
193 **/
194 guint16
195 dfu_device_get_transfer_size (DfuDevice *device)
196 {
197 DfuDevicePrivate *priv = GET_PRIVATE (device);
198 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
199 return priv->transfer_size;
200 }
201
202 /**
203 * dfu_device_get_version:
204 * @device: a #GUsbDevice
205 *
206 * Gets the DFU specification version supported by the device.
207 *
208 * Return value: integer, or 0 for unknown, e.g. %DFU_VERSION_DFU_1_1
209 *
210 * Since: 0.7.2
211 **/
212 guint16
213 dfu_device_get_version (DfuDevice *device)
214 {
215 DfuDevicePrivate *priv = GET_PRIVATE (device);
216 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
217 return priv->version;
218 }
219
220 /**
221 * dfu_device_get_download_timeout:
222 * @device: a #GUsbDevice
223 *
224 * Gets the download timeout in ms.
225 *
226 * Return value: delay, or 0 for unknown
227 *
228 * Since: 0.5.4
229 **/
230 guint
231 dfu_device_get_download_timeout (DfuDevice *device)
232 {
233 DfuDevicePrivate *priv = GET_PRIVATE (device);
234 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
235 return priv->dnload_timeout;
236 }
237
238 /**
239 * dfu_device_set_transfer_size:
240 * @device: a #GUsbDevice
241 * @transfer_size: maximum packet size
242 *
243 * Sets the transfer size in bytes.
244 *
245 * Since: 0.5.4
246 **/
247 void
248 dfu_device_set_transfer_size (DfuDevice *device, guint16 transfer_size)
249 {
250 DfuDevicePrivate *priv = GET_PRIVATE (device);
251 g_return_if_fail (DFU_IS_DEVICE (device));
252 priv->transfer_size = transfer_size;
253 }
254
255 static void
256 dfu_device_finalize (GObject *object)
257 {
258 DfuDevice *device = DFU_DEVICE (object);
259 DfuDevicePrivate *priv = GET_PRIVATE (device);
260
261 /* don't rely on this */
262 if (priv->dev != NULL)
263 g_usb_device_close (priv->dev, NULL);
264
265 g_free (priv->display_name);
266 g_free (priv->serial_number);
267 g_free (priv->platform_id);
268 g_ptr_array_unref (priv->targets);
269
270 G_OBJECT_CLASS (dfu_device_parent_class)->finalize (object);
271 }
272
273 typedef struct __attribute__((packed)) {
274 guint8 bLength;
275 guint8 bDescriptorType;
276 guint8 bmAttributes;
277 guint16 wDetachTimeOut;
278 guint16 wTransferSize;
279 guint16 bcdDFUVersion;
280 } DfuFuncDescriptor;
281
282 static void
283 dfu_device_parse_iface_data (DfuDevice *device, GBytes *iface_data)
284 {
285 DfuDevicePrivate *priv = GET_PRIVATE (device);
286 const DfuFuncDescriptor *desc;
287 gsize iface_data_length;
288
289 /* parse the functional descriptor */
290 desc = g_bytes_get_data (iface_data, &iface_data_length);
291 if (iface_data_length != 0x09) {
292 g_warning ("interface found, but not interface data");
293 return;
294 }
295
296 /* check sanity */
297 if (desc->bLength != 0x09) {
298 g_warning ("DFU interface data has incorrect length: 0x%02x",
299 desc->bLength);
300 }
301
302 /* check transfer size */
303 priv->transfer_size = desc->wTransferSize;
304 if (priv->transfer_size == 0x0000) {
305 g_warning ("DFU transfer size invalid, using default: 0x%04x",
306 desc->wTransferSize);
307 priv->transfer_size = 64;
308 }
309
310 /* check DFU version */
311 priv->version = GUINT16_FROM_LE (desc->bcdDFUVersion);
312 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION) {
313 g_debug ("ignoring quirked DFU version");
314 } else {
315 if (priv->version == DFU_VERSION_DFU_1_0 ||
316 priv->version == DFU_VERSION_DFU_1_1) {
317 g_debug ("basic DFU, no DfuSe support");
318 priv->dfuse_supported = FALSE;
319 } else if (priv->version == DFU_VERSION_DFUSE) {
320 g_debug ("DfuSe support");
321 priv->dfuse_supported = TRUE;
322 } else {
323 g_warning ("DFU version is invalid: 0x%04x",
324 priv->version);
325 }
326 }
327
328 /* ST-specific */
329 if (priv->dfuse_supported &&
330 desc->bmAttributes & DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE)
331 priv->transfer_size = 0x1000;
332
333 /* get attributes about the DFU operation */
334 priv->attributes = desc->bmAttributes;
335 }
336
337 static gboolean
338 dfu_device_update_from_iface (DfuDevice *device, GUsbInterface *iface)
339 {
340 DfuMode target_mode = DFU_MODE_UNKNOWN;
341 DfuDevicePrivate *priv = GET_PRIVATE (device);
342
343 /* runtime */
344 if (g_usb_interface_get_protocol (iface) == 0x01)
345 target_mode = DFU_MODE_RUNTIME;
346
347 /* DFU */
348 if (g_usb_interface_get_protocol (iface) == 0x02)
349 target_mode = DFU_MODE_DFU;
350
351 /* the DSO Nano has uses 0 instead of 2 when in DFU target_mode */
352 if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO) &&
353 g_usb_interface_get_protocol (iface) == 0x00)
354 target_mode = DFU_MODE_DFU;
355
356 /* nothing found */
357 if (target_mode == DFU_MODE_UNKNOWN)
358 return FALSE;
359
360 /* in DFU mode, the interface is supposed to be 0 */
361 if (target_mode == DFU_MODE_DFU && g_usb_interface_get_number (iface) != 0)
362 g_warning ("iface has to be 0 in DFU mode, got 0x%02i",
363 g_usb_interface_get_number (iface));
364
365 /* some devices set the wrong mode */
366 if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_FORCE_DFU_MODE))
367 target_mode = DFU_MODE_DFU;
368
369 /* save for reset */
370 if (target_mode == DFU_MODE_RUNTIME ||
371 (priv->quirks & DFU_DEVICE_QUIRK_NO_PID_CHANGE)) {
372 priv->runtime_vid = g_usb_device_get_vid (priv->dev);
373 priv->runtime_pid = g_usb_device_get_pid (priv->dev);
374 priv->runtime_release = g_usb_device_get_release (priv->dev);
375 }
376
377 priv->mode = target_mode;
378 return TRUE;
379 }
380
381 static gboolean
382 dfu_device_add_targets (DfuDevice *device)
383 {
384 DfuDevicePrivate *priv = GET_PRIVATE (device);
385 guint i;
386 GUsbInterface *iface;
387 g_autoptr(GPtrArray) ifaces = NULL;
388
389 /* add all DFU-capable targets */
390 ifaces = g_usb_device_get_interfaces (priv->dev, NULL);
391 if (ifaces == NULL)
392 return FALSE;
393 g_ptr_array_set_size (priv->targets, 0);
394 for (i = 0; i < ifaces->len; i++) {
395 GBytes *iface_data = NULL;
396 DfuTarget *target;
397 iface = g_ptr_array_index (ifaces, i);
398 if (g_usb_interface_get_class (iface) != G_USB_DEVICE_CLASS_APPLICATION_SPECIFIC)
399 continue;
400 if (g_usb_interface_get_subclass (iface) != 0x01)
401 continue;
402 target = dfu_target_new (device, iface);
403 if (target == NULL)
404 continue;
405
406 /* add target */
407 priv->iface_number = g_usb_interface_get_number (iface);
408 g_ptr_array_add (priv->targets, target);
409 dfu_device_update_from_iface (device, iface);
410
411 /* parse any interface data */
412 iface_data = g_usb_interface_get_extra (iface);
413 if (g_bytes_get_size (iface_data) > 0)
414 dfu_device_parse_iface_data (device, iface_data);
415 }
416
417 /* the device has no DFU runtime, so cheat */
418 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
419 if (priv->targets->len == 0) {
420 g_debug ("no DFU runtime, so faking device");
421 priv->iface_number = 0xff;
422 priv->runtime_vid = g_usb_device_get_vid (priv->dev);
423 priv->runtime_pid = g_usb_device_get_pid (priv->dev);
424 priv->runtime_release = g_usb_device_get_release (priv->dev);
425 priv->attributes = DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD |
426 DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD;
427 }
428 return TRUE;
429 }
430
431 return priv->targets->len > 0;
432 }
433
434 /**
435 * dfu_device_has_quirk: (skip)
436 * @device: A #DfuDevice
437 * @quirk: A #DfuDeviceQuirks
438 *
439 * Returns if a device has a specific quirk
440 *
441 * Return value: %TRUE if the device has this quirk
442 *
443 * Since: 0.5.4
444 **/
445 gboolean
446 dfu_device_has_quirk (DfuDevice *device, DfuDeviceQuirks quirk)
447 {
448 DfuDevicePrivate *priv = GET_PRIVATE (device);
449 g_return_val_if_fail (DFU_IS_DEVICE (device), 0x0);
450 return (priv->quirks & quirk) > 0;
451 }
452
453 /**
454 * dfu_device_can_upload:
455 * @device: a #GUsbDevice
456 *
457 * Gets if the device can upload.
458 *
459 * Return value: %TRUE if the device can upload from device to host
460 *
461 * Since: 0.5.4
462 **/
463 gboolean
464 dfu_device_can_upload (DfuDevice *device)
465 {
466 DfuDevicePrivate *priv = GET_PRIVATE (device);
467 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
468 return (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD) > 0;
469 }
470
471 /**
472 * dfu_device_can_download:
473 * @device: a #GUsbDevice
474 *
475 * Gets if the device can download.
476 *
477 * Return value: %TRUE if the device can download from host to device
478 *
479 * Since: 0.5.4
480 **/
481 gboolean
482 dfu_device_can_download (DfuDevice *device)
483 {
484 DfuDevicePrivate *priv = GET_PRIVATE (device);
485 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
486 return (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD) > 0;
487 }
488
489 /**
490 * dfu_device_set_timeout:
491 * @device: a #DfuDevice
492 * @timeout_ms: the timeout in ms
493 *
494 * Sets the USB timeout to use when contacting the USB device.
495 *
496 * Since: 0.5.4
497 **/
498 void
499 dfu_device_set_timeout (DfuDevice *device, guint timeout_ms)
500 {
501 DfuDevicePrivate *priv = GET_PRIVATE (device);
502 g_return_if_fail (DFU_IS_DEVICE (device));
503 priv->timeout_ms = timeout_ms;
504 }
505
506 /**
507 * dfu_device_get_mode:
508 * @device: a #GUsbDevice
509 *
510 * Gets the device mode.
511 *
512 * Return value: enumerated mode, e.g. %DFU_MODE_RUNTIME
513 *
514 * Since: 0.5.4
515 **/
516 DfuMode
517 dfu_device_get_mode (DfuDevice *device)
518 {
519 DfuDevicePrivate *priv = GET_PRIVATE (device);
520 g_return_val_if_fail (DFU_IS_DEVICE (device), DFU_MODE_UNKNOWN);
521 return priv->mode;
522 }
523
524 /**
525 * dfu_device_get_timeout:
526 * @device: a #GUsbDevice
527 *
528 * Gets the device timeout.
529 *
530 * Return value: enumerated timeout in ms
531 *
532 * Since: 0.5.4
533 **/
534 guint
535 dfu_device_get_timeout (DfuDevice *device)
536 {
537 DfuDevicePrivate *priv = GET_PRIVATE (device);
538 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
539 return priv->timeout_ms;
540 }
541
542 /**
543 * dfu_device_get_state:
544 * @device: a #GUsbDevice
545 *
546 * Gets the device state.
547 *
548 * Return value: enumerated state, e.g. %DFU_STATE_DFU_UPLOAD_IDLE
549 *
550 * Since: 0.5.4
551 **/
552 DfuState
553 dfu_device_get_state (DfuDevice *device)
554 {
555 DfuDevicePrivate *priv = GET_PRIVATE (device);
556 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
557 return priv->state;
558 }
559
560 /**
561 * dfu_device_get_status:
562 * @device: a #GUsbDevice
563 *
564 * Gets the device status.
565 *
566 * Return value: enumerated status, e.g. %DFU_STATUS_ERR_ADDRESS
567 *
568 * Since: 0.5.4
569 **/
570 DfuStatus
571 dfu_device_get_status (DfuDevice *device)
572 {
573 DfuDevicePrivate *priv = GET_PRIVATE (device);
574 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
575 return priv->status;
576 }
577
578 /**
579 * dfu_device_has_attribute: (skip)
580 * @device: A #DfuDevice
581 * @attribute: A #DfuDeviceAttributes, e.g. %DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD
582 *
583 * Returns if an attribute set for the device.
584 *
585 * Return value: %TRUE if the attribute is set
586 *
587 * Since: 0.5.4
588 **/
589 gboolean
590 dfu_device_has_attribute (DfuDevice *device, DfuDeviceAttributes attribute)
591 {
592 DfuDevicePrivate *priv = GET_PRIVATE (device);
593 g_return_val_if_fail (DFU_IS_DEVICE (device), 0x0);
594 return (priv->attributes & attribute) > 0;
595 }
596
597 /**
598 * dfu_device_has_dfuse_support:
599 * @device: A #DfuDevice
600 *
601 * Returns is DfuSe is supported on a device.
602 *
603 * Return value: %TRUE for DfuSe
604 *
605 * Since: 0.5.4
606 **/
607 gboolean
608 dfu_device_has_dfuse_support (DfuDevice *device)
609 {
610 DfuDevicePrivate *priv = GET_PRIVATE (device);
611 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
612 return priv->dfuse_supported;
613 }
614
615 static void
616 dfu_device_set_quirks (DfuDevice *device)
617 {
618 DfuDevicePrivate *priv = GET_PRIVATE (device);
619 guint16 vid, pid, release;
620
621 vid = g_usb_device_get_vid (priv->dev);
622 pid = g_usb_device_get_pid (priv->dev);
623 release = g_usb_device_get_release (priv->dev);
624
625 /* on PC platforms the DW1820A firmware is loaded at runtime and can't
626 * be stored on the device itself as the flash chip is unpopulated */
627 if (vid == 0x0a5c && pid == 0x6412)
628 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_RUNTIME;
629
630 /* Openmoko Freerunner / GTA02 */
631 if ((vid == 0x1d50 || vid == 0x1457) &&
632 pid >= 0x5117 && pid <= 0x5126)
633 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT |
634 DFU_DEVICE_QUIRK_NO_PID_CHANGE |
635 DFU_DEVICE_QUIRK_NO_DFU_RUNTIME |
636 DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD;
637
638 /* OpenPCD Reader */
639 if (vid == 0x16c0 && pid == 0x076b)
640 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
641
642 /* SIMtrace */
643 if (vid == 0x16c0 && pid == 0x0762)
644 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
645
646 /* OpenPICC */
647 if (vid == 0x16c0 && pid == 0x076c)
648 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
649
650 /* Siemens AG, PXM 40 & PXM 50 */
651 if (vid == 0x0908 && (pid == 0x02c4 || pid == 0x02c5) && release == 0x0)
652 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
653
654 /* Midiman M-Audio Transit */
655 if (vid == 0x0763 && pid == 0x2806)
656 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
657
658 /* the LPC DFU bootloader uses the wrong mode */
659 if (vid == 0x1fc9 && pid == 0x000c)
660 priv->quirks |= DFU_DEVICE_QUIRK_FORCE_DFU_MODE;
661
662 /* the Leaflabs Maple3 is known broken */
663 if (vid == 0x1eaf && pid == 0x0003 && release == 0x0200)
664 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION;
665
666 /* m-stack DFU implementation */
667 if (vid == 0x273f && pid == 0x1003)
668 priv->quirks |= DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD;
669
670 /* HydraBus */
671 if (vid == 0x1d50 && pid == 0x60a7)
672 priv->quirks |= DFU_DEVICE_QUIRK_NO_DFU_RUNTIME;
673
674 /* the DSO Nano has uses 0 instead of 2 when in DFU mode */
675 // quirks |= DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO;
676 }
677
678 /**
679 * dfu_device_new:
680 * @dev: A #GUsbDevice
681 *
682 * Creates a new DFU device object.
683 *
684 * Return value: a new #DfuDevice, or %NULL if @dev was not DFU-capable
685 *
686 * Since: 0.5.4
687 **/
688 DfuDevice *
689 dfu_device_new (GUsbDevice *dev)
690 {
691 DfuDevicePrivate *priv;
692 DfuDevice *device;
693 device = g_object_new (DFU_TYPE_DEVICE, NULL);
694 priv = GET_PRIVATE (device);
695 priv->dev = g_object_ref (dev);
696 priv->platform_id = g_strdup (g_usb_device_get_platform_id (dev));
697
698 /* set any quirks on the device before adding targets */
699 dfu_device_set_quirks (device);
700
701 /* add each alternate interface, although typically there will
702 * be only one */
703 if (!dfu_device_add_targets (device)) {
704 g_object_unref (device);
705 return NULL;
706 }
707
708 return device;
709 }
710
711 /**
712 * dfu_device_get_targets:
713 * @device: a #DfuDevice
714 *
715 * Gets all the targets for this device.
716 *
717 * Return value: (transfer none) (element-type DfuTarget): #DfuTarget, or %NULL
718 *
719 * Since: 0.5.4
720 **/
721 GPtrArray *
722 dfu_device_get_targets (DfuDevice *device)
723 {
724 DfuDevicePrivate *priv = GET_PRIVATE (device);
725 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
726 return priv->targets;
727 }
728
729 /**
730 * dfu_device_get_target_by_alt_setting:
731 * @device: a #DfuDevice
732 * @alt_setting: the setting used to find
733 * @error: a #GError, or %NULL
734 *
735 * Gets a target with a specific alternative setting.
736 *
737 * Return value: (transfer full): a #DfuTarget, or %NULL
738 *
739 * Since: 0.5.4
740 **/
741 DfuTarget *
742 dfu_device_get_target_by_alt_setting (DfuDevice *device,
743 guint8 alt_setting,
744 GError **error)
745 {
746 DfuDevicePrivate *priv = GET_PRIVATE (device);
747 DfuTarget *target;
748 guint i;
749
750 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
751 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
752
753 /* find by ID */
754 for (i = 0; i < priv->targets->len; i++) {
755 target = g_ptr_array_index (priv->targets, i);
756 if (dfu_target_get_alt_setting (target) == alt_setting)
757 return g_object_ref (target);
758 }
759
760 /* failed */
761 g_set_error (error,
762 DFU_ERROR,
763 DFU_ERROR_NOT_FOUND,
764 "No target with alt-setting %i",
765 alt_setting);
766 return NULL;
767 }
768
769 /**
770 * dfu_device_get_target_by_alt_name:
771 * @device: a #DfuDevice
772 * @alt_name: the name used to find
773 * @error: a #GError, or %NULL
774 *
775 * Gets a target with a specific alternative name.
776 *
777 * Return value: (transfer full): a #DfuTarget, or %NULL
778 *
779 * Since: 0.5.4
780 **/
781 DfuTarget *
782 dfu_device_get_target_by_alt_name (DfuDevice *device,
783 const gchar *alt_name,
784 GError **error)
785 {
786 DfuDevicePrivate *priv = GET_PRIVATE (device);
787 DfuTarget *target;
788 guint i;
789
790 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
791 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
792
793 /* find by ID */
794 for (i = 0; i < priv->targets->len; i++) {
795 target = g_ptr_array_index (priv->targets, i);
796 if (g_strcmp0 (dfu_target_get_alt_name (target, NULL), alt_name) == 0)
797 return g_object_ref (target);
798 }
799
800 /* failed */
801 g_set_error (error,
802 DFU_ERROR,
803 DFU_ERROR_NOT_FOUND,
804 "No target with alt-name %s",
805 alt_name);
806 return NULL;
807 }
808
809 /**
810 * dfu_device_get_platform_id:
811 * @device: a #DfuDevice
812 *
813 * Gets the platform ID which normally corresponds to the port in some way.
814 *
815 * Return value: string or %NULL
816 *
817 * Since: 0.5.4
818 **/
819 const gchar *
820 dfu_device_get_platform_id (DfuDevice *device)
821 {
822 DfuDevicePrivate *priv = GET_PRIVATE (device);
823 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
824 return priv->platform_id;
825 }
826
827 /**
828 * dfu_device_get_runtime_vid:
829 * @device: a #DfuDevice
830 *
831 * Gets the runtime vendor ID.
832 *
833 * Return value: vendor ID, or 0xffff for unknown
834 *
835 * Since: 0.5.4
836 **/
837 guint16
838 dfu_device_get_runtime_vid (DfuDevice *device)
839 {
840 DfuDevicePrivate *priv = GET_PRIVATE (device);
841 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
842 return priv->runtime_vid;
843 }
844
845 /**
846 * dfu_device_get_runtime_pid:
847 * @device: a #DfuDevice
848 *
849 * Gets the runtime product ID.
850 *
851 * Return value: product ID, or 0xffff for unknown
852 *
853 * Since: 0.5.4
854 **/
855 guint16
856 dfu_device_get_runtime_pid (DfuDevice *device)
857 {
858 DfuDevicePrivate *priv = GET_PRIVATE (device);
859 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
860 return priv->runtime_pid;
861 }
862
863 /**
864 * dfu_device_get_runtime_release:
865 * @device: a #DfuDevice
866 *
867 * Gets the runtime release number in BCD format.
868 *
869 * Return value: release number, or 0xffff for unknown
870 *
871 * Since: 0.5.4
872 **/
873 guint16
874 dfu_device_get_runtime_release (DfuDevice *device)
875 {
876 DfuDevicePrivate *priv = GET_PRIVATE (device);
877 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
878 return priv->runtime_release;
879 }
880
881 /**
882 * dfu_device_get_usb_dev: (skip)
883 * @device: a #DfuDevice
884 *
885 * Gets the internal USB device for the #DfuDevice.
886 *
887 * NOTE: This may change at runtime if the device is replugged or
888 * reset.
889 *
890 * Returns: (transfer none): the internal USB device
891 **/
892 GUsbDevice *
893 dfu_device_get_usb_dev (DfuDevice *device)
894 {
895 DfuDevicePrivate *priv = GET_PRIVATE (device);
896 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
897 return priv->dev;
898 }
899
900 /**
901 * dfu_device_get_display_name:
902 * @device: a #DfuDevice
903 *
904 * Gets the display name to use for the device.
905 *
906 * Return value: string or %NULL for unset
907 *
908 * Since: 0.5.4
909 **/
910 const gchar *
911 dfu_device_get_display_name (DfuDevice *device)
912 {
913 DfuDevicePrivate *priv = GET_PRIVATE (device);
914 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
915 return priv->display_name;
916 }
917
918 /**
919 * dfu_device_get_serial_number:
920 * @device: a #DfuDevice
921 *
922 * Gets the serial number for the device.
923 *
924 * Return value: string or %NULL for unset
925 *
926 * Since: 0.7.3
927 **/
928 const gchar *
929 dfu_device_get_serial_number (DfuDevice *device)
930 {
931 DfuDevicePrivate *priv = GET_PRIVATE (device);
932 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
933 return priv->serial_number;
934 }
935
936 static void
937 dfu_device_set_state (DfuDevice *device, DfuState state)
938 {
939 DfuDevicePrivate *priv = GET_PRIVATE (device);
940 if (priv->state == state)
941 return;
942 priv->state = state;
943 g_signal_emit (device, signals[SIGNAL_STATE_CHANGED], 0, state);
944 }
945
946 static void
947 dfu_device_set_status (DfuDevice *device, DfuStatus status)
948 {
949 DfuDevicePrivate *priv = GET_PRIVATE (device);
950 if (priv->status == status)
951 return;
952 priv->status = status;
953 g_signal_emit (device, signals[SIGNAL_STATUS_CHANGED], 0, status);
954 }
955
956 gboolean
957 dfu_device_ensure_interface (DfuDevice *device,
958 GCancellable *cancellable,
959 GError **error)
960 {
961 DfuDevicePrivate *priv = GET_PRIVATE (device);
962 g_autoptr(GError) error_local = NULL;
963
964 /* already done */
965 if (priv->claimed_interface)
966 return TRUE;
967
968 /* nothing set */
969 if (priv->iface_number == 0xff)
970 return TRUE;
971
972 /* ensure open */
973 if (!dfu_device_open (device,
974 DFU_DEVICE_OPEN_FLAG_NONE,
975 cancellable,
976 error)) {
977 g_prefix_error (error, "cannot claim interface %i: ",
978 priv->iface_number);
979 return FALSE;
980 }
981
982 /* claim, without detaching kernel driver */
983 if (!g_usb_device_claim_interface (priv->dev,
984 (gint) priv->iface_number,
985 0, &error_local)) {
986 g_set_error (error,
987 DFU_ERROR,
988 DFU_ERROR_INVALID_DEVICE,
989 "cannot claim interface %i: %s",
990 priv->iface_number, error_local->message);
991 return FALSE;
992 }
993
994 /* success */
995 priv->claimed_interface = TRUE;
996 return TRUE;
997 }
998
999 /**
1000 * dfu_device_refresh:
1001 * @device: a #DfuDevice
1002 * @cancellable: a #GCancellable, or %NULL
1003 * @error: a #GError, or %NULL
1004 *
1005 * Refreshes the cached properties on the DFU device.
1006 *
1007 * Return value: %TRUE for success
1008 *
1009 * Since: 0.5.4
1010 **/
1011 gboolean
1012 dfu_device_refresh (DfuDevice *device, GCancellable *cancellable, GError **error)
1013 {
1014 DfuDevicePrivate *priv = GET_PRIVATE (device);
1015 gsize actual_length = 0;
1016 guint8 buf[6];
1017 g_autoptr(GError) error_local = NULL;
1018
1019 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1020 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1021
1022 /* no backing USB device */
1023 if (priv->dev == NULL) {
1024 g_set_error (error,
1025 DFU_ERROR,
1026 DFU_ERROR_INTERNAL,
1027 "failed to refresh: no GUsbDevice for %s",
1028 priv->platform_id);
1029 return FALSE;
1030 }
1031
1032 /* the device has no DFU runtime, so cheat */
1033 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1034 g_set_error_literal (error,
1035 DFU_ERROR,
1036 DFU_ERROR_NOT_SUPPORTED,
1037 "not supported as no DFU runtime");
1038 return FALSE;
1039 }
1040
1041 /* ensure interface is claimed */
1042 if (!dfu_device_ensure_interface (device, cancellable, error))
1043 return FALSE;
1044
1045 if (!g_usb_device_control_transfer (priv->dev,
1046 G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
1047 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1048 G_USB_DEVICE_RECIPIENT_INTERFACE,
1049 DFU_REQUEST_GETSTATUS,
1050 0,
1051 priv->iface_number,
1052 buf, sizeof(buf), &actual_length,
1053 priv->timeout_ms,
1054 cancellable,
1055 &error_local)) {
1056 g_set_error (error,
1057 DFU_ERROR,
1058 DFU_ERROR_NOT_SUPPORTED,
1059 "cannot get device state: %s",
1060 error_local->message);
1061 return FALSE;
1062 }
1063 if (actual_length != 6) {
1064 g_set_error (error,
1065 DFU_ERROR,
1066 DFU_ERROR_INTERNAL,
1067 "cannot get device status, invalid size: %04x",
1068 (guint) actual_length);
1069 }
1070
1071 /* status or state changed */
1072 dfu_device_set_status (device, buf[0]);
1073 dfu_device_set_state (device, buf[4]);
1074 if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT)) {
1075 priv->dnload_timeout = 5;
1076 } else {
1077 priv->dnload_timeout = buf[1] +
1078 (((guint32) buf[2]) << 8) +
1079 (((guint32) buf[3]) << 16);
1080 }
1081 g_debug ("refreshed status=%s and state=%s (dnload=%u)",
1082 dfu_status_to_string (priv->status),
1083 dfu_state_to_string (priv->state),
1084 priv->dnload_timeout);
1085 return TRUE;
1086 }
1087
1088 /**
1089 * dfu_device_detach:
1090 * @device: a #DfuDevice
1091 * @cancellable: a #GCancellable, or %NULL
1092 * @error: a #GError, or %NULL
1093 *
1094 * Detaches the device putting it into DFU-mode.
1095 *
1096 * Return value: %TRUE for success
1097 *
1098 * Since: 0.5.4
1099 **/
1100 gboolean
1101 dfu_device_detach (DfuDevice *device, GCancellable *cancellable, GError **error)
1102 {
1103 DfuDevicePrivate *priv = GET_PRIVATE (device);
1104 g_autoptr(GError) error_local = NULL;
1105
1106 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1107 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1108
1109 /* already in DFU mode */
1110 switch (priv->state) {
1111 case DFU_STATE_APP_IDLE:
1112 case DFU_STATE_APP_DETACH:
1113 break;
1114 default:
1115 g_set_error (error,
1116 DFU_ERROR,
1117 DFU_ERROR_NOT_SUPPORTED,
1118 "Already in DFU mode");
1119 return FALSE;
1120 }
1121
1122 /* no backing USB device */
1123 if (priv->dev == NULL) {
1124 g_set_error (error,
1125 DFU_ERROR,
1126 DFU_ERROR_INTERNAL,
1127 "failed to detach: no GUsbDevice for %s",
1128 priv->platform_id);
1129 return FALSE;
1130 }
1131
1132 /* the device has no DFU runtime, so cheat */
1133 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1134 g_set_error_literal (error,
1135 DFU_ERROR,
1136 DFU_ERROR_NOT_SUPPORTED,
1137 "not supported as no DFU runtime");
1138 return FALSE;
1139 }
1140
1141 /* ensure interface is claimed */
1142 if (!dfu_device_ensure_interface (device, cancellable, error))
1143 return FALSE;
1144
1145 /* inform UI there's going to be a detach:attach */
1146 dfu_device_set_action (device, DFU_ACTION_DETACH);
1147
1148 if (!g_usb_device_control_transfer (priv->dev,
1149 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
1150 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1151 G_USB_DEVICE_RECIPIENT_INTERFACE,
1152 DFU_REQUEST_DETACH,
1153 0,
1154 priv->iface_number,
1155 NULL, 0, NULL,
1156 priv->timeout_ms,
1157 cancellable,
1158 &error_local)) {
1159 /* refresh the error code */
1160 dfu_device_error_fixup (device, cancellable, &error_local);
1161 g_set_error (error,
1162 DFU_ERROR,
1163 DFU_ERROR_NOT_SUPPORTED,
1164 "cannot detach device: %s",
1165 error_local->message);
1166 return FALSE;
1167 }
1168
1169 /* do a host reset */
1170 if ((priv->attributes & DFU_DEVICE_ATTRIBUTE_WILL_DETACH) == 0) {
1171 g_debug ("doing device reset as host will not self-reset");
1172 if (!dfu_device_reset (device, error))
1173 return FALSE;
1174 }
1175
1176 /* success */
1177 dfu_device_set_action (device, DFU_ACTION_IDLE);
1178 return TRUE;
1179 }
1180
1181 /**
1182 * dfu_device_abort:
1183 * @device: a #DfuDevice
1184 * @cancellable: a #GCancellable, or %NULL
1185 * @error: a #GError, or %NULL
1186 *
1187 * Aborts any upload or download in progress.
1188 *
1189 * Return value: %TRUE for success
1190 *
1191 * Since: 0.5.4
1192 **/
1193 gboolean
1194 dfu_device_abort (DfuDevice *device, GCancellable *cancellable, GError **error)
1195 {
1196 DfuDevicePrivate *priv = GET_PRIVATE (device);
1197 g_autoptr(GError) error_local = NULL;
1198
1199 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1200 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1201
1202 /* no backing USB device */
1203 if (priv->dev == NULL) {
1204 g_set_error (error,
1205 DFU_ERROR,
1206 DFU_ERROR_INTERNAL,
1207 "failed to abort: no GUsbDevice for %s",
1208 priv->platform_id);
1209 return FALSE;
1210 }
1211
1212 /* the device has no DFU runtime, so cheat */
1213 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1214 g_set_error_literal (error,
1215 DFU_ERROR,
1216 DFU_ERROR_NOT_SUPPORTED,
1217 "not supported as no DFU runtime");
1218 return FALSE;
1219 }
1220
1221 /* ensure interface is claimed */
1222 if (!dfu_device_ensure_interface (device, cancellable, error))
1223 return FALSE;
1224
1225 if (!g_usb_device_control_transfer (priv->dev,
1226 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
1227 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1228 G_USB_DEVICE_RECIPIENT_INTERFACE,
1229 DFU_REQUEST_ABORT,
1230 0,
1231 priv->iface_number,
1232 NULL, 0, NULL,
1233 priv->timeout_ms,
1234 cancellable,
1235 &error_local)) {
1236 /* refresh the error code */
1237 dfu_device_error_fixup (device, cancellable, &error_local);
1238 g_set_error (error,
1239 DFU_ERROR,
1240 DFU_ERROR_NOT_SUPPORTED,
1241 "cannot abort device: %s",
1242 error_local->message);
1243 return FALSE;
1244 }
1245
1246 return TRUE;
1247 }
1248
1249 /**
1250 * dfu_device_clear_status:
1251 * @device: a #DfuDevice
1252 * @cancellable: a #GCancellable, or %NULL
1253 * @error: a #GError, or %NULL
1254 *
1255 * Clears any error status on the DFU device.
1256 *
1257 * Return value: %TRUE for success
1258 *
1259 * Since: 0.5.4
1260 **/
1261 gboolean
1262 dfu_device_clear_status (DfuDevice *device, GCancellable *cancellable, GError **error)
1263 {
1264 DfuDevicePrivate *priv = GET_PRIVATE (device);
1265 g_autoptr(GError) error_local = NULL;
1266
1267 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1268 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1269
1270 /* no backing USB device */
1271 if (priv->dev == NULL) {
1272 g_set_error (error,
1273 DFU_ERROR,
1274 DFU_ERROR_INTERNAL,
1275 "failed to clear status: no GUsbDevice for %s",
1276 priv->platform_id);
1277 return FALSE;
1278 }
1279
1280 /* the device has no DFU runtime, so cheat */
1281 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1282 g_set_error_literal (error,
1283 DFU_ERROR,
1284 DFU_ERROR_NOT_SUPPORTED,
1285 "not supported as no DFU runtime");
1286 return FALSE;
1287 }
1288
1289 /* ensure interface is claimed */
1290 if (!dfu_device_ensure_interface (device, cancellable, error))
1291 return FALSE;
1292
1293 if (!g_usb_device_control_transfer (priv->dev,
1294 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
1295 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1296 G_USB_DEVICE_RECIPIENT_INTERFACE,
1297 DFU_REQUEST_CLRSTATUS,
1298 0,
1299 priv->iface_number,
1300 NULL, 0, NULL,
1301 priv->timeout_ms,
1302 cancellable,
1303 &error_local)) {
1304 /* refresh the error code */
1305 dfu_device_error_fixup (device, cancellable, &error_local);
1306 g_set_error (error,
1307 DFU_ERROR,
1308 DFU_ERROR_NOT_SUPPORTED,
1309 "cannot clear status on the device: %s",
1310 error_local->message);
1311 return FALSE;
1312 }
1313 return TRUE;
1314 }
1315
1316 /**
1317 * dfu_device_get_interface:
1318 * @device: a #DfuDevice
1319 *
1320 * Gets the interface number.
1321 *
1322 * Since: 0.5.4
1323 **/
1324 guint8
1325 dfu_device_get_interface (DfuDevice *device)
1326 {
1327 DfuDevicePrivate *priv = GET_PRIVATE (device);
1328 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xff);
1329 return priv->iface_number;
1330 }
1331
1332 /**
1333 * dfu_device_open:
1334 * @device: a #DfuDevice
1335 * @flags: #DfuDeviceOpenFlags, e.g. %DFU_DEVICE_OPEN_FLAG_NONE
1336 * @cancellable: a #GCancellable, or %NULL
1337 * @error: a #GError, or %NULL
1338 *
1339 * Opens a DFU-capable device.
1340 *
1341 * Return value: %TRUE for success
1342 *
1343 * Since: 0.5.4
1344 **/
1345 gboolean
1346 dfu_device_open (DfuDevice *device, DfuDeviceOpenFlags flags,
1347 GCancellable *cancellable, GError **error)
1348 {
1349 DfuDevicePrivate *priv = GET_PRIVATE (device);
1350 guint8 idx;
1351 g_autoptr(GError) error_local = NULL;
1352
1353 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1354 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1355
1356 /* no backing USB device */
1357 if (priv->dev == NULL) {
1358 g_set_error (error,
1359 DFU_ERROR,
1360 DFU_ERROR_INTERNAL,
1361 "failed to open: no GUsbDevice for %s",
1362 priv->platform_id);
1363 return FALSE;
1364 }
1365
1366 /* open */
1367 if (!g_usb_device_open (priv->dev, &error_local)) {
1368 if (g_error_matches (error_local,
1369 G_USB_DEVICE_ERROR,
1370 G_USB_DEVICE_ERROR_ALREADY_OPEN)) {
1371 g_debug ("device already open, ignoring");
1372 return TRUE;
1373 }
1374 if (g_error_matches (error_local,
1375 G_USB_DEVICE_ERROR,
1376 G_USB_DEVICE_ERROR_PERMISSION_DENIED)) {
1377 g_set_error (error,
1378 DFU_ERROR,
1379 DFU_ERROR_PERMISSION_DENIED,
1380 "%s", error_local->message);
1381 return FALSE;
1382 }
1383 g_set_error (error,
1384 DFU_ERROR,
1385 DFU_ERROR_INVALID_DEVICE,
1386 "cannot open device %s: %s",
1387 g_usb_device_get_platform_id (priv->dev),
1388 error_local->message);
1389 return FALSE;
1390 }
1391
1392 /* get product name if it exists */
1393 idx = g_usb_device_get_product_index (priv->dev);
1394 if (idx != 0x00)
1395 priv->display_name = g_usb_device_get_string_descriptor (priv->dev, idx, NULL);
1396
1397 /* get serial number if it exists */
1398 idx = g_usb_device_get_serial_number_index (priv->dev);
1399 if (idx != 0x00)
1400 priv->serial_number = g_usb_device_get_string_descriptor (priv->dev, idx, NULL);
1401
1402 /* the device has no DFU runtime, so cheat */
1403 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1404 priv->state = DFU_STATE_APP_IDLE;
1405 priv->status = DFU_STATUS_OK;
1406 priv->mode = DFU_MODE_RUNTIME;
1407 flags |= DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH;
1408 }
1409
1410 /* automatically abort any uploads or downloads */
1411 if ((flags & DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH) == 0) {
1412 if (!dfu_device_refresh (device, cancellable, error)) {
1413 g_usb_device_close (priv->dev, NULL);
1414 return FALSE;
1415 }
1416 switch (priv->state) {
1417 case DFU_STATE_DFU_UPLOAD_IDLE:
1418 case DFU_STATE_DFU_DNLOAD_IDLE:
1419 case DFU_STATE_DFU_DNLOAD_SYNC:
1420 g_debug ("aborting transfer %s", dfu_status_to_string (priv->status));
1421 if (!dfu_device_abort (device, cancellable, error)) {
1422 g_usb_device_close (priv->dev, NULL);
1423 return FALSE;
1424 }
1425 break;
1426 case DFU_STATE_DFU_ERROR:
1427 g_debug ("clearing error %s", dfu_status_to_string (priv->status));
1428 if (!dfu_device_clear_status (device, cancellable, error)) {
1429 g_usb_device_close (priv->dev, NULL);
1430 return FALSE;
1431 }
1432 break;
1433 default:
1434 break;
1435 }
1436 }
1437
1438 priv->open_new_dev = TRUE;
1439 return TRUE;
1440 }
1441
1442 /**
1443 * dfu_device_close:
1444 * @device: a #DfuDevice
1445 * @error: a #GError, or %NULL
1446 *
1447 * Closes a DFU device.
1448 *
1449 * Return value: %TRUE for success
1450 *
1451 * Since: 0.5.4
1452 **/
1453 gboolean
1454 dfu_device_close (DfuDevice *device, GError **error)
1455 {
1456 DfuDevicePrivate *priv = GET_PRIVATE (device);
1457 g_autoptr(GError) error_local = NULL;
1458
1459 /* no backing USB device */
1460 if (priv->dev == NULL) {
1461 g_set_error (error,
1462 DFU_ERROR,
1463 DFU_ERROR_INTERNAL,
1464 "failed to close: no GUsbDevice for %s",
1465 priv->platform_id);
1466 return FALSE;
1467 }
1468
1469 /* close if open */
1470 if (!g_usb_device_close (priv->dev, &error_local)) {
1471 if (g_error_matches (error_local,
1472 G_USB_DEVICE_ERROR,
1473 G_USB_DEVICE_ERROR_NOT_OPEN)) {
1474 g_debug ("device not open, so ignoring error for close");
1475 return TRUE;
1476 }
1477 g_set_error_literal (error,
1478 DFU_ERROR,
1479 DFU_ERROR_INTERNAL,
1480 error_local->message);
1481 return FALSE;
1482 }
1483 priv->claimed_interface = FALSE;
1484 priv->open_new_dev = FALSE;
1485 return TRUE;
1486 }
1487
1488 gboolean
1489 dfu_device_set_new_usb_dev (DfuDevice *device, GUsbDevice *dev,
1490 GCancellable *cancellable, GError **error)
1491 {
1492 DfuDevicePrivate *priv = GET_PRIVATE (device);
1493
1494 /* same */
1495 if (priv->dev == dev) {
1496 g_warning ("setting GUsbDevice with same dev?!");
1497 return TRUE;
1498 }
1499
1500 /* device removed */
1501 if (dev == NULL) {
1502 g_debug ("invalidating backing GUsbDevice");
1503 g_clear_object (&priv->dev);
1504 g_ptr_array_set_size (priv->targets, 0);
1505 priv->claimed_interface = FALSE;
1506 return TRUE;
1507 }
1508
1509 /* close */
1510 if (priv->dev != NULL) {
1511 gboolean tmp = priv->open_new_dev;
1512 if (!dfu_device_close (device, error))
1513 return FALSE;
1514 priv->open_new_dev = tmp;
1515 }
1516
1517 /* set the new USB device */
1518 g_set_object (&priv->dev, dev);
1519
1520 /* should be the same */
1521 if (g_strcmp0 (priv->platform_id,
1522 g_usb_device_get_platform_id (dev)) != 0) {
1523 g_warning ("platform ID changed when setting new GUsbDevice?!");
1524 g_free (priv->platform_id);
1525 priv->platform_id = g_strdup (g_usb_device_get_platform_id (dev));
1526 }
1527
1528 /* re-get the quirks for this new device */
1529 priv->quirks = DFU_DEVICE_QUIRK_NONE;
1530 priv->attributes = DFU_DEVICE_ATTRIBUTE_NONE;
1531 dfu_device_set_quirks (device);
1532
1533 /* the device has no DFU runtime, so cheat */
1534 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1535 g_debug ("ignoring fake device");
1536 return TRUE;
1537 }
1538
1539 /* update all the targets */
1540 if (!dfu_device_add_targets (device)) {
1541 g_set_error_literal (error,
1542 DFU_ERROR,
1543 DFU_ERROR_NOT_SUPPORTED,
1544 "replugged device is not DFU-capable");
1545 return FALSE;
1546 }
1547
1548 /* reclaim */
1549 if (priv->open_new_dev) {
1550 g_debug ("automatically reopening device");
1551 if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE,
1552 cancellable, error))
1553 return FALSE;
1554 }
1555 return TRUE;
1556 }
1557
1558 typedef struct {
1559 DfuDevice *device;
1560 GError **error;
1561 GMainLoop *loop;
1562 GUsbDevice *dev;
1563 guint cnt;
1564 guint timeout;
1565 } DfuDeviceReplugHelper;
1566
1567 static void
1568 dfu_device_replug_helper_free (DfuDeviceReplugHelper *helper)
1569 {
1570 if (helper->dev != NULL)
1571 g_object_unref (helper->dev);
1572 g_object_unref (helper->device);
1573 g_main_loop_unref (helper->loop);
1574 g_free (helper);
1575 }
1576
1577 static gboolean
1578 dfu_device_replug_helper_cb (gpointer user_data)
1579 {
1580 DfuDeviceReplugHelper *helper = (DfuDeviceReplugHelper *) user_data;
1581 DfuDevicePrivate *priv = GET_PRIVATE (helper->device);
1582
1583 /* did the backing GUsbDevice change */
1584 if (helper->dev != priv->dev) {
1585 g_debug ("device changed GUsbDevice %p->%p",
1586 helper->dev, priv->dev);
1587 g_set_object (&helper->dev, priv->dev);
1588
1589 /* success */
1590 if (helper->dev != NULL) {
1591 g_main_loop_quit (helper->loop);
1592 return FALSE;
1593 }
1594 }
1595
1596 /* set a limit */
1597 if (helper->cnt++ * 100 > helper->timeout) {
1598 g_debug ("gave up waiting for device replug");
1599 if (helper->dev == NULL) {
1600 g_set_error_literal (helper->error,
1601 DFU_ERROR,
1602 DFU_ERROR_INVALID_DEVICE,
1603 "target went away but did not come back");
1604 } else {
1605 g_set_error_literal (helper->error,
1606 DFU_ERROR,
1607 DFU_ERROR_INVALID_DEVICE,
1608 "target did not disconnect");
1609 }
1610 g_main_loop_quit (helper->loop);
1611 return FALSE;
1612 }
1613
1614 /* continue waiting */
1615 g_debug ("waiting for device replug for %ums -- state is %s",
1616 helper->cnt * 100, dfu_state_to_string (priv->state));
1617 return TRUE;
1618 }
1619
1620 /**
1621 * dfu_device_wait_for_replug:
1622 * @device: a #DfuDevice
1623 * @timeout: the maximum amount of time to wait
1624 * @cancellable: a #GCancellable, or %NULL
1625 * @error: a #GError, or %NULL
1626 *
1627 * Waits for a DFU device to disconnect and reconnect.
1628 * This does rely on a #DfuContext being set up before this is called.
1629 *
1630 * Return value: %TRUE for success
1631 *
1632 * Since: 0.5.4
1633 **/
1634 gboolean
1635 dfu_device_wait_for_replug (DfuDevice *device, guint timeout,
1636 GCancellable *cancellable, GError **error)
1637 {
1638 DfuDevicePrivate *priv = GET_PRIVATE (device);
1639 DfuDeviceReplugHelper *helper;
1640 GError *error_tmp = NULL;
1641 const guint replug_poll = 100; /* ms */
1642
1643 /* wait for replug */
1644 helper = g_new0 (DfuDeviceReplugHelper, 1);
1645 helper->loop = g_main_loop_new (NULL, FALSE);
1646 helper->device = g_object_ref (device);
1647 helper->dev = g_object_ref (priv->dev);
1648 helper->error = &error_tmp;
1649 helper->timeout = timeout;
1650 g_timeout_add_full (G_PRIORITY_DEFAULT, replug_poll,
1651 dfu_device_replug_helper_cb, helper,
1652 (GDestroyNotify) dfu_device_replug_helper_free);
1653 g_main_loop_run (helper->loop);
1654 if (error_tmp != NULL) {
1655 g_propagate_error (error, error_tmp);
1656 return FALSE;
1657 }
1658
1659 /* success */
1660 dfu_device_set_action (device, DFU_ACTION_IDLE);
1661 return TRUE;
1662 }
1663
1664 /**
1665 * dfu_device_reset:
1666 * @device: a #DfuDevice
1667 * @error: a #GError, or %NULL
1668 *
1669 * Resets the USB device.
1670 *
1671 * Return value: %TRUE for success
1672 *
1673 * Since: 0.5.4
1674 **/
1675 gboolean
1676 dfu_device_reset (DfuDevice *device, GError **error)
1677 {
1678 DfuDevicePrivate *priv = GET_PRIVATE (device);
1679 g_autoptr(GError) error_local = NULL;
1680
1681 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1682 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1683
1684 /* no backing USB device */
1685 if (priv->dev == NULL) {
1686 g_set_error (error,
1687 DFU_ERROR,
1688 DFU_ERROR_INTERNAL,
1689 "failed to reset: no GUsbDevice for %s",
1690 priv->platform_id);
1691 return FALSE;
1692 }
1693
1694 if (!g_usb_device_reset (priv->dev, &error_local)) {
1695 g_set_error (error,
1696 DFU_ERROR,
1697 DFU_ERROR_INVALID_DEVICE,
1698 "cannot reset USB device: %s [%i]",
1699 error_local->message,
1700 error_local->code);
1701 return FALSE;
1702 }
1703 return TRUE;
1704 }
1705
1706 /**
1707 * dfu_device_attach:
1708 * @device: a #DfuDevice
1709 * @error: a #GError, or %NULL
1710 *
1711 * Move device from DFU mode to runtime.
1712 *
1713 * Return value: %TRUE for success
1714 *
1715 * Since: 0.5.4
1716 **/
1717 gboolean
1718 dfu_device_attach (DfuDevice *device, GError **error)
1719 {
1720 DfuDevicePrivate *priv = GET_PRIVATE (device);
1721
1722 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1723 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1724
1725 /* already in runtime mode */
1726 switch (priv->state) {
1727 case DFU_STATE_APP_IDLE:
1728 case DFU_STATE_APP_DETACH:
1729 g_set_error (error,
1730 DFU_ERROR,
1731 DFU_ERROR_NOT_SUPPORTED,
1732 "Already in application runtime mode");
1733 return FALSE;
1734 default:
1735 break;
1736 }
1737
1738 /* inform UI there's going to be a re-attach */
1739 dfu_device_set_action (device, DFU_ACTION_ATTACH);
1740
1741 /* handle m-stack DFU bootloaders */
1742 if (!priv->done_upload_or_download &&
1743 (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD) > 0) {
1744 g_autoptr(GBytes) chunk = NULL;
1745 g_autoptr(DfuTarget) target = NULL;
1746 g_debug ("doing dummy upload to work around m-stack quirk");
1747 target = dfu_device_get_target_by_alt_setting (device, 0, error);
1748 if (target == NULL)
1749 return FALSE;
1750 chunk = dfu_target_upload_chunk (target, 0, NULL, error);
1751 if (chunk == NULL)
1752 return FALSE;
1753 }
1754
1755 /* there's a a special command for ST devices */
1756 if (priv->dfuse_supported) {
1757 g_autoptr(DfuTarget) target = NULL;
1758 g_autoptr(GBytes) bytes_tmp = NULL;
1759
1760 /* get default target */
1761 target = dfu_device_get_target_by_alt_setting (device, 0, error);
1762 if (target == NULL)
1763 return FALSE;
1764
1765 /* do zero byte download */
1766 bytes_tmp = g_bytes_new (NULL, 0);
1767 if (!dfu_target_download_chunk (target,
1768 0 + 2,
1769 bytes_tmp,
1770 NULL,
1771 error))
1772 return FALSE;
1773
1774 dfu_device_set_action (device, DFU_ACTION_IDLE);
1775 return TRUE;
1776 }
1777
1778 /* normal DFU mode just needs a bus reset */
1779 if (!dfu_device_reset (device, error))
1780 return FALSE;
1781
1782 /* success */
1783 dfu_device_set_action (device, DFU_ACTION_IDLE);
1784 return TRUE;
1785 }
1786
1787 static void
1788 dfu_device_percentage_cb (DfuTarget *target, guint percentage, DfuDevice *device)
1789 {
1790 /* FIXME: divide by number of targets? */
1791 g_signal_emit (device, signals[SIGNAL_PERCENTAGE_CHANGED], 0, percentage);
1792 }
1793
1794 static void
1795 dfu_device_action_cb (DfuTarget *target, DfuAction action, DfuDevice *device)
1796 {
1797 dfu_device_set_action (device, action);
1798 }
1799
1800 /**
1801 * dfu_device_upload:
1802 * @device: a #DfuDevice
1803 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1804 * @cancellable: a #GCancellable, or %NULL
1805 * @error: a #GError, or %NULL
1806 *
1807 * Uploads firmware from the target to the host.
1808 *
1809 * Return value: (transfer full): the uploaded firmware, or %NULL for error
1810 *
1811 * Since: 0.5.4
1812 **/
1813 DfuFirmware *
1814 dfu_device_upload (DfuDevice *device,
1815 DfuTargetTransferFlags flags,
1816 GCancellable *cancellable,
1817 GError **error)
1818 {
1819 DfuDevicePrivate *priv = GET_PRIVATE (device);
1820 guint i;
1821 g_autoptr(DfuFirmware) firmware = NULL;
1822
1823 /* no backing USB device */
1824 if (priv->dev == NULL) {
1825 g_set_error (error,
1826 DFU_ERROR,
1827 DFU_ERROR_INTERNAL,
1828 "failed to upload: no GUsbDevice for %s",
1829 priv->platform_id);
1830 return NULL;
1831 }
1832
1833 /* ensure interface is claimed */
1834 if (!dfu_device_ensure_interface (device, cancellable, error))
1835 return NULL;
1836
1837 /* create ahead of time */
1838 firmware = dfu_firmware_new ();
1839 dfu_firmware_set_vid (firmware, priv->runtime_vid);
1840 dfu_firmware_set_pid (firmware, priv->runtime_pid);
1841 dfu_firmware_set_release (firmware, 0xffff);
1842
1843 /* APP -> DFU */
1844 if (priv->mode == DFU_MODE_RUNTIME) {
1845 if ((flags & DFU_TARGET_TRANSFER_FLAG_DETACH) == 0) {
1846 g_set_error (error,
1847 DFU_ERROR,
1848 DFU_ERROR_NOT_SUPPORTED,
1849 "device is not in DFU mode");
1850 return NULL;
1851 }
1852 g_debug ("detaching");
1853
1854 /* detach and USB reset */
1855 if (!dfu_device_detach (device, NULL, error))
1856 return NULL;
1857 if (!dfu_device_wait_for_replug (device,
1858 DFU_DEVICE_REPLUG_TIMEOUT,
1859 cancellable,
1860 error))
1861 return NULL;
1862 }
1863
1864 /* upload from each target */
1865 for (i = 0; i < priv->targets->len; i++) {
1866 DfuTarget *target;
1867 const gchar *alt_name;
1868 gulong id1;
1869 gulong id2;
1870 g_autoptr(DfuImage) image = NULL;
1871
1872 /* upload to target and proxy signals */
1873 target = g_ptr_array_index (priv->targets, i);
1874
1875 /* ignore some target types */
1876 alt_name = dfu_target_get_alt_name_for_display (target, NULL);
1877 if (g_strcmp0 (alt_name, "Option Bytes") == 0) {
1878 g_debug ("ignoring target %s", alt_name);
1879 continue;
1880 }
1881
1882 id1 = g_signal_connect (target, "percentage-changed",
1883 G_CALLBACK (dfu_device_percentage_cb), device);
1884 id2 = g_signal_connect (target, "action-changed",
1885 G_CALLBACK (dfu_device_action_cb), device);
1886 image = dfu_target_upload (target,
1887 DFU_TARGET_TRANSFER_FLAG_NONE,
1888 cancellable,
1889 error);
1890 g_signal_handler_disconnect (target, id1);
1891 g_signal_handler_disconnect (target, id2);
1892 if (image == NULL)
1893 return NULL;
1894 dfu_firmware_add_image (firmware, image);
1895 }
1896
1897 /* do not do the dummy upload for quirked devices */
1898 priv->done_upload_or_download = TRUE;
1899
1900 /* choose the most appropriate type */
1901 if (priv->targets->len > 1) {
1902 g_debug ("switching to DefuSe automatically");
1903 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFUSE);
1904 } else {
1905 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU);
1906 }
1907
1908 /* do host reset */
1909 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
1910 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
1911 if (!dfu_device_attach (device, error))
1912 return NULL;
1913 }
1914
1915 /* boot to runtime */
1916 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
1917 g_debug ("booting to runtime");
1918 if (!dfu_device_wait_for_replug (device,
1919 DFU_DEVICE_REPLUG_TIMEOUT,
1920 cancellable,
1921 error))
1922 return NULL;
1923 }
1924
1925 /* success */
1926 dfu_device_set_action (device, DFU_ACTION_IDLE);
1927 return g_object_ref (firmware);
1928 }
1929
1930 static gboolean
1931 dfu_device_id_compatible (guint16 id_file, guint16 id_runtime, guint16 id_dev)
1932 {
1933 /* file doesn't specify */
1934 if (id_file == 0xffff)
1935 return TRUE;
1936
1937 /* runtime matches */
1938 if (id_runtime != 0xffff && id_file == id_runtime)
1939 return TRUE;
1940
1941 /* bootloader matches */
1942 if (id_dev != 0xffff && id_file == id_dev)
1943 return TRUE;
1944
1945 /* nothing */
1946 return FALSE;
1947 }
1948
1949 /**
1950 * dfu_device_download:
1951 * @device: a #DfuDevice
1952 * @firmware: a #DfuFirmware
1953 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1954 * @cancellable: a #GCancellable, or %NULL
1955 * @error: a #GError, or %NULL
1956 *
1957 * Downloads firmware from the host to the target, optionally verifying
1958 * the transfer.
1959 *
1960 * Return value: %TRUE for success
1961 *
1962 * Since: 0.5.4
1963 **/
1964 gboolean
1965 dfu_device_download (DfuDevice *device,
1966 DfuFirmware *firmware,
1967 DfuTargetTransferFlags flags,
1968 GCancellable *cancellable,
1969 GError **error)
1970 {
1971 DfuDevicePrivate *priv = GET_PRIVATE (device);
1972 GPtrArray *images;
1973 gboolean ret;
1974 guint i;
1975
1976 /* no backing USB device */
1977 if (priv->dev == NULL) {
1978 g_set_error (error,
1979 DFU_ERROR,
1980 DFU_ERROR_INTERNAL,
1981 "failed to download: no GUsbDevice for %s",
1982 priv->platform_id);
1983 return FALSE;
1984 }
1985
1986 /* ensure interface is claimed */
1987 if (!dfu_device_ensure_interface (device, cancellable, error))
1988 return FALSE;
1989
1990 /* do we allow wildcard VID:PID matches */
1991 if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID) == 0) {
1992 if (dfu_firmware_get_vid (firmware) == 0xffff) {
1993 g_set_error (error,
1994 DFU_ERROR,
1995 DFU_ERROR_NOT_SUPPORTED,
1996 "firmware vendor ID not specified");
1997 return FALSE;
1998 }
1999 }
2000 if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID) == 0) {
2001 if (dfu_firmware_get_pid (firmware) == 0xffff) {
2002 g_set_error (error,
2003 DFU_ERROR,
2004 DFU_ERROR_NOT_SUPPORTED,
2005 "firmware product ID not specified");
2006 return FALSE;
2007 }
2008 }
2009
2010 /* check vendor matches */
2011 if (priv->runtime_vid != 0xffff) {
2012 if (!dfu_device_id_compatible (dfu_firmware_get_vid (firmware),
2013 priv->runtime_vid,
2014 g_usb_device_get_vid (priv->dev))) {
2015 g_set_error (error,
2016 DFU_ERROR,
2017 DFU_ERROR_NOT_SUPPORTED,
2018 "vendor ID incorrect, expected 0x%04x "
2019 "got 0x%04x and 0x%04x\n",
2020 dfu_firmware_get_vid (firmware),
2021 priv->runtime_vid,
2022 g_usb_device_get_vid (priv->dev));
2023 return FALSE;
2024 }
2025 }
2026
2027 /* check product matches */
2028 if (priv->runtime_pid != 0xffff) {
2029 if (!dfu_device_id_compatible (dfu_firmware_get_pid (firmware),
2030 priv->runtime_pid,
2031 g_usb_device_get_pid (priv->dev))) {
2032 g_set_error (error,
2033 DFU_ERROR,
2034 DFU_ERROR_NOT_SUPPORTED,
2035 "product ID incorrect, expected 0x%04x "
2036 "got 0x%04x and 0x%04x",
2037 dfu_firmware_get_pid (firmware),
2038 priv->runtime_pid,
2039 g_usb_device_get_pid (priv->dev));
2040 return FALSE;
2041 }
2042 }
2043
2044 /* APP -> DFU */
2045 if (priv->mode == DFU_MODE_RUNTIME) {
2046 if ((flags & DFU_TARGET_TRANSFER_FLAG_DETACH) == 0) {
2047 g_set_error (error,
2048 DFU_ERROR,
2049 DFU_ERROR_NOT_SUPPORTED,
2050 "device is not in DFU mode");
2051 return FALSE;
2052 }
2053
2054 /* detach and USB reset */
2055 g_debug ("detaching");
2056 if (!dfu_device_detach (device, NULL, error))
2057 return FALSE;
2058 if (!dfu_device_wait_for_replug (device,
2059 DFU_DEVICE_REPLUG_TIMEOUT,
2060 NULL,
2061 error))
2062 return FALSE;
2063 }
2064
2065 /* download each target */
2066 images = dfu_firmware_get_images (firmware);
2067 if (images->len == 0) {
2068 g_set_error_literal (error,
2069 DFU_ERROR,
2070 DFU_ERROR_INVALID_FILE,
2071 "no images in firmware file");
2072 return FALSE;
2073 }
2074 for (i = 0; i < images->len; i++) {
2075 DfuCipherKind cipher_fw;
2076 DfuCipherKind cipher_target;
2077 DfuImage *image;
2078 DfuTargetTransferFlags flags_local = DFU_TARGET_TRANSFER_FLAG_NONE;
2079 const gchar *alt_name;
2080 gulong id1;
2081 gulong id2;
2082 g_autoptr(DfuTarget) target_tmp = NULL;
2083
2084 image = g_ptr_array_index (images, i);
2085 target_tmp = dfu_device_get_target_by_alt_setting (device,
2086 dfu_image_get_alt_setting (image),
2087 error);
2088 if (target_tmp == NULL)
2089 return FALSE;
2090
2091 /* we don't actually need to print this, but it makes sure the
2092 * target is setup prior to doing the cipher checks */
2093 alt_name = dfu_target_get_alt_name (target_tmp, error);
2094 if (alt_name == NULL)
2095 return FALSE;
2096 g_debug ("downloading to target: %s", alt_name);
2097
2098 /* check we're flashing a compatible firmware */
2099 cipher_target = dfu_target_get_cipher_kind (target_tmp);
2100 cipher_fw = dfu_firmware_get_cipher_kind (firmware);
2101 if ((flags & DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER) == 0) {
2102 if (cipher_fw != DFU_CIPHER_KIND_NONE &&
2103 cipher_target == DFU_CIPHER_KIND_NONE) {
2104 g_set_error (error,
2105 DFU_ERROR,
2106 DFU_ERROR_INVALID_FILE,
2107 "Device is only accepting "
2108 "unsigned firmware, not %s",
2109 dfu_cipher_kind_to_string (cipher_fw));
2110 return FALSE;
2111 }
2112 if (cipher_fw == DFU_CIPHER_KIND_NONE &&
2113 cipher_target != DFU_CIPHER_KIND_NONE) {
2114 g_set_error (error,
2115 DFU_ERROR,
2116 DFU_ERROR_INVALID_FILE,
2117 "Device is only accepting "
2118 "firmware with %s cipher kind",
2119 dfu_cipher_kind_to_string (cipher_target));
2120 return FALSE;
2121 }
2122 }
2123
2124 /* download onto target */
2125 if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY)
2126 flags_local = DFU_TARGET_TRANSFER_FLAG_VERIFY;
2127 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_RAW)
2128 flags_local |= DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC;
2129 id1 = g_signal_connect (target_tmp, "percentage-changed",
2130 G_CALLBACK (dfu_device_percentage_cb), device);
2131 id2 = g_signal_connect (target_tmp, "action-changed",
2132 G_CALLBACK (dfu_device_action_cb), device);
2133 ret = dfu_target_download (target_tmp,
2134 image,
2135 flags_local,
2136 cancellable,
2137 error);
2138 g_signal_handler_disconnect (target_tmp, id1);
2139 g_signal_handler_disconnect (target_tmp, id2);
2140 if (!ret)
2141 return FALSE;
2142 }
2143
2144 /* do not do the dummy upload for quirked devices */
2145 priv->done_upload_or_download = TRUE;
2146
2147 /* attempt to switch back to runtime */
2148 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
2149 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
2150 if (!dfu_device_attach (device, error))
2151 return FALSE;
2152 }
2153
2154 /* boot to runtime */
2155 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
2156 g_debug ("booting to runtime to set auto-boot");
2157 if (!dfu_device_wait_for_replug (device,
2158 DFU_DEVICE_REPLUG_TIMEOUT,
2159 cancellable,
2160 error))
2161 return FALSE;
2162 }
2163
2164 /* success */
2165 dfu_device_set_action (device, DFU_ACTION_IDLE);
2166 return TRUE;
2167 }
2168
2169 void
2170 dfu_device_error_fixup (DfuDevice *device,
2171 GCancellable *cancellable,
2172 GError **error)
2173 {
2174 DfuDevicePrivate *priv = GET_PRIVATE (device);
2175
2176 /* sad panda */
2177 if (error == NULL)
2178 return;
2179
2180 /* not the right error to query */
2181 if (!g_error_matches (*error,
2182 G_USB_DEVICE_ERROR,
2183 G_USB_DEVICE_ERROR_NOT_SUPPORTED))
2184 return;
2185
2186 /* get the status */
2187 if (!dfu_device_refresh (device, cancellable, NULL))
2188 return;
2189
2190 /* not in an error state */
2191 if (priv->state != DFU_STATE_DFU_ERROR)
2192 return;
2193
2194 /* prefix the error */
2195 switch (priv->status) {
2196 case DFU_STATUS_OK:
2197 /* ignore */
2198 break;
2199 case DFU_STATUS_ERR_VENDOR:
2200 g_prefix_error (error, "read protection is active: ");
2201 break;
2202 default:
2203 g_prefix_error (error, "[%s,%s]: ",
2204 dfu_state_to_string (priv->state),
2205 dfu_status_to_string (priv->status));
2206 break;
2207 }
2208 }
2209
2210 /**
2211 * dfu_device_get_quirks_as_string: (skip)
2212 * @device: a #DfuDevice
2213 *
2214 * Gets a string describing the quirks set for a device.
2215 *
2216 * Return value: string, or %NULL for no quirks
2217 *
2218 * Since: 0.5.4
2219 **/
2220 gchar *
2221 dfu_device_get_quirks_as_string (DfuDevice *device)
2222 {
2223 DfuDevicePrivate *priv = GET_PRIVATE (device);
2224 GString *str;
2225
2226 /* just append to a string */
2227 str = g_string_new ("");
2228 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT)
2229 g_string_append_printf (str, "ignore-polltimeout|");
2230 if (priv->quirks & DFU_DEVICE_QUIRK_FORCE_DFU_MODE)
2231 g_string_append_printf (str, "force-dfu-mode|");
2232 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION)
2233 g_string_append_printf (str, "ignore-invalid-version|");
2234 if (priv->quirks & DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO)
2235 g_string_append_printf (str, "use-protocol-zero|");
2236 if (priv->quirks & DFU_DEVICE_QUIRK_NO_PID_CHANGE)
2237 g_string_append_printf (str, "no-pid-change|");
2238 if (priv->quirks & DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD)
2239 g_string_append_printf (str, "no-get-status-upload|");
2240 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME)
2241 g_string_append_printf (str, "no-dfu-runtime|");
2242 if (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD)
2243 g_string_append_printf (str, "attach-upload-download|");
2244 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_RUNTIME)
2245 g_string_append_printf (str, "ignore-runtime|");
2246
2247 /* a well behaved device */
2248 if (str->len == 0) {
2249 g_string_free (str, TRUE);
2250 return NULL;
2251 }
2252
2253 /* remove trailing pipe */
2254 g_string_truncate (str, str->len - 1);
2255 return g_string_free (str, FALSE);
2256 }
+0
-199
libdfu/dfu-device.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_DEVICE_H
22 #define __DFU_DEVICE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-common.h"
29 #include "dfu-target.h"
30 #include "dfu-firmware.h"
31
32 G_BEGIN_DECLS
33
34 #define DFU_TYPE_DEVICE (dfu_device_get_type ())
35 G_DECLARE_DERIVABLE_TYPE (DfuDevice, dfu_device, DFU, DEVICE, GObject)
36
37 /**
38 * DfuDeviceOpenFlags:
39 * @DFU_DEVICE_OPEN_FLAG_NONE: No flags set
40 * @DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH: Do not do the initial GET_STATUS
41 *
42 * The optional flags used for opening the target.
43 **/
44 typedef enum {
45 DFU_DEVICE_OPEN_FLAG_NONE = 0,
46 DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH = (1 << 0),
47 /*< private >*/
48 DFU_DEVICE_OPEN_FLAG_LAST
49 } DfuDeviceOpenFlags;
50
51 /**
52 * DfuDeviceQuirks:
53 * @DFU_DEVICE_QUIRK_NONE: No device quirks
54 * @DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT: Ignore the device download timeout
55 * @DFU_DEVICE_QUIRK_FORCE_DFU_MODE: Force DFU mode
56 * @DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION: Ignore invalid version numbers
57 * @DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO: Fix up the protocol number
58 * @DFU_DEVICE_QUIRK_NO_PID_CHANGE: Accept the same VID:PID when changing modes
59 * @DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD: Do not do GetStatus when uploading
60 * @DFU_DEVICE_QUIRK_NO_DFU_RUNTIME: No DFU runtime interface is provided
61 * @DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD: An upload or download is required for attach
62 * @DFU_DEVICE_QUIRK_IGNORE_RUNTIME: Device has broken DFU runtime support
63 *
64 * The workarounds for different devices.
65 **/
66 typedef enum {
67 DFU_DEVICE_QUIRK_NONE = 0,
68 DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT = (1 << 0),
69 DFU_DEVICE_QUIRK_FORCE_DFU_MODE = (1 << 1),
70 DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION = (1 << 2),
71 DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO = (1 << 3),
72 DFU_DEVICE_QUIRK_NO_PID_CHANGE = (1 << 4),
73 DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD = (1 << 5),
74 DFU_DEVICE_QUIRK_NO_DFU_RUNTIME = (1 << 6),
75 DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD = (1 << 7),
76 DFU_DEVICE_QUIRK_IGNORE_RUNTIME = (1 << 8),
77 /*< private >*/
78 DFU_DEVICE_QUIRK_LAST
79 } DfuDeviceQuirks;
80
81 /**
82 * DfuDeviceAttributes:
83 * @DFU_DEVICE_ATTRIBUTE_NONE: No attributes set
84 * @DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD: Can download from host->device
85 * @DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD: Can upload from device->host
86 * @DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL: Can answer GetStatus in manifest
87 * @DFU_DEVICE_ATTRIBUTE_WILL_DETACH: Will self-detach
88 * @DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE: Use a larger transfer size for speed
89 *
90 * The device DFU attributes.
91 **/
92 typedef enum {
93 DFU_DEVICE_ATTRIBUTE_NONE = 0,
94 DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD = (1 << 0),
95 DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD = (1 << 1),
96 DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL = (1 << 2),
97 DFU_DEVICE_ATTRIBUTE_WILL_DETACH = (1 << 3),
98 DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE = (1 << 7),
99 /*< private >*/
100 DFU_DEVICE_ATTRIBUTE_LAST
101 } DfuDeviceAttributes;
102
103 struct _DfuDeviceClass
104 {
105 GObjectClass parent_class;
106 void (*status_changed) (DfuDevice *device,
107 DfuStatus status);
108 void (*state_changed) (DfuDevice *device,
109 DfuState state);
110 void (*percentage_changed) (DfuDevice *device,
111 guint percentage);
112 void (*action_changed) (DfuDevice *device,
113 DfuAction action);
114 /*< private >*/
115 /* Padding for future expansion */
116 void (*_dfu_device_reserved1) (void);
117 void (*_dfu_device_reserved2) (void);
118 void (*_dfu_device_reserved3) (void);
119 void (*_dfu_device_reserved4) (void);
120 void (*_dfu_device_reserved5) (void);
121 void (*_dfu_device_reserved6) (void);
122 void (*_dfu_device_reserved7) (void);
123 void (*_dfu_device_reserved8) (void);
124 };
125
126 DfuDevice *dfu_device_new (GUsbDevice *dev);
127 gboolean dfu_device_open (DfuDevice *device,
128 DfuDeviceOpenFlags flags,
129 GCancellable *cancellable,
130 GError **error);
131 gboolean dfu_device_close (DfuDevice *device,
132 GError **error);
133 const gchar *dfu_device_get_platform_id (DfuDevice *device);
134 GPtrArray *dfu_device_get_targets (DfuDevice *device);
135 DfuTarget *dfu_device_get_target_by_alt_setting (DfuDevice *device,
136 guint8 alt_setting,
137 GError **error);
138 DfuTarget *dfu_device_get_target_by_alt_name (DfuDevice *device,
139 const gchar *alt_name,
140 GError **error);
141 const gchar *dfu_device_get_display_name (DfuDevice *device);
142 const gchar *dfu_device_get_serial_number (DfuDevice *device);
143 guint16 dfu_device_get_runtime_vid (DfuDevice *device);
144 guint16 dfu_device_get_runtime_pid (DfuDevice *device);
145 guint16 dfu_device_get_runtime_release (DfuDevice *device);
146 gboolean dfu_device_reset (DfuDevice *device,
147 GError **error);
148 gboolean dfu_device_attach (DfuDevice *device,
149 GError **error);
150 gboolean dfu_device_wait_for_replug (DfuDevice *device,
151 guint timeout,
152 GCancellable *cancellable,
153 GError **error);
154 DfuFirmware *dfu_device_upload (DfuDevice *device,
155 DfuTargetTransferFlags flags,
156 GCancellable *cancellable,
157 GError **error);
158 gboolean dfu_device_download (DfuDevice *device,
159 DfuFirmware *firmware,
160 DfuTargetTransferFlags flags,
161 GCancellable *cancellable,
162 GError **error);
163 gboolean dfu_device_refresh (DfuDevice *device,
164 GCancellable *cancellable,
165 GError **error);
166 gboolean dfu_device_detach (DfuDevice *device,
167 GCancellable *cancellable,
168 GError **error);
169 gboolean dfu_device_abort (DfuDevice *device,
170 GCancellable *cancellable,
171 GError **error);
172 gboolean dfu_device_clear_status (DfuDevice *device,
173 GCancellable *cancellable,
174 GError **error);
175
176 guint8 dfu_device_get_interface (DfuDevice *device);
177 DfuMode dfu_device_get_mode (DfuDevice *device);
178 DfuState dfu_device_get_state (DfuDevice *device);
179 DfuStatus dfu_device_get_status (DfuDevice *device);
180 guint16 dfu_device_get_transfer_size (DfuDevice *device);
181 guint16 dfu_device_get_version (DfuDevice *device);
182 guint dfu_device_get_timeout (DfuDevice *device);
183 gboolean dfu_device_can_upload (DfuDevice *device);
184 gboolean dfu_device_can_download (DfuDevice *device);
185
186 gboolean dfu_device_has_attribute (DfuDevice *device,
187 DfuDeviceAttributes attribute);
188 gboolean dfu_device_has_quirk (DfuDevice *device,
189 DfuDeviceQuirks quirk);
190
191 void dfu_device_set_transfer_size (DfuDevice *device,
192 guint16 transfer_size);
193 void dfu_device_set_timeout (DfuDevice *device,
194 guint timeout_ms);
195
196 G_END_DECLS
197
198 #endif /* __DFU_DEVICE_H */
+0
-271
libdfu/dfu-element.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-element
23 * @short_description: Object representing a binary element
24 *
25 * This object represents an binary blob of data at a specific address.
26 *
27 * This allows relocatable data segments to be stored in different
28 * locations on the device itself.
29 *
30 * See also: #DfuImage, #DfuFirmware
31 */
32
33 #include "config.h"
34
35 #include <string.h>
36 #include <stdio.h>
37
38 #include "dfu-common.h"
39 #include "dfu-element.h"
40 #include "dfu-error.h"
41
42 static void dfu_element_finalize (GObject *object);
43
44 typedef struct {
45 GBytes *contents;
46 guint32 target_size;
47 guint32 address;
48 guint8 padding_value;
49 } DfuElementPrivate;
50
51 G_DEFINE_TYPE_WITH_PRIVATE (DfuElement, dfu_element, G_TYPE_OBJECT)
52 #define GET_PRIVATE(o) (dfu_element_get_instance_private (o))
53
54 static void
55 dfu_element_class_init (DfuElementClass *klass)
56 {
57 GObjectClass *object_class = G_OBJECT_CLASS (klass);
58 object_class->finalize = dfu_element_finalize;
59 }
60
61 static void
62 dfu_element_init (DfuElement *element)
63 {
64 }
65
66 static void
67 dfu_element_finalize (GObject *object)
68 {
69 DfuElement *element = DFU_ELEMENT (object);
70 DfuElementPrivate *priv = GET_PRIVATE (element);
71
72 if (priv->contents != NULL)
73 g_bytes_unref (priv->contents);
74
75 G_OBJECT_CLASS (dfu_element_parent_class)->finalize (object);
76 }
77
78 /**
79 * dfu_element_new:
80 *
81 * Creates a new DFU element object.
82 *
83 * Return value: a new #DfuElement
84 *
85 * Since: 0.5.4
86 **/
87 DfuElement *
88 dfu_element_new (void)
89 {
90 DfuElement *element;
91 element = g_object_new (DFU_TYPE_ELEMENT, NULL);
92 return element;
93 }
94
95 /**
96 * dfu_element_get_contents:
97 * @element: a #DfuElement
98 *
99 * Gets the element data.
100 *
101 * Return value: (transfer none): element data
102 *
103 * Since: 0.5.4
104 **/
105 GBytes *
106 dfu_element_get_contents (DfuElement *element)
107 {
108 DfuElementPrivate *priv = GET_PRIVATE (element);
109 g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL);
110 return priv->contents;
111 }
112
113 /**
114 * dfu_element_get_address:
115 * @element: a #DfuElement
116 *
117 * Gets the offset address of the element.
118 *
119 * Return value: memory offset value, or 0x00 for unset
120 *
121 * Since: 0.5.4
122 **/
123 guint32
124 dfu_element_get_address (DfuElement *element)
125 {
126 DfuElementPrivate *priv = GET_PRIVATE (element);
127 g_return_val_if_fail (DFU_IS_ELEMENT (element), 0x00);
128 return priv->address;
129 }
130
131 /**
132 * dfu_element_set_contents:
133 * @element: a #DfuElement
134 * @contents: element data
135 *
136 * Sets the element data.
137 *
138 * Since: 0.5.4
139 **/
140 void
141 dfu_element_set_contents (DfuElement *element, GBytes *contents)
142 {
143 DfuElementPrivate *priv = GET_PRIVATE (element);
144 g_return_if_fail (DFU_IS_ELEMENT (element));
145 g_return_if_fail (contents != NULL);
146 if (priv->contents == contents)
147 return;
148 if (priv->contents != NULL)
149 g_bytes_unref (priv->contents);
150 priv->contents = g_bytes_ref (contents);
151 }
152
153 /**
154 * dfu_element_set_address:
155 * @element: a #DfuElement
156 * @address: memory offset value
157 *
158 * Sets the offset address of the element.
159 *
160 * Since: 0.5.4
161 **/
162 void
163 dfu_element_set_address (DfuElement *element, guint32 address)
164 {
165 DfuElementPrivate *priv = GET_PRIVATE (element);
166 g_return_if_fail (DFU_IS_ELEMENT (element));
167 priv->address = address;
168 }
169
170 /**
171 * dfu_element_to_string:
172 * @element: a #DfuElement
173 *
174 * Returns a string representaiton of the object.
175 *
176 * Return value: NULL terminated string, or %NULL for invalid
177 *
178 * Since: 0.5.4
179 **/
180 gchar *
181 dfu_element_to_string (DfuElement *element)
182 {
183 DfuElementPrivate *priv = GET_PRIVATE (element);
184 GString *str;
185
186 g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL);
187
188 str = g_string_new ("");
189 g_string_append_printf (str, "address: 0x%02x\n", priv->address);
190 if (priv->target_size > 0) {
191 g_string_append_printf (str, "target: 0x%04x\n",
192 priv->target_size);
193 }
194 if (priv->contents != NULL) {
195 g_string_append_printf (str, "contents: 0x%04x\n",
196 (guint32) g_bytes_get_size (priv->contents));
197 }
198
199 g_string_truncate (str, str->len - 1);
200 return g_string_free (str, FALSE);
201 }
202
203 /**
204 * dfu_element_set_padding_value:
205 * @element: a #DfuElement
206 * @padding_value: char value, typically 0x00 or 0xff
207 *
208 * Sets a the value of the padding byte to be used in the function
209 * dfu_element_set_target_size().
210 *
211 * Since: 0.7.3
212 **/
213 void
214 dfu_element_set_padding_value (DfuElement *element, guint8 padding_value)
215 {
216 DfuElementPrivate *priv = GET_PRIVATE (element);
217 g_return_if_fail (DFU_IS_ELEMENT (element));
218 priv->padding_value = padding_value;
219 }
220
221 /**
222 * dfu_element_set_target_size:
223 * @element: a #DfuElement
224 * @target_size: size in bytes
225 *
226 * Sets a target size for the element. If the prepared element is smaller
227 * than this then it will be padded up to the required size.
228 *
229 * If a padding byte other than 0x00 is required then the function
230 * dfu_element_set_padding_value() should be used before this function is
231 * called.
232 *
233 * Since: 0.5.4
234 **/
235 void
236 dfu_element_set_target_size (DfuElement *element, guint32 target_size)
237 {
238 DfuElementPrivate *priv = GET_PRIVATE (element);
239 const guint8 *data;
240 gsize length;
241 guint8 *buf;
242
243 g_return_if_fail (DFU_IS_ELEMENT (element));
244
245 /* save for dump */
246 priv->target_size = target_size;
247
248 /* no need to pad */
249 if (priv->contents == NULL)
250 return;
251 if (g_bytes_get_size (priv->contents) >= target_size)
252 return;
253
254 /* reallocate and pad */
255 data = g_bytes_get_data (priv->contents, &length);
256 buf = g_malloc0 (target_size);
257 g_assert (buf != NULL);
258 memcpy (buf, data, length);
259
260 /* set the pading value */
261 if (priv->padding_value != 0x00) {
262 memset (buf + length,
263 priv->padding_value,
264 target_size - length);
265 }
266
267 /* replace */
268 g_bytes_unref (priv->contents);
269 priv->contents = g_bytes_new_take (buf, target_size);
270 }
+0
-67
libdfu/dfu-element.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_ELEMENT_H
22 #define __DFU_ELEMENT_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 #define DFU_TYPE_ELEMENT (dfu_element_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (DfuElement, dfu_element, DFU, ELEMENT, GObject)
31
32 struct _DfuElementClass
33 {
34 GObjectClass parent_class;
35 /*< private >*/
36 /* Padding for future expansion */
37 void (*_dfu_element_reserved1) (void);
38 void (*_dfu_element_reserved2) (void);
39 void (*_dfu_element_reserved3) (void);
40 void (*_dfu_element_reserved4) (void);
41 void (*_dfu_element_reserved5) (void);
42 void (*_dfu_element_reserved6) (void);
43 void (*_dfu_element_reserved7) (void);
44 void (*_dfu_element_reserved8) (void);
45 void (*_dfu_element_reserved9) (void);
46 };
47
48 DfuElement *dfu_element_new (void);
49
50 GBytes *dfu_element_get_contents (DfuElement *element);
51 guint32 dfu_element_get_address (DfuElement *element);
52
53 void dfu_element_set_contents (DfuElement *element,
54 GBytes *contents);
55 void dfu_element_set_address (DfuElement *element,
56 guint32 address);
57 void dfu_element_set_target_size (DfuElement *element,
58 guint32 target_size);
59 void dfu_element_set_padding_value (DfuElement *element,
60 guint8 padding_value);
61
62 gchar *dfu_element_to_string (DfuElement *element);
63
64 G_END_DECLS
65
66 #endif /* __DFU_ELEMENT_H */
+0
-49
libdfu/dfu-error.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-error
23 * @short_description: Error defines for libdfu
24 *
25 * This documents the error domain and codes used by libdfu.
26 */
27
28 #include "config.h"
29
30 #include <gio/gio.h>
31
32 #include "dfu-error.h"
33
34 /**
35 * dfu_error_quark:
36 *
37 * Return value: An error quark.
38 *
39 * Since: 0.5.4
40 **/
41 GQuark
42 dfu_error_quark (void)
43 {
44 static GQuark quark = 0;
45 if (!quark)
46 quark = g_quark_from_static_string ("DfuError");
47 return quark;
48 }
+0
-55
libdfu/dfu-error.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_ERROR_H
22 #define __DFU_ERROR_H
23
24 #include <glib.h>
25
26 #define DFU_ERROR dfu_error_quark()
27
28 /**
29 * DfuError:
30 * @DFU_ERROR_INTERNAL: Internal error
31 * @DFU_ERROR_VERIFY_FAILED: Failed to verify write
32 * @DFU_ERROR_INVALID_FILE: Invalid file format
33 * @DFU_ERROR_INVALID_DEVICE: Invalid device type
34 * @DFU_ERROR_NOT_FOUND: Resource not found
35 * @DFU_ERROR_NOT_SUPPORTED: Action was not supported
36 * @DFU_ERROR_PERMISSION_DENIED: Failed due to access permissions
37 *
38 * The error code.
39 **/
40 typedef enum {
41 DFU_ERROR_INTERNAL, /* Since: 0.5.4 */
42 DFU_ERROR_VERIFY_FAILED, /* Since: 0.5.4 */
43 DFU_ERROR_INVALID_FILE, /* Since: 0.5.4 */
44 DFU_ERROR_INVALID_DEVICE, /* Since: 0.5.4 */
45 DFU_ERROR_NOT_FOUND, /* Since: 0.5.4 */
46 DFU_ERROR_NOT_SUPPORTED, /* Since: 0.5.4 */
47 DFU_ERROR_PERMISSION_DENIED, /* Since: 0.5.4 */
48 /*< private >*/
49 DFU_ERROR_LAST
50 } DfuError;
51
52 GQuark dfu_error_quark (void);
53
54 #endif /* __DFU_ERROR_H */
+0
-38
libdfu/dfu-firmware-private.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FIRMWARE_PRIVATE_H
22 #define __DFU_FIRMWARE_PRIVATE_H
23
24 #include "dfu-firmware.h"
25
26 G_BEGIN_DECLS
27
28 void dfu_firmware_add_symbol (DfuFirmware *firmware,
29 const gchar *symbol_name,
30 guint32 symbol_addr);
31 guint32 dfu_firmware_lookup_symbol (DfuFirmware *firmware,
32 const gchar *symbol_name);
33 GPtrArray *dfu_firmware_get_symbols (DfuFirmware *firmware);
34
35 G_END_DECLS
36
37 #endif /* __DFU_FIRMWARE_PRIVATE_H */
+0
-965
libdfu/dfu-firmware.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-firmware
23 * @short_description: Object representing a DFU or DfuSe firmware file
24 *
25 * This object allows reading and writing firmware files either in
26 * raw, DFU or DfuSe formats.
27 *
28 * A #DfuFirmware can be made up of several #DfuImages, although
29 * typically there is only one.
30 *
31 * See also: #DfuImage
32 */
33
34 #include "config.h"
35
36 #include <string.h>
37 #include <stdio.h>
38 #include <appstream-glib.h>
39
40 #include "dfu-common.h"
41 #include "dfu-error.h"
42 #include "dfu-firmware-private.h"
43 #include "dfu-format-elf.h"
44 #include "dfu-format-dfu.h"
45 #include "dfu-format-ihex.h"
46 #include "dfu-format-raw.h"
47 #include "dfu-image.h"
48
49 static void dfu_firmware_finalize (GObject *object);
50
51 typedef struct {
52 GHashTable *metadata;
53 GHashTable *symtab;
54 GPtrArray *images;
55 guint16 vid;
56 guint16 pid;
57 guint16 release;
58 DfuCipherKind cipher_kind;
59 DfuFirmwareFormat format;
60 } DfuFirmwarePrivate;
61
62 G_DEFINE_TYPE_WITH_PRIVATE (DfuFirmware, dfu_firmware, G_TYPE_OBJECT)
63 #define GET_PRIVATE(o) (dfu_firmware_get_instance_private (o))
64
65 static void
66 dfu_firmware_class_init (DfuFirmwareClass *klass)
67 {
68 GObjectClass *object_class = G_OBJECT_CLASS (klass);
69 object_class->finalize = dfu_firmware_finalize;
70 }
71
72 static void
73 dfu_firmware_init (DfuFirmware *firmware)
74 {
75 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
76 priv->vid = 0xffff;
77 priv->pid = 0xffff;
78 priv->release = 0xffff;
79 priv->images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
80 priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
81 priv->symtab = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
82 }
83
84 static void
85 dfu_firmware_finalize (GObject *object)
86 {
87 DfuFirmware *firmware = DFU_FIRMWARE (object);
88 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
89
90 g_ptr_array_unref (priv->images);
91 g_hash_table_destroy (priv->metadata);
92 g_hash_table_destroy (priv->symtab);
93
94 G_OBJECT_CLASS (dfu_firmware_parent_class)->finalize (object);
95 }
96
97 /**
98 * dfu_firmware_new:
99 *
100 * Creates a new DFU firmware object.
101 *
102 * Return value: a new #DfuFirmware
103 *
104 * Since: 0.5.4
105 **/
106 DfuFirmware *
107 dfu_firmware_new (void)
108 {
109 DfuFirmware *firmware;
110 firmware = g_object_new (DFU_TYPE_FIRMWARE, NULL);
111 return firmware;
112 }
113
114 /**
115 * dfu_firmware_get_image:
116 * @firmware: a #DfuFirmware
117 * @alt_setting: an alternative setting, typically 0x00
118 *
119 * Gets an image from the firmware file.
120 *
121 * Return value: (transfer none): a #DfuImage, or %NULL for not found
122 *
123 * Since: 0.5.4
124 **/
125 DfuImage *
126 dfu_firmware_get_image (DfuFirmware *firmware, guint8 alt_setting)
127 {
128 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
129 DfuImage *im;
130 guint i;
131
132 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
133
134 /* find correct image */
135 for (i = 0; i < priv->images->len; i++) {
136 im = g_ptr_array_index (priv->images, i);
137 if (dfu_image_get_alt_setting (im) == alt_setting)
138 return im;
139 }
140 return NULL;
141 }
142
143 /**
144 * dfu_firmware_get_image_by_name:
145 * @firmware: a #DfuFirmware
146 * @name: an alternative setting name
147 *
148 * Gets an image from the firmware file.
149 *
150 * Return value: (transfer none): a #DfuImage, or %NULL for not found
151 *
152 * Since: 0.5.4
153 **/
154 DfuImage *
155 dfu_firmware_get_image_by_name (DfuFirmware *firmware, const gchar *name)
156 {
157 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
158 DfuImage *im;
159 guint i;
160
161 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
162
163 /* find correct image */
164 for (i = 0; i < priv->images->len; i++) {
165 im = g_ptr_array_index (priv->images, i);
166 if (g_strcmp0 (dfu_image_get_name (im), name) == 0)
167 return im;
168 }
169 return NULL;
170 }
171
172 /**
173 * dfu_firmware_get_image_default:
174 * @firmware: a #DfuFirmware
175 *
176 * Gets the default image from the firmware file.
177 *
178 * Return value: (transfer none): a #DfuImage, or %NULL for not found
179 *
180 * Since: 0.5.4
181 **/
182 DfuImage *
183 dfu_firmware_get_image_default (DfuFirmware *firmware)
184 {
185 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
186 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
187 if (priv->images->len == 0)
188 return NULL;
189 return g_ptr_array_index (priv->images, 0);
190 }
191
192 /**
193 * dfu_firmware_get_images:
194 * @firmware: a #DfuFirmware
195 *
196 * Gets all the images contained in this firmware file.
197 *
198 * Return value: (transfer none) (element-type DfuImage): list of images
199 *
200 * Since: 0.5.4
201 **/
202 GPtrArray *
203 dfu_firmware_get_images (DfuFirmware *firmware)
204 {
205 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
206 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
207 return priv->images;
208 }
209
210 /**
211 * dfu_firmware_get_size:
212 * @firmware: a #DfuFirmware
213 *
214 * Gets the size of all the images in the firmware.
215 *
216 * This only returns actual data that would be sent to the device and
217 * does not include any padding.
218 *
219 * Return value: a integer value, or 0 if there are no images.
220 *
221 * Since: 0.5.4
222 **/
223 guint32
224 dfu_firmware_get_size (DfuFirmware *firmware)
225 {
226 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
227 guint32 length = 0;
228 guint i;
229 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0);
230 for (i = 0; i < priv->images->len; i++) {
231 DfuImage *image = g_ptr_array_index (priv->images, i);
232 length += dfu_image_get_size (image);
233 }
234 return length;
235 }
236
237 /**
238 * dfu_firmware_add_image:
239 * @firmware: a #DfuFirmware
240 * @image: a #DfuImage
241 *
242 * Adds an image to the list of images.
243 *
244 * Since: 0.5.4
245 **/
246 void
247 dfu_firmware_add_image (DfuFirmware *firmware, DfuImage *image)
248 {
249 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
250 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
251 g_return_if_fail (DFU_IS_IMAGE (image));
252 g_ptr_array_add (priv->images, g_object_ref (image));
253 }
254
255 /**
256 * dfu_firmware_get_vid:
257 * @firmware: a #DfuFirmware
258 *
259 * Gets the vendor ID.
260 *
261 * Return value: a vendor ID, or 0xffff for unset
262 *
263 * Since: 0.5.4
264 **/
265 guint16
266 dfu_firmware_get_vid (DfuFirmware *firmware)
267 {
268 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
269 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
270 return priv->vid;
271 }
272
273 /**
274 * dfu_firmware_get_pid:
275 * @firmware: a #DfuFirmware
276 *
277 * Gets the product ID.
278 *
279 * Return value: a product ID, or 0xffff for unset
280 *
281 * Since: 0.5.4
282 **/
283 guint16
284 dfu_firmware_get_pid (DfuFirmware *firmware)
285 {
286 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
287 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
288 return priv->pid;
289 }
290
291 /**
292 * dfu_firmware_get_release:
293 * @firmware: a #DfuFirmware
294 *
295 * Gets the device ID.
296 *
297 * Return value: a device ID, or 0xffff for unset
298 *
299 * Since: 0.5.4
300 **/
301 guint16
302 dfu_firmware_get_release (DfuFirmware *firmware)
303 {
304 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
305 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
306 return priv->release;
307 }
308
309 /**
310 * dfu_firmware_get_format:
311 * @firmware: a #DfuFirmware
312 *
313 * Gets the DFU version.
314 *
315 * Return value: a version, or 0x0 for unset
316 *
317 * Since: 0.5.4
318 **/
319 guint16
320 dfu_firmware_get_format (DfuFirmware *firmware)
321 {
322 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
323 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
324 return priv->format;
325 }
326
327 /**
328 * dfu_firmware_set_vid:
329 * @firmware: a #DfuFirmware
330 * @vid: vendor ID, or 0xffff for unset
331 *
332 * Sets the vendor ID.
333 *
334 * Since: 0.5.4
335 **/
336 void
337 dfu_firmware_set_vid (DfuFirmware *firmware, guint16 vid)
338 {
339 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
340 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
341 priv->vid = vid;
342 }
343
344 /**
345 * dfu_firmware_set_pid:
346 * @firmware: a #DfuFirmware
347 * @pid: product ID, or 0xffff for unset
348 *
349 * Sets the product ID.
350 *
351 * Since: 0.5.4
352 **/
353 void
354 dfu_firmware_set_pid (DfuFirmware *firmware, guint16 pid)
355 {
356 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
357 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
358 priv->pid = pid;
359 }
360
361 /**
362 * dfu_firmware_set_release:
363 * @firmware: a #DfuFirmware
364 * @release: device ID, or 0xffff for unset
365 *
366 * Sets the device ID.
367 *
368 * Since: 0.5.4
369 **/
370 void
371 dfu_firmware_set_release (DfuFirmware *firmware, guint16 release)
372 {
373 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
374 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
375 priv->release = release;
376 }
377
378 /**
379 * dfu_firmware_set_format:
380 * @firmware: a #DfuFirmware
381 * @format: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFUSE
382 *
383 * Sets the DFU version in BCD format.
384 *
385 * Since: 0.5.4
386 **/
387 void
388 dfu_firmware_set_format (DfuFirmware *firmware, DfuFirmwareFormat format)
389 {
390 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
391 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
392 priv->format = format;
393 }
394
395 static void
396 dfu_firmware_parse_altos_vid_pid (DfuFirmware *firmware)
397 {
398 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
399 guint32 addr32;
400
401 /* find symbol */
402 addr32 = dfu_firmware_lookup_symbol (firmware, "ao_usb_descriptors");
403 if (addr32 == 0x0)
404 return;
405
406 /* search each element */
407 for (guint i = 0; i < priv->images->len; i++) {
408 DfuImage *image = g_ptr_array_index (priv->images, i);
409 DfuElement *element;
410 GBytes *bytes_tmp;
411 const guint8 *data;
412 gsize length;
413 guint32 element_address;
414 guint16 vid, pid, release;
415
416 /* get element data */
417 element = dfu_image_get_element_default (image);
418 if (element == NULL)
419 continue;
420
421 /* check address is in this element */
422 element_address = dfu_element_get_address (element);
423 if (element_address > addr32)
424 continue;
425 bytes_tmp = dfu_element_get_contents (element);
426 if (bytes_tmp == NULL)
427 continue;
428
429 /* check this element is big enough */
430 data = g_bytes_get_data (bytes_tmp, &length);
431 if (addr32 - element_address > length)
432 continue;
433
434 /* read the USB descriptor */
435 addr32 -= element_address;
436 memcpy (&vid, &data[addr32 + 8], 2);
437 memcpy (&pid, &data[addr32 + 10], 2);
438 memcpy (&release, &data[addr32 + 12], 2);
439 dfu_firmware_set_vid (firmware, GUINT32_FROM_LE (vid));
440 dfu_firmware_set_pid (firmware, GUINT32_FROM_LE (pid));
441 dfu_firmware_set_release (firmware, GUINT32_FROM_LE (release));
442 }
443 }
444
445 /**
446 * dfu_firmware_parse_data:
447 * @firmware: a #DfuFirmware
448 * @bytes: raw firmware data
449 * @flags: optional flags, e.g. %DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST
450 * @error: a #GError, or %NULL
451 *
452 * Parses firmware data which may have an optional DFU suffix.
453 *
454 * Return value: %TRUE for success
455 *
456 * Since: 0.5.4
457 **/
458 gboolean
459 dfu_firmware_parse_data (DfuFirmware *firmware, GBytes *bytes,
460 DfuFirmwareParseFlags flags, GError **error)
461 {
462 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
463
464 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE);
465 g_return_val_if_fail (bytes != NULL, FALSE);
466 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
467
468 /* set defaults */
469 priv->vid = 0xffff;
470 priv->pid = 0xffff;
471 priv->release = 0xffff;
472
473 /* try to get format if not already set */
474 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
475 priv->format = dfu_firmware_detect_ihex (bytes);
476 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
477 priv->format = dfu_firmware_detect_dfu (bytes);
478 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
479 priv->format = dfu_firmware_detect_elf (bytes);
480 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
481 priv->format = dfu_firmware_detect_raw (bytes);
482
483 /* handled easily */
484 switch (priv->format) {
485 case DFU_FIRMWARE_FORMAT_INTEL_HEX:
486 if (!dfu_firmware_from_ihex (firmware, bytes, flags, error))
487 return FALSE;
488 break;
489 case DFU_FIRMWARE_FORMAT_ELF:
490 if (!dfu_firmware_from_elf (firmware, bytes, flags, error))
491 return FALSE;
492 break;
493 case DFU_FIRMWARE_FORMAT_DFU:
494 case DFU_FIRMWARE_FORMAT_DFUSE:
495 if (!dfu_firmware_from_dfu (firmware, bytes, flags, error))
496 return FALSE;
497 break;
498 default:
499 if (!dfu_firmware_from_raw (firmware, bytes, flags, error))
500 return FALSE;
501 break;
502 }
503
504 /* get the VID/PID for altos devices */
505 dfu_firmware_parse_altos_vid_pid (firmware);
506
507 return TRUE;
508 }
509
510 /**
511 * dfu_firmware_parse_file:
512 * @firmware: a #DfuFirmware
513 * @file: a #GFile to load and parse
514 * @flags: optional flags, e.g. %DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST
515 * @cancellable: a #GCancellable, or %NULL
516 * @error: a #GError, or %NULL
517 *
518 * Parses a DFU firmware, which may contain an optional footer.
519 *
520 * Return value: %TRUE for success
521 *
522 * Since: 0.5.4
523 **/
524 gboolean
525 dfu_firmware_parse_file (DfuFirmware *firmware, GFile *file,
526 DfuFirmwareParseFlags flags,
527 GCancellable *cancellable, GError **error)
528 {
529 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
530 gchar *contents = NULL;
531 gsize length = 0;
532 g_autofree gchar *basename = NULL;
533 g_autoptr(GBytes) bytes = NULL;
534
535 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE);
536 g_return_val_if_fail (G_IS_FILE (file), FALSE);
537 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
538
539 /* guess cipher kind based on file extension */
540 basename = g_file_get_basename (file);
541 if (g_str_has_suffix (basename, ".xdfu"))
542 priv->cipher_kind = DFU_CIPHER_KIND_XTEA;
543
544 if (!g_file_load_contents (file, cancellable, &contents,
545 &length, NULL, error))
546 return FALSE;
547 bytes = g_bytes_new_take (contents, length);
548 return dfu_firmware_parse_data (firmware, bytes, flags, error);
549 }
550
551 /**
552 * dfu_firmware_get_metadata:
553 * @firmware: a #DfuFirmware
554 * @key: metadata string key
555 *
556 * Gets metadata from the store with a specific key.
557 *
558 * Return value: the metadata value, or %NULL for unset
559 *
560 * Since: 0.5.4
561 **/
562 const gchar *
563 dfu_firmware_get_metadata (DfuFirmware *firmware, const gchar *key)
564 {
565 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
566 return g_hash_table_lookup (priv->metadata, key);
567 }
568
569 /**
570 * dfu_firmware_get_metadata_table:
571 * @firmware: a #DfuFirmware
572 *
573 * Gets all metadata from the store.
574 *
575 * Return value: (transfer none): the metadata hash table
576 *
577 * Since: 0.6.3
578 **/
579 GHashTable *
580 dfu_firmware_get_metadata_table (DfuFirmware *firmware)
581 {
582 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
583 return priv->metadata;
584 }
585
586 /**
587 * dfu_firmware_set_metadata:
588 * @firmware: a #DfuFirmware
589 * @key: metadata string key
590 * @value: metadata string value
591 *
592 * Sets a metadata value with a specific key.
593 *
594 * Since: 0.5.4
595 **/
596 void
597 dfu_firmware_set_metadata (DfuFirmware *firmware, const gchar *key, const gchar *value)
598 {
599 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
600 g_debug ("adding metadata %s=%s", key, value);
601 g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value));
602 }
603
604 /**
605 * dfu_firmware_remove_metadata:
606 * @firmware: a #DfuFirmware
607 * @key: metadata string key
608 *
609 * Removes a metadata item from the store
610 *
611 * Since: 0.5.4
612 **/
613 void
614 dfu_firmware_remove_metadata (DfuFirmware *firmware, const gchar *key)
615 {
616 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
617 g_debug ("removing metadata %s", key);
618 g_hash_table_remove (priv->metadata, key);
619 }
620
621 static gboolean
622 dfu_firmware_check_acceptable_for_format (DfuFirmware *firmware, GError **error)
623 {
624 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
625
626 /* always okay */
627 if (priv->images->len <= 1)
628 return TRUE;
629 if (priv->format == DFU_FIRMWARE_FORMAT_DFUSE)
630 return TRUE;
631
632 /* one is usual, and 2 is okay if one image is the signature */
633 if (priv->format == DFU_FIRMWARE_FORMAT_INTEL_HEX) {
634 if (priv->images->len == 2 &&
635 dfu_firmware_get_image_by_name (firmware, "signature") != NULL)
636 return TRUE;
637 }
638
639 /* unsupported */
640 g_set_error (error,
641 DFU_ERROR,
642 DFU_ERROR_INTERNAL,
643 "multiple images (%u) not supported for %s",
644 priv->images->len,
645 dfu_firmware_format_to_string (priv->format));
646 return TRUE;
647 }
648
649 /**
650 * dfu_firmware_write_data:
651 * @firmware: a #DfuFirmware
652 * @error: a #GError, or %NULL
653 *
654 * Writes DFU data to a data blob with a DFU-specific footer.
655 *
656 * Return value: (transfer none): firmware data
657 *
658 * Since: 0.5.4
659 **/
660 GBytes *
661 dfu_firmware_write_data (DfuFirmware *firmware, GError **error)
662 {
663 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
664
665 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
666 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
667
668 /* at least one image */
669 if (priv->images == 0) {
670 g_set_error_literal (error,
671 DFU_ERROR,
672 DFU_ERROR_INTERNAL,
673 "no image data to write");
674 return NULL;
675 }
676
677 /* does the format support this many images */
678 if (!dfu_firmware_check_acceptable_for_format (firmware, error))
679 return NULL;
680
681 /* raw */
682 if (priv->format == DFU_FIRMWARE_FORMAT_RAW)
683 return dfu_firmware_to_raw (firmware, error);
684
685 /* DFU or DfuSe*/
686 if (priv->format == DFU_FIRMWARE_FORMAT_DFU ||
687 priv->format == DFU_FIRMWARE_FORMAT_DFUSE)
688 return dfu_firmware_to_dfu (firmware, error);
689
690 /* Intel HEX */
691 if (priv->format == DFU_FIRMWARE_FORMAT_INTEL_HEX)
692 return dfu_firmware_to_ihex (firmware, error);
693
694 /* ELF */
695 if (priv->format == DFU_FIRMWARE_FORMAT_ELF)
696 return dfu_firmware_to_elf (firmware, error);
697
698 /* invalid */
699 g_set_error (error,
700 DFU_ERROR,
701 DFU_ERROR_INTERNAL,
702 "invalid format for write (0x%04x)",
703 priv->format);
704 return NULL;
705 }
706
707 /**
708 * dfu_firmware_write_file:
709 * @firmware: a #DfuFirmware
710 * @file: a #GFile
711 * @cancellable: a #GCancellable, or %NULL
712 * @error: a #GError, or %NULL
713 *
714 * Writes a DFU firmware with the optional footer.
715 *
716 * Return value: %TRUE for success
717 *
718 * Since: 0.5.4
719 **/
720 gboolean
721 dfu_firmware_write_file (DfuFirmware *firmware, GFile *file,
722 GCancellable *cancellable, GError **error)
723 {
724 const guint8 *data;
725 gsize length = 0;
726 g_autoptr(GBytes) bytes = NULL;
727
728 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE);
729 g_return_val_if_fail (G_IS_FILE (file), FALSE);
730 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
731
732 /* get blob */
733 bytes = dfu_firmware_write_data (firmware, error);
734 if (bytes == NULL)
735 return FALSE;
736
737 /* save to firmware */
738 data = g_bytes_get_data (bytes, &length);
739 return g_file_replace_contents (file,
740 (const gchar *) data,
741 length,
742 NULL,
743 FALSE,
744 G_FILE_CREATE_NONE,
745 NULL,
746 cancellable,
747 error);
748 }
749
750 /**
751 * dfu_firmware_to_string:
752 * @firmware: a #DfuFirmware
753 *
754 * Returns a string representaiton of the object.
755 *
756 * Return value: NULL terminated string, or %NULL for invalid
757 *
758 * Since: 0.5.4
759 **/
760 gchar *
761 dfu_firmware_to_string (DfuFirmware *firmware)
762 {
763 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
764 DfuImage *image;
765 GList *l;
766 GString *str;
767 guint i;
768 g_autofree gchar *release_str = NULL;
769 g_autoptr(GList) keys = NULL;
770
771 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
772
773 release_str = as_utils_version_from_uint16 (priv->release,
774 AS_VERSION_PARSE_FLAG_NONE);
775 str = g_string_new ("");
776 g_string_append_printf (str, "vid: 0x%04x\n", priv->vid);
777 g_string_append_printf (str, "pid: 0x%04x\n", priv->pid);
778 g_string_append_printf (str, "release: 0x%04x [%s]\n",
779 priv->release, release_str);
780 g_string_append_printf (str, "format: %s [0x%04x]\n",
781 dfu_firmware_format_to_string (priv->format),
782 priv->format);
783 g_string_append_printf (str, "cipher: %s\n",
784 dfu_cipher_kind_to_string (priv->cipher_kind));
785
786 /* print metadata */
787 keys = g_hash_table_get_keys (priv->metadata);
788 for (l = keys; l != NULL; l = l->next) {
789 const gchar *key;
790 const gchar *value;
791 key = l->data;
792 value = g_hash_table_lookup (priv->metadata, key);
793 g_string_append_printf (str, "metadata: %s=%s\n", key, value);
794 }
795
796 /* print images */
797 for (i = 0; i < priv->images->len; i++) {
798 g_autofree gchar *tmp = NULL;
799 image = g_ptr_array_index (priv->images, i);
800 tmp = dfu_image_to_string (image);
801 g_string_append_printf (str, "= IMAGE %u =\n", i);
802 g_string_append_printf (str, "%s\n", tmp);
803 }
804
805 g_string_truncate (str, str->len - 1);
806 return g_string_free (str, FALSE);
807 }
808
809 /**
810 * dfu_firmware_format_to_string:
811 * @format: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFU
812 *
813 * Returns a string representaiton of the format.
814 *
815 * Return value: NULL terminated string, or %NULL for invalid
816 *
817 * Since: 0.5.4
818 **/
819 const gchar *
820 dfu_firmware_format_to_string (DfuFirmwareFormat format)
821 {
822 if (format == DFU_FIRMWARE_FORMAT_RAW)
823 return "raw";
824 if (format == DFU_FIRMWARE_FORMAT_DFU)
825 return "dfu";
826 if (format == DFU_FIRMWARE_FORMAT_DFUSE)
827 return "dfuse";
828 if (format == DFU_FIRMWARE_FORMAT_INTEL_HEX)
829 return "ihex";
830 if (format == DFU_FIRMWARE_FORMAT_ELF)
831 return "elf";
832 return NULL;
833 }
834
835 /**
836 * dfu_firmware_format_from_string:
837 * @format: a format string, e.g. `dfuse`
838 *
839 * Returns an enumerated version of the format.
840 *
841 * Return value: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFUSE
842 *
843 * Since: 0.7.3
844 **/
845 DfuFirmwareFormat
846 dfu_firmware_format_from_string (const gchar *format)
847 {
848 if (g_strcmp0 (format, "raw") == 0)
849 return DFU_FIRMWARE_FORMAT_RAW;
850 if (g_strcmp0 (format, "dfu") == 0)
851 return DFU_FIRMWARE_FORMAT_DFU;
852 if (g_strcmp0 (format, "dfuse") == 0)
853 return DFU_FIRMWARE_FORMAT_DFUSE;
854 if (g_strcmp0 (format, "ihex") == 0)
855 return DFU_FIRMWARE_FORMAT_INTEL_HEX;
856 if (g_strcmp0 (format, "elf") == 0)
857 return DFU_FIRMWARE_FORMAT_ELF;
858 return DFU_FIRMWARE_FORMAT_UNKNOWN;
859 }
860
861 /**
862 * dfu_firmware_get_cipher_kind:
863 * @firmware: a #DfuFirmware
864 *
865 * Returns the kind of cipher used by the firmware file.
866 *
867 * NOTE: this value is based on a heuristic, and may not be accurate.
868 * The value %DFU_CIPHER_KIND_NONE will be returned when the cipher
869 * is not recognised.
870 *
871 * Return value: NULL terminated string, or %NULL for invalid
872 *
873 * Since: 0.5.4
874 **/
875 DfuCipherKind
876 dfu_firmware_get_cipher_kind (DfuFirmware *firmware)
877 {
878 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
879 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0);
880 return priv->cipher_kind;
881 }
882
883 /**
884 * dfu_firmware_set_cipher_kind:
885 * @firmware: a #DfuFirmware
886 * @cipher_kind: a #DfuCipherKind, e.g. %DFU_CIPHER_KIND_XTEA
887 *
888 * Sets the kind of cipher used by the firmware file.
889 *
890 * Since: 0.6.3
891 **/
892 void
893 dfu_firmware_set_cipher_kind (DfuFirmware *firmware, DfuCipherKind cipher_kind)
894 {
895 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
896 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
897 priv->cipher_kind = cipher_kind;
898 }
899
900 /**
901 * dfu_firmware_add_symbol:
902 * @firmware: a #DfuFirmware
903 * @symbol_name: a valid symbol name
904 * @symbol_addr: a symbol memory address
905 *
906 * Adds a symbol to the global map for the firmware.
907 *
908 * NOTE: Only certain types of firmware can contain a symbol table.
909 *
910 * Since: 0.7.4
911 **/
912 void
913 dfu_firmware_add_symbol (DfuFirmware *firmware,
914 const gchar *symbol_name,
915 guint32 symbol_addr)
916 {
917 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
918 g_hash_table_insert (priv->symtab,
919 g_strdup (symbol_name),
920 GUINT_TO_POINTER (symbol_addr));
921 }
922
923 /**
924 * dfu_firmware_lookup_symbol:
925 * @firmware: a #DfuFirmware
926 * @symbol_name: a valid symbol name
927 *
928 * Returns the address of a symbol from the global map.
929 *
930 * NOTE: Only certain types of firmware can contain a symbol table.
931 *
932 * Return value: address of the symbol, or 0x0 for not found.
933 *
934 * Since: 0.7.4
935 **/
936 guint32
937 dfu_firmware_lookup_symbol (DfuFirmware *firmware, const gchar *symbol_name)
938 {
939 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
940 return GPOINTER_TO_UINT (g_hash_table_lookup (priv->symtab,
941 symbol_name));
942 }
943
944 /**
945 * dfu_firmware_get_symbols:
946 * @firmware: a #DfuFirmware
947 *
948 * Gets all the symbols currently defined.
949 *
950 * Return value: (element-type utf8) (transfer container): symbol names
951 *
952 * Since: 0.7.4
953 **/
954 GPtrArray *
955 dfu_firmware_get_symbols (DfuFirmware *firmware)
956 {
957 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
958 GPtrArray *array = g_ptr_array_new_with_free_func (g_free);
959 GList *l;
960 g_autoptr(GList) keys = g_hash_table_get_keys (priv->symtab);
961 for (l = keys; l != NULL; l = l->next)
962 g_ptr_array_add (array, g_strdup (l->data));
963 return array;
964 }
+0
-152
libdfu/dfu-firmware.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FIRMWARE_H
22 #define __DFU_FIRMWARE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-common.h"
28 #include "dfu-image.h"
29
30 G_BEGIN_DECLS
31
32 #define DFU_TYPE_FIRMWARE (dfu_firmware_get_type ())
33 G_DECLARE_DERIVABLE_TYPE (DfuFirmware, dfu_firmware, DFU, FIRMWARE, GObject)
34
35 struct _DfuFirmwareClass
36 {
37 GObjectClass parent_class;
38 /*< private >*/
39 /* Padding for future expansion */
40 void (*_dfu_firmware_reserved1) (void);
41 void (*_dfu_firmware_reserved2) (void);
42 void (*_dfu_firmware_reserved3) (void);
43 void (*_dfu_firmware_reserved4) (void);
44 void (*_dfu_firmware_reserved5) (void);
45 void (*_dfu_firmware_reserved6) (void);
46 void (*_dfu_firmware_reserved7) (void);
47 void (*_dfu_firmware_reserved8) (void);
48 void (*_dfu_firmware_reserved9) (void);
49 };
50
51 /**
52 * DfuFirmwareParseFlags:
53 * @DFU_FIRMWARE_PARSE_FLAG_NONE: No flags set
54 * @DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST: Do not verify the CRC
55 * @DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST: Do not verify the DFU version
56 * @DFU_FIRMWARE_PARSE_FLAG_NO_METADATA: Do not read the metadata table
57 *
58 * The optional flags used for parsing.
59 **/
60 typedef enum {
61 DFU_FIRMWARE_PARSE_FLAG_NONE = 0,
62 DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST = (1 << 0),
63 DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST = (1 << 1),
64 DFU_FIRMWARE_PARSE_FLAG_NO_METADATA = (1 << 2),
65 /*< private >*/
66 DFU_FIRMWARE_PARSE_FLAG_LAST
67 } DfuFirmwareParseFlags;
68
69 /**
70 * DfuFirmwareFormat:
71 * @DFU_FIRMWARE_FORMAT_UNKNOWN: Format unknown
72 * @DFU_FIRMWARE_FORMAT_RAW: Raw format
73 * @DFU_FIRMWARE_FORMAT_DFU: DFU footer
74 * @DFU_FIRMWARE_FORMAT_DFUSE: DfuSe header
75 * @DFU_FIRMWARE_FORMAT_INTEL_HEX: Intel HEX
76 * @DFU_FIRMWARE_FORMAT_ELF: ELF
77 *
78 * The known versions of the DFU standard in BCD format.
79 **/
80 typedef enum {
81 DFU_FIRMWARE_FORMAT_UNKNOWN,
82 DFU_FIRMWARE_FORMAT_RAW,
83 DFU_FIRMWARE_FORMAT_DFU,
84 DFU_FIRMWARE_FORMAT_DFUSE,
85 DFU_FIRMWARE_FORMAT_INTEL_HEX,
86 DFU_FIRMWARE_FORMAT_ELF,
87 /*< private >*/
88 DFU_FIRMWARE_FORMAT_LAST
89 } DfuFirmwareFormat;
90
91 DfuFirmware *dfu_firmware_new (void);
92
93 const gchar *dfu_firmware_format_to_string (DfuFirmwareFormat format);
94 DfuFirmwareFormat dfu_firmware_format_from_string(const gchar *format);
95
96 DfuImage *dfu_firmware_get_image (DfuFirmware *firmware,
97 guint8 alt_setting);
98 DfuImage *dfu_firmware_get_image_by_name (DfuFirmware *firmware,
99 const gchar *name);
100 DfuImage *dfu_firmware_get_image_default (DfuFirmware *firmware);
101 GPtrArray *dfu_firmware_get_images (DfuFirmware *firmware);
102 guint16 dfu_firmware_get_vid (DfuFirmware *firmware);
103 guint16 dfu_firmware_get_pid (DfuFirmware *firmware);
104 guint16 dfu_firmware_get_release (DfuFirmware *firmware);
105 guint16 dfu_firmware_get_format (DfuFirmware *firmware);
106 guint32 dfu_firmware_get_size (DfuFirmware *firmware);
107 DfuCipherKind dfu_firmware_get_cipher_kind (DfuFirmware *firmware);
108
109 void dfu_firmware_add_image (DfuFirmware *firmware,
110 DfuImage *image);
111 void dfu_firmware_set_vid (DfuFirmware *firmware,
112 guint16 vid);
113 void dfu_firmware_set_pid (DfuFirmware *firmware,
114 guint16 pid);
115 void dfu_firmware_set_release (DfuFirmware *firmware,
116 guint16 release);
117 void dfu_firmware_set_format (DfuFirmware *firmware,
118 DfuFirmwareFormat format);
119 void dfu_firmware_set_cipher_kind (DfuFirmware *firmware,
120 DfuCipherKind cipher_kind);
121
122 gboolean dfu_firmware_parse_data (DfuFirmware *firmware,
123 GBytes *bytes,
124 DfuFirmwareParseFlags flags,
125 GError **error);
126 gboolean dfu_firmware_parse_file (DfuFirmware *firmware,
127 GFile *file,
128 DfuFirmwareParseFlags flags,
129 GCancellable *cancellable,
130 GError **error);
131
132 GBytes *dfu_firmware_write_data (DfuFirmware *firmware,
133 GError **error);
134 gboolean dfu_firmware_write_file (DfuFirmware *firmware,
135 GFile *file,
136 GCancellable *cancellable,
137 GError **error);
138 gchar *dfu_firmware_to_string (DfuFirmware *firmware);
139
140 GHashTable *dfu_firmware_get_metadata_table(DfuFirmware *firmware);
141 const gchar *dfu_firmware_get_metadata (DfuFirmware *firmware,
142 const gchar *key);
143 void dfu_firmware_set_metadata (DfuFirmware *firmware,
144 const gchar *key,
145 const gchar *value);
146 void dfu_firmware_remove_metadata (DfuFirmware *firmware,
147 const gchar *key);
148
149 G_END_DECLS
150
151 #endif /* __DFU_FIRMWARE_H */
+0
-345
libdfu/dfu-format-dfu.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-dfu.h"
27 #include "dfu-format-metadata.h"
28 #include "dfu-format-dfuse.h"
29 #include "dfu-format-raw.h"
30 #include "dfu-image.h"
31 #include "dfu-error.h"
32
33 typedef struct __attribute__((packed)) {
34 guint16 release;
35 guint16 pid;
36 guint16 vid;
37 guint16 ver;
38 guint8 sig[3];
39 guint8 len;
40 guint32 crc;
41 } DfuFirmwareFooter;
42
43 /**
44 * dfu_firmware_detect_dfu: (skip)
45 * @bytes: data to parse
46 *
47 * Attempts to sniff the data and work out the firmware format
48 *
49 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW
50 **/
51 DfuFirmwareFormat
52 dfu_firmware_detect_dfu (GBytes *bytes)
53 {
54 DfuFirmwareFooter *ftr;
55 guint8 *data;
56 gsize len;
57
58 /* check data size */
59 data = (guint8 *) g_bytes_get_data (bytes, &len);
60 if (len < 16)
61 return DFU_FIRMWARE_FORMAT_UNKNOWN;
62
63 /* check for DFU signature */
64 ftr = (DfuFirmwareFooter *) &data[len - sizeof(DfuFirmwareFooter)];
65 if (memcmp (ftr->sig, "UFD", 3) != 0)
66 return DFU_FIRMWARE_FORMAT_UNKNOWN;
67
68 /* check versions */
69 switch (GUINT16_FROM_LE (ftr->ver)) {
70 case DFU_VERSION_DFU_1_0:
71 case DFU_VERSION_DFU_1_1:
72 return DFU_FIRMWARE_FORMAT_DFU;
73 case DFU_VERSION_DFUSE:
74 return DFU_FIRMWARE_FORMAT_DFUSE;
75 default:
76 break;
77 }
78 return DFU_FIRMWARE_FORMAT_UNKNOWN;
79 }
80
81 static guint32 _crctbl[] = {
82 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
83 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
84 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
85 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
86 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
87 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
88 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
89 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
90 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
91 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
92 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
93 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
94 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
95 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
96 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
97 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
98 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
99 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
100 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
101 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
102 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
103 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
104 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
105 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
106 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
107 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
108 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
109 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
110 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
111 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
112 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
113 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
114 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
115 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
116 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
117 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
118 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
119 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
120 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
121 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
122 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
123 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
124 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
125
126 static guint32
127 dfu_firmware_generate_crc32 (const guint8 *data, gsize length)
128 {
129 guint i;
130 guint32 accum = 0xffffffff;
131 for (i = 0; i < length; i++)
132 accum = _crctbl[(accum^data[i]) & 0xff] ^ (accum >> 8);
133 return accum;
134 }
135
136 /**
137 * dfu_firmware_from_dfu: (skip)
138 * @firmware: a #DfuFirmware
139 * @bytes: data to parse
140 * @flags: some #DfuFirmwareParseFlags
141 * @error: a #GError, or %NULL
142 *
143 * Unpacks into a firmware object from dfu data.
144 *
145 * Returns: %TRUE for success
146 **/
147 gboolean
148 dfu_firmware_from_dfu (DfuFirmware *firmware,
149 GBytes *bytes,
150 DfuFirmwareParseFlags flags,
151 GError **error)
152 {
153 DfuFirmwareFooter *ftr;
154 const gchar *cipher_str;
155 gsize len;
156 guint32 crc;
157 guint32 crc_new;
158 guint8 *data;
159 g_autoptr(GBytes) contents = NULL;
160
161 /* check data size */
162 data = (guint8 *) g_bytes_get_data (bytes, &len);
163 if (len < 16) {
164 g_set_error_literal (error,
165 DFU_ERROR,
166 DFU_ERROR_INTERNAL,
167 "size check failed, too small");
168 return FALSE;
169 }
170
171 /* check for DFU signature */
172 ftr = (DfuFirmwareFooter *) &data[len - sizeof(DfuFirmwareFooter)];
173 if (memcmp (ftr->sig, "UFD", 3) != 0) {
174 g_set_error_literal (error,
175 DFU_ERROR,
176 DFU_ERROR_INTERNAL,
177 "no DFU signature");
178 return FALSE;
179 }
180
181 /* check version */
182 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST) == 0) {
183 if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFU &&
184 dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) {
185 g_set_error (error,
186 DFU_ERROR,
187 DFU_ERROR_INTERNAL,
188 "version check failed, got %04x",
189 dfu_firmware_get_format (firmware));
190 return FALSE;
191 }
192 }
193
194 /* verify the checksum */
195 crc = GUINT32_FROM_LE (ftr->crc);
196 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
197 crc_new = dfu_firmware_generate_crc32 (data, len - 4);
198 if (crc != crc_new) {
199 g_set_error (error,
200 DFU_ERROR,
201 DFU_ERROR_INTERNAL,
202 "CRC failed, expected %04x, got %04x",
203 crc_new, GUINT32_FROM_LE (ftr->crc));
204 return FALSE;
205 }
206 }
207
208 /* set from footer */
209 dfu_firmware_set_vid (firmware, GUINT16_FROM_LE (ftr->vid));
210 dfu_firmware_set_pid (firmware, GUINT16_FROM_LE (ftr->pid));
211 dfu_firmware_set_release (firmware, GUINT16_FROM_LE (ftr->release));
212
213 /* check reported length */
214 if (ftr->len > len) {
215 g_set_error (error,
216 DFU_ERROR,
217 DFU_ERROR_INTERNAL,
218 "reported firmware size %04x larger than file %04x",
219 (guint) ftr->len, (guint) len);
220 return FALSE;
221 }
222
223 /* parse the optional metadata segment */
224 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_METADATA) == 0) {
225 gsize offset = len - ftr->len;
226 g_autoptr(GBytes) md = g_bytes_new (&data[offset], ftr->len);
227 if (!dfu_firmware_from_metadata (firmware, md, flags, error))
228 return FALSE;
229 }
230
231 /* set this automatically */
232 cipher_str = dfu_firmware_get_metadata (firmware, DFU_METADATA_KEY_CIPHER_KIND);
233 if (cipher_str != NULL) {
234 if (g_strcmp0 (cipher_str, "XTEA") == 0)
235 dfu_firmware_set_cipher_kind (firmware, DFU_CIPHER_KIND_XTEA);
236 else if (g_strcmp0 (cipher_str, "DEVO") == 0)
237 dfu_firmware_set_cipher_kind (firmware, DFU_CIPHER_KIND_DEVO);
238 else
239 g_warning ("Unknown CipherKind: %s", cipher_str);
240 }
241
242 /* parse DfuSe prefix */
243 contents = g_bytes_new_from_bytes (bytes, 0, len - ftr->len);
244 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE)
245 return dfu_firmware_from_dfuse (firmware, contents, flags, error);
246
247 /* just copy old-plain DFU file */
248 return dfu_firmware_from_raw (firmware, contents, flags, error);
249 }
250
251 static DfuVersion
252 dfu_convert_version (DfuFirmwareFormat format)
253 {
254 if (format == DFU_FIRMWARE_FORMAT_DFU)
255 return DFU_VERSION_DFU_1_0;
256 if (format == DFU_FIRMWARE_FORMAT_DFUSE)
257 return DFU_VERSION_DFUSE;
258 return DFU_VERSION_UNKNOWN;
259 }
260
261 static GBytes *
262 dfu_firmware_add_footer (DfuFirmware *firmware, GBytes *contents, GError **error)
263 {
264 DfuFirmwareFooter *ftr;
265 const guint8 *data_bin;
266 const guint8 *data_md;
267 gsize length_bin = 0;
268 gsize length_md = 0;
269 guint32 crc_new;
270 guint8 *buf;
271 g_autoptr(GBytes) metadata_table = NULL;
272
273 /* get any file metadata */
274 metadata_table = dfu_firmware_to_metadata (firmware, error);
275 if (metadata_table == NULL)
276 return NULL;
277 data_md = g_bytes_get_data (metadata_table, &length_md);
278
279 /* add the raw firmware data */
280 data_bin = g_bytes_get_data (contents, &length_bin);
281 buf = g_malloc0 (length_bin + length_md + 0x10);
282 memcpy (buf + 0, data_bin, length_bin);
283
284 /* add the metadata table */
285 memcpy (buf + length_bin, data_md, length_md);
286
287 /* set up LE footer */
288 ftr = (DfuFirmwareFooter *) (buf + length_bin + length_md);
289 ftr->release = GUINT16_TO_LE (dfu_firmware_get_release (firmware));
290 ftr->pid = GUINT16_TO_LE (dfu_firmware_get_pid (firmware));
291 ftr->vid = GUINT16_TO_LE (dfu_firmware_get_vid (firmware));
292 ftr->ver = GUINT16_TO_LE (dfu_convert_version (dfu_firmware_get_format (firmware)));
293 ftr->len = (guint8) (sizeof (DfuFirmwareFooter) + length_md);
294 memcpy(ftr->sig, "UFD", 3);
295 crc_new = dfu_firmware_generate_crc32 (buf, length_bin + length_md + 12);
296 ftr->crc = GUINT32_TO_LE (crc_new);
297
298 /* return all data */
299 return g_bytes_new_take (buf, length_bin + length_md + 0x10);
300 }
301
302 /**
303 * dfu_firmware_to_dfu: (skip)
304 * @firmware: a #DfuFirmware
305 * @error: a #GError, or %NULL
306 *
307 * Packs dfu firmware
308 *
309 * Returns: (transfer full): the packed data
310 **/
311 GBytes *
312 dfu_firmware_to_dfu (DfuFirmware *firmware, GError **error)
313 {
314 /* plain DFU */
315 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFU) {
316 GBytes *contents;
317 DfuElement *element;
318 DfuImage *image;
319 image = dfu_firmware_get_image_default (firmware);
320 g_assert (image != NULL);
321 element = dfu_image_get_element (image, 0);
322 if (element == NULL) {
323 g_set_error (error,
324 DFU_ERROR,
325 DFU_ERROR_NOT_FOUND,
326 "no firmware element data to write");
327 return NULL;
328 }
329 contents = dfu_element_get_contents (element);
330 return dfu_firmware_add_footer (firmware, contents, error);
331 }
332
333 /* DfuSe */
334 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) {
335 g_autoptr(GBytes) contents = NULL;
336 contents = dfu_firmware_to_dfuse (firmware, error);
337 if (contents == NULL)
338 return NULL;
339 return dfu_firmware_add_footer (firmware, contents, error);
340 }
341
342 g_assert_not_reached ();
343 return NULL;
344 }
+0
-42
libdfu/dfu-format-dfu.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_DFU_H
22 #define __DFU_FORMAT_DFU_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_dfu (GBytes *bytes);
32 GBytes *dfu_firmware_to_dfu (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_dfu (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_DFU_H */
+0
-402
libdfu/dfu-format-dfuse.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-dfuse.h"
27 #include "dfu-image.h"
28 #include "dfu-error.h"
29
30 /* DfuSe element header */
31 typedef struct __attribute__((packed)) {
32 guint32 address;
33 guint32 size;
34 } DfuSeElementPrefix;
35
36 /**
37 * dfu_element_from_dfuse: (skip)
38 * @data: data buffer
39 * @length: length of @data we can access
40 * @consumed: (out): the number of bytes we consued
41 * @error: a #GError, or %NULL
42 *
43 * Unpacks an element from DfuSe data.
44 *
45 * Returns: a #DfuElement, or %NULL for error
46 **/
47 static DfuElement *
48 dfu_element_from_dfuse (const guint8 *data,
49 guint32 length,
50 guint32 *consumed,
51 GError **error)
52 {
53 DfuElement *element = NULL;
54 DfuSeElementPrefix *el = (DfuSeElementPrefix *) data;
55 guint32 size;
56 g_autoptr(GBytes) contents = NULL;
57
58 g_assert_cmpint(sizeof(DfuSeElementPrefix), ==, 8);
59
60 /* check input buffer size */
61 if (length < sizeof(DfuSeElementPrefix)) {
62 g_set_error (error,
63 DFU_ERROR,
64 DFU_ERROR_INTERNAL,
65 "invalid element data size %u",
66 (guint32) length);
67 return NULL;
68 }
69
70 /* check size */
71 size = GUINT32_FROM_LE (el->size);
72 if (size + sizeof(DfuSeElementPrefix) > length) {
73 g_set_error (error,
74 DFU_ERROR,
75 DFU_ERROR_INTERNAL,
76 "invalid element size %u, only %u bytes left",
77 size,
78 (guint32) (length - sizeof(DfuSeElementPrefix)));
79 return NULL;
80 }
81
82 /* create new element */
83 element = dfu_element_new ();
84 dfu_element_set_address (element, GUINT32_FROM_LE (el->address));
85 contents = g_bytes_new (data + sizeof(DfuSeElementPrefix), size);
86 dfu_element_set_contents (element, contents);
87
88 /* return size */
89 if (consumed != NULL)
90 *consumed = (guint32) sizeof(DfuSeElementPrefix) + size;
91
92 return element;
93 }
94
95 /**
96 * dfu_element_to_dfuse: (skip)
97 * @element: a #DfuElement
98 *
99 * Packs a DfuSe element.
100 *
101 * Returns: (transfer full): the packed data
102 **/
103 static GBytes *
104 dfu_element_to_dfuse (DfuElement *element)
105 {
106 DfuSeElementPrefix *el;
107 const guint8 *data;
108 gsize length;
109 guint8 *buf;
110
111 data = g_bytes_get_data (dfu_element_get_contents (element), &length);
112 buf = g_malloc0 (length + sizeof (DfuSeElementPrefix));
113 el = (DfuSeElementPrefix *) buf;
114 el->address = GUINT32_TO_LE (dfu_element_get_address (element));
115 el->size = GUINT32_TO_LE (length);
116
117 memcpy (buf + sizeof (DfuSeElementPrefix), data, length);
118 return g_bytes_new_take (buf, length + sizeof (DfuSeElementPrefix));
119 }
120
121 /* DfuSe image header */
122 typedef struct __attribute__((packed)) {
123 guint8 sig[6];
124 guint8 alt_setting;
125 guint32 target_named;
126 gchar target_name[255];
127 guint32 target_size;
128 guint32 elements;
129 } DfuSeImagePrefix;
130
131 /**
132 * dfu_image_from_dfuse: (skip)
133 * @data: data buffer
134 * @length: length of @data we can access
135 * @consumed: (out): the number of bytes we consued
136 * @error: a #GError, or %NULL
137 *
138 * Unpacks an image from DfuSe data.
139 *
140 * Returns: a #DfuImage, or %NULL for error
141 **/
142 static DfuImage *
143 dfu_image_from_dfuse (const guint8 *data,
144 guint32 length,
145 guint32 *consumed,
146 GError **error)
147 {
148 DfuSeImagePrefix *im;
149 guint32 elements;
150 guint32 offset = sizeof(DfuSeImagePrefix);
151 guint j;
152 g_autoptr(DfuImage) image = NULL;
153
154 g_assert_cmpint(sizeof(DfuSeImagePrefix), ==, 274);
155
156 /* check input buffer size */
157 if (length < sizeof(DfuSeImagePrefix)) {
158 g_set_error (error,
159 DFU_ERROR,
160 DFU_ERROR_INTERNAL,
161 "invalid image data size %u",
162 (guint32) length);
163 return NULL;
164 }
165
166 /* verify image signature */
167 im = (DfuSeImagePrefix *) data;
168 if (memcmp (im->sig, "Target", 6) != 0) {
169 g_set_error_literal (error,
170 DFU_ERROR,
171 DFU_ERROR_INVALID_FILE,
172 "invalid DfuSe target signature");
173 return NULL;
174 }
175
176 /* create new image */
177 image = dfu_image_new ();
178 dfu_image_set_alt_setting (image, im->alt_setting);
179 if (GUINT32_FROM_LE (im->target_named) == 0x01)
180 dfu_image_set_name (image, im->target_name);
181
182 /* parse elements */
183 length -= offset;
184 elements = GUINT32_FROM_LE (im->elements);
185 for (j = 0; j < elements; j++) {
186 guint32 consumed_local;
187 g_autoptr(DfuElement) element = NULL;
188 element = dfu_element_from_dfuse (data + offset, length,
189 &consumed_local, error);
190 if (element == NULL)
191 return NULL;
192 dfu_image_add_element (image, element);
193 offset += consumed_local;
194 length -= consumed_local;
195 }
196
197 /* return size */
198 if (consumed != NULL)
199 *consumed = offset;
200
201 return g_object_ref (image);
202 }
203
204 /**
205 * dfu_image_to_dfuse: (skip)
206 * @image: a #DfuImage
207 *
208 * Packs a DfuSe image
209 *
210 * Returns: (transfer full): the packed data
211 **/
212 static GBytes *
213 dfu_image_to_dfuse (DfuImage *image)
214 {
215 DfuElement *element;
216 DfuSeImagePrefix *im;
217 GBytes *bytes;
218 GPtrArray *elements;
219 guint32 length_total = 0;
220 guint32 offset = sizeof (DfuSeImagePrefix);
221 guint8 *buf;
222 guint i;
223 g_autoptr(GPtrArray) element_array = NULL;
224
225 /* get total size */
226 element_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
227 elements = dfu_image_get_elements (image);
228 for (i = 0; i < elements->len; i++) {
229 element = g_ptr_array_index (elements, i);
230 bytes = dfu_element_to_dfuse (element);
231 g_ptr_array_add (element_array, bytes);
232 length_total += (guint32) g_bytes_get_size (bytes);
233 }
234
235 /* add prefix */
236 buf = g_malloc0 (length_total + sizeof (DfuSeImagePrefix));
237 im = (DfuSeImagePrefix *) buf;
238 memcpy (im->sig, "Target", 6);
239 im->alt_setting = dfu_image_get_alt_setting (image);
240 if (dfu_image_get_name (image) != NULL) {
241 im->target_named = GUINT32_TO_LE (0x01);
242 memcpy (im->target_name, dfu_image_get_name (image), 255);
243 }
244 im->target_size = GUINT32_TO_LE (length_total);
245 im->elements = GUINT32_TO_LE (elements->len);
246
247 /* copy data */
248 for (i = 0; i < element_array->len; i++) {
249 const guint8 *data;
250 gsize length;
251 bytes = g_ptr_array_index (element_array, i);
252 data = g_bytes_get_data (bytes, &length);
253 memcpy (buf + offset, data, length);
254 offset += (guint32) length;
255 }
256 return g_bytes_new_take (buf, length_total + sizeof (DfuSeImagePrefix));
257 }
258
259 /* DfuSe header */
260 typedef struct __attribute__((packed)) {
261 guint8 sig[5];
262 guint8 ver;
263 guint32 image_size;
264 guint8 targets;
265 } DfuSePrefix;
266
267 /**
268 * dfu_firmware_to_dfuse: (skip)
269 * @firmware: a #DfuFirmware
270 * @error: a #GError, or %NULL
271 *
272 * Packs a DfuSe firmware
273 *
274 * Returns: (transfer full): the packed data
275 **/
276 GBytes *
277 dfu_firmware_to_dfuse (DfuFirmware *firmware, GError **error)
278 {
279 DfuSePrefix *prefix;
280 GPtrArray *images;
281 guint i;
282 guint32 image_size_total = 0;
283 guint32 offset = sizeof (DfuSePrefix);
284 g_autofree guint8 *buf = NULL;
285 g_autoptr(GPtrArray) dfuse_images = NULL;
286
287 /* get all the image data */
288 dfuse_images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
289 images = dfu_firmware_get_images (firmware);
290 for (i = 0; i < images->len; i++) {
291 DfuImage *im = g_ptr_array_index (images, i);
292 GBytes *contents;
293 contents = dfu_image_to_dfuse (im);
294 image_size_total += (guint32) g_bytes_get_size (contents);
295 g_ptr_array_add (dfuse_images, contents);
296 }
297 g_debug ("image_size_total: %" G_GUINT32_FORMAT, image_size_total);
298
299 buf = g_malloc0 (sizeof (DfuSePrefix) + image_size_total);
300
301 /* DfuSe header */
302 prefix = (DfuSePrefix *) buf;
303 memcpy (prefix->sig, "DfuSe", 5);
304 prefix->ver = 0x01;
305 prefix->image_size = GUINT32_TO_LE (offset + image_size_total);
306 if (images->len > G_MAXUINT8) {
307 g_set_error (error,
308 DFU_ERROR,
309 DFU_ERROR_INTERNAL,
310 "too many (%u) images to write DfuSe file",
311 images->len);
312 return NULL;
313 }
314 prefix->targets = (guint8) images->len;
315
316 /* copy images */
317 for (i = 0; i < dfuse_images->len; i++) {
318 GBytes *contents = g_ptr_array_index (dfuse_images, i);
319 gsize length;
320 const guint8 *data;
321 data = g_bytes_get_data (contents, &length);
322 memcpy (buf + offset, data, length);
323 offset += (guint32) length;
324 }
325
326 /* return blob */
327 return g_bytes_new (buf, sizeof (DfuSePrefix) + image_size_total);
328 }
329
330 /**
331 * dfu_firmware_from_dfuse: (skip)
332 * @firmware: a #DfuFirmware
333 * @bytes: data to parse
334 * @flags: some #DfuFirmwareParseFlags
335 * @error: a #GError, or %NULL
336 *
337 * Unpacks into a firmware object from DfuSe data.
338 *
339 * Returns: %TRUE for success
340 **/
341 gboolean
342 dfu_firmware_from_dfuse (DfuFirmware *firmware,
343 GBytes *bytes,
344 DfuFirmwareParseFlags flags,
345 GError **error)
346 {
347 DfuSePrefix *prefix;
348 gsize len;
349 guint32 offset = sizeof(DfuSePrefix);
350 guint8 *data;
351 guint i;
352
353 /* check the prefix (BE) */
354 data = (guint8 *) g_bytes_get_data (bytes, &len);
355 prefix = (DfuSePrefix *) data;
356 if (memcmp (prefix->sig, "DfuSe", 5) != 0) {
357 g_set_error_literal (error,
358 DFU_ERROR,
359 DFU_ERROR_INTERNAL,
360 "invalid DfuSe prefix");
361 return FALSE;
362 }
363
364 /* check the version */
365 if (prefix->ver != 0x01) {
366 g_set_error (error,
367 DFU_ERROR,
368 DFU_ERROR_INTERNAL,
369 "invalid DfuSe version, got %02x",
370 prefix->ver);
371 return FALSE;
372 }
373
374 /* check image size */
375 if (GUINT32_FROM_LE (prefix->image_size) != len) {
376 g_set_error (error,
377 DFU_ERROR,
378 DFU_ERROR_INTERNAL,
379 "invalid DfuSe image size, "
380 "got %" G_GUINT32_FORMAT ", "
381 "expected %" G_GSIZE_FORMAT,
382 GUINT32_FROM_LE (prefix->image_size),
383 len);
384 return FALSE;
385 }
386
387 /* parse the image targets */
388 len -= sizeof(DfuSePrefix);
389 for (i = 0; i < prefix->targets; i++) {
390 guint consumed;
391 g_autoptr(DfuImage) image = NULL;
392 image = dfu_image_from_dfuse (data + offset, (guint32) len,
393 &consumed, error);
394 if (image == NULL)
395 return FALSE;
396 dfu_firmware_add_image (firmware, image);
397 offset += consumed;
398 len -= consumed;
399 }
400 return TRUE;
401 }
+0
-42
libdfu/dfu-format-dfuse.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_DFUSE_H
22 #define __DFU_FORMAT_DFUSE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_dfuse (GBytes *bytes);
32 GBytes *dfu_firmware_to_dfuse (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_dfuse (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_DFUSE_H */
+0
-468
libdfu/dfu-format-elf.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <fcntl.h>
24 #include <gio/gunixinputstream.h>
25
26 #ifdef HAVE_LIBELF
27 #include <gelf.h>
28 #include <libelf.h>
29 #include <linux/memfd.h>
30 #endif
31
32 #include <string.h>
33 #include <sys/syscall.h>
34
35 #include "dfu-firmware-private.h"
36 #include "dfu-format-elf.h"
37 #include "dfu-error.h"
38
39 /**
40 * dfu_firmware_detect_elf: (skip)
41 * @bytes: data to parse
42 *
43 * Attempts to sniff the data and work out the firmware format
44 *
45 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_ELF
46 **/
47 DfuFirmwareFormat
48 dfu_firmware_detect_elf (GBytes *bytes)
49 {
50 guint8 *data;
51 gsize len;
52
53 /* check data size */
54 data = (guint8 *) g_bytes_get_data (bytes, &len);
55 if (len < 16)
56 return DFU_FIRMWARE_FORMAT_UNKNOWN;
57
58 /* sniff the signature bytes */
59 if (memcmp (data + 1, "ELF", 3) != 0)
60 return DFU_FIRMWARE_FORMAT_UNKNOWN;
61
62 /* success */
63 return DFU_FIRMWARE_FORMAT_ELF;
64 }
65
66 #ifdef HAVE_LIBELF
67 static DfuElement *
68 _get_element_from_section_name (Elf *e, const gchar *desired_name)
69 {
70 DfuElement *element = NULL;
71 Elf_Scn *scn = NULL;
72 GElf_Shdr shdr;
73 const gchar *name;
74 size_t shstrndx;
75
76 if (elf_getshdrstrndx (e, &shstrndx) != 0)
77 return NULL;
78 while ((scn = elf_nextscn (e, scn)) != NULL ) {
79 if (gelf_getshdr (scn, &shdr ) != & shdr) {
80 continue;
81 }
82
83 /* not program data */
84 if (shdr.sh_type != SHT_PROGBITS)
85 continue;
86
87 /* not the same section name */
88 if ((name = elf_strptr (e, shstrndx, shdr.sh_name)) == NULL) {
89 continue;
90 }
91 if (g_strcmp0 (name, desired_name) == 0) {
92 Elf_Data *data = elf_getdata (scn, NULL);
93 if (data != NULL && data->d_buf != NULL) {
94 g_autoptr(GBytes) bytes = NULL;
95 bytes = g_bytes_new (data->d_buf, data->d_size);
96 element = dfu_element_new ();
97 dfu_element_set_contents (element, bytes);
98 dfu_element_set_address (element, shdr.sh_addr);
99 }
100 break;
101 }
102 }
103 return element;
104 }
105
106 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Elf, elf_end);
107
108 static void
109 dfu_format_elf_symbols_from_symtab (DfuFirmware *firmware, Elf *e)
110 {
111 Elf_Scn *scn = NULL;
112 gsize shstrndx;
113
114 if (elf_getshdrstrndx (e, &shstrndx) != 0)
115 return;
116 while ((scn = elf_nextscn (e, scn)) != NULL ) {
117 Elf_Data *data;
118 GElf_Shdr shdr;
119 const gchar *name;
120 gssize ns;
121 if (gelf_getshdr (scn, &shdr) != &shdr)
122 continue;
123
124 /* not program data */
125 if (shdr.sh_type != SHT_SYMTAB)
126 continue;
127
128 /* get symbols */
129 data = elf_getdata (scn, NULL);
130 ns = shdr.sh_size / shdr.sh_entsize;
131 for (gint i = 0; i < ns; i++) {
132 GElf_Sym sym;
133 gelf_getsym (data, i, &sym);
134 if (sym.st_value == 0)
135 continue;
136 name = elf_strptr (e, shdr.sh_link, sym.st_name);
137 if (name == NULL)
138 continue;
139 dfu_firmware_add_symbol (firmware, name, sym.st_value);
140 }
141 }
142 }
143 #endif
144
145 /**
146 * dfu_firmware_from_elf: (skip)
147 * @firmware: a #DfuFirmware
148 * @bytes: data to parse
149 * @flags: some #DfuFirmwareParseFlags
150 * @error: a #GError, or %NULL
151 *
152 * Unpacks into a firmware object from ELF data.
153 *
154 * Returns: %TRUE for success
155 **/
156 gboolean
157 dfu_firmware_from_elf (DfuFirmware *firmware,
158 GBytes *bytes,
159 DfuFirmwareParseFlags flags,
160 GError **error)
161 {
162 #ifdef HAVE_LIBELF
163 guint i;
164 guint sections_cnt = 0;
165 g_autoptr(Elf) e = NULL;
166 const gchar *section_names[] = {
167 ".interrupt",
168 ".text",
169 NULL };
170
171 /* load library */
172 if (elf_version (EV_CURRENT) == EV_NONE) {
173 g_set_error (error,
174 DFU_ERROR,
175 DFU_ERROR_INTERNAL,
176 "ELF library init failed: %s",
177 elf_errmsg (-1));
178 return FALSE;
179 }
180
181 /* parse data */
182 e = elf_memory ((gchar *) g_bytes_get_data (bytes, NULL),
183 g_bytes_get_size (bytes));
184 if (e == NULL) {
185 g_set_error (error,
186 DFU_ERROR,
187 DFU_ERROR_INTERNAL,
188 "failed to load data as ELF: %s",
189 elf_errmsg (-1));
190 return FALSE;
191 }
192 if (elf_kind (e) != ELF_K_ELF) {
193 g_set_error (error,
194 DFU_ERROR,
195 DFU_ERROR_INTERNAL,
196 "not a supported ELF format: %s",
197 elf_errmsg (-1));
198 return FALSE;
199 }
200 g_debug ("loading %ib ELF object" ,
201 gelf_getclass (e) == ELFCLASS32 ? 32 : 64);
202
203 /* add interesting sections as the image */
204 for (i = 0; section_names[i] != NULL; i++) {
205 g_autoptr(DfuElement) element = NULL;
206 g_autoptr(DfuImage) image = NULL;
207 element = _get_element_from_section_name (e, section_names[i]);
208 if (element == NULL)
209 continue;
210 image = dfu_image_new ();
211 dfu_image_add_element (image, element);
212 dfu_image_set_name (image, section_names[i]);
213 dfu_firmware_add_image (firmware, image);
214 sections_cnt++;
215 }
216
217 /* load symbol table */
218 dfu_format_elf_symbols_from_symtab (firmware, e);
219
220 /* nothing found */
221 if (sections_cnt == 0) {
222 g_set_error_literal (error,
223 DFU_ERROR,
224 DFU_ERROR_INTERNAL,
225 "no firmware found in ELF file");
226 return FALSE;
227 }
228
229 /* success */
230 return TRUE;
231 #else
232 g_set_error_literal (error,
233 DFU_ERROR,
234 DFU_ERROR_INTERNAL,
235 "compiled without libelf support");
236 return FALSE;
237 #endif
238 }
239
240 #ifdef HAVE_LIBELF
241 static int
242 _memfd_create (const char *name, unsigned int flags)
243 {
244 #if defined (__NR_memfd_create)
245 return syscall (__NR_memfd_create, name, flags);
246 #else
247 return -1;
248 #endif
249 }
250
251 static gboolean
252 dfu_format_elf_pack_element (Elf *e, DfuElement *element, GError **error)
253 {
254 Elf32_Shdr *shdr;
255 Elf_Data *data;
256 Elf_Scn *scn;
257 GBytes *bytes = dfu_element_get_contents (element);
258
259 /* create a section descriptor for the firmware */
260 scn = elf_newscn (e);
261 if (scn == NULL) {
262 g_set_error (error,
263 DFU_ERROR,
264 DFU_ERROR_INTERNAL,
265 "failed to create section descriptor: %s",
266 elf_errmsg (-1));
267 return FALSE;
268 }
269 data = elf_newdata (scn);
270 data->d_align = 1;
271 data->d_off = 0;
272 data->d_buf = (gpointer) g_bytes_get_data (bytes, NULL);
273 data->d_type = ELF_T_BYTE;
274 data->d_size = g_bytes_get_size (bytes);
275 data->d_version = EV_CURRENT;
276 shdr = elf32_getshdr (scn);
277 if (shdr == NULL) {
278 g_set_error (error,
279 DFU_ERROR,
280 DFU_ERROR_INTERNAL,
281 "failed to create XXX: %s",
282 elf_errmsg (-1));
283 return FALSE;
284 }
285 shdr->sh_name = 1;
286 shdr->sh_type = SHT_PROGBITS;
287 shdr->sh_flags = SHF_ALLOC;
288 shdr->sh_entsize = 0;
289 return TRUE;
290 }
291
292 static gboolean
293 dfu_format_elf_pack_image (Elf *e, DfuImage *image, GError **error)
294 {
295 DfuElement *element;
296
297 /* only works for one element */
298 element = dfu_image_get_element_default (image);
299 if (element == NULL) {
300 g_set_error_literal (error,
301 DFU_ERROR,
302 DFU_ERROR_INTERNAL,
303 "no element to write");
304 return FALSE;
305 }
306 return dfu_format_elf_pack_element (e, element, error);
307 }
308 #endif
309
310 /**
311 * dfu_firmware_to_elf: (skip)
312 * @firmware: a #DfuFirmware
313 * @error: a #GError, or %NULL
314 *
315 * Packs elf firmware
316 *
317 * Returns: (transfer full): the packed data
318 **/
319 GBytes *
320 dfu_firmware_to_elf (DfuFirmware *firmware, GError **error)
321 {
322 #ifdef HAVE_LIBELF
323 DfuImage *image;
324 Elf32_Ehdr *ehdr;
325 Elf32_Shdr *shdr;
326 Elf_Data *data;
327 Elf_Scn *scn;
328 gint fd;
329 goffset fsize;
330 g_autoptr(Elf) e = NULL;
331 g_autoptr(GInputStream) stream = NULL;
332 gchar string_table2[] =
333 "\0"
334 ".text\0" // FIXME: use the name in the DfuImage?
335 ".shstrtab";
336
337 /* only works for one image */
338 image = dfu_firmware_get_image_default (firmware);
339 if (image == NULL) {
340 g_set_error_literal (error,
341 DFU_ERROR,
342 DFU_ERROR_INTERNAL,
343 "no image to write");
344 return NULL;
345 }
346
347 /* load library */
348 if (elf_version (EV_CURRENT) == EV_NONE) {
349 g_set_error (error,
350 DFU_ERROR,
351 DFU_ERROR_INTERNAL,
352 "ELF library init failed: %s",
353 elf_errmsg (-1));
354 return NULL;
355 }
356
357 /* create from buffer */
358 fd = _memfd_create ("elf", MFD_CLOEXEC);
359 if (fd < 0) {
360 g_set_error_literal (error,
361 DFU_ERROR,
362 DFU_ERROR_INTERNAL,
363 "failed to open memfd");
364 return NULL;
365 }
366 stream = g_unix_input_stream_new (fd, TRUE);
367 e = elf_begin (fd, ELF_C_WRITE, NULL);
368 if (e == NULL) {
369 g_set_error (error,
370 DFU_ERROR,
371 DFU_ERROR_INTERNAL,
372 "failed to create ELF: %s",
373 elf_errmsg (-1));
374 return NULL;
375 }
376
377 /* add executable header */
378 ehdr = elf32_newehdr (e);
379 if (ehdr == NULL) {
380 g_set_error (error,
381 DFU_ERROR,
382 DFU_ERROR_INTERNAL,
383 "failed to create executable header: %s",
384 elf_errmsg (-1));
385 return NULL;
386 }
387 ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
388 ehdr->e_machine = EM_NONE;
389 ehdr->e_type = ET_NONE;
390
391 /* pack the image */
392 if (!dfu_format_elf_pack_image (e, image, error))
393 return NULL;
394
395 /* allocate section for holding the string table */
396 scn = elf_newscn (e);
397 if (scn == NULL) {
398 g_set_error (error,
399 DFU_ERROR,
400 DFU_ERROR_INTERNAL,
401 "failed to create section descriptor: %s",
402 elf_errmsg (-1));
403 return NULL;
404 }
405 data = elf_newdata (scn);
406 data->d_align = 1;
407 data->d_off = 0;
408 data->d_buf = string_table2;
409 data->d_type = ELF_T_BYTE;
410 data->d_size = sizeof (string_table2);
411 data->d_version = EV_CURRENT;
412 shdr = elf32_getshdr (scn);
413 if (shdr == NULL) {
414 g_set_error (error,
415 DFU_ERROR,
416 DFU_ERROR_INTERNAL,
417 "failed to create XXX: %s",
418 elf_errmsg (-1));
419 return NULL;
420 }
421 shdr->sh_name = 7; /* offset to table name */
422 shdr->sh_type = SHT_STRTAB;
423 shdr->sh_flags = SHF_STRINGS | SHF_ALLOC;
424 shdr->sh_entsize = 0;
425
426 /* set string table index field */
427 ehdr->e_shstrndx = elf_ndxscn (scn);
428
429 /* compute the layout of the object */
430 if (elf_update (e, ELF_C_NULL) < 0) {
431 g_set_error (error,
432 DFU_ERROR,
433 DFU_ERROR_INTERNAL,
434 "failed to compute layout: %s",
435 elf_errmsg (-1));
436 return NULL;
437 }
438
439 /* write out the actual data */
440 elf_flagphdr (e, ELF_C_SET, ELF_F_DIRTY );
441 if (elf_update (e, ELF_C_WRITE ) < 0) {
442 g_set_error (error,
443 DFU_ERROR,
444 DFU_ERROR_INTERNAL,
445 "failed to write to fd: %s",
446 elf_errmsg (-1));
447 return NULL;
448 }
449
450 /* read out the blob of memory in one chunk */
451 fsize = lseek(fd, 0, SEEK_END);
452 if (lseek (fd, 0, SEEK_SET) < 0) {
453 g_set_error (error,
454 DFU_ERROR,
455 DFU_ERROR_INTERNAL,
456 "failed to seek to start");
457 return NULL;
458 }
459 return g_input_stream_read_bytes (stream, fsize, NULL, error);
460 #else
461 g_set_error_literal (error,
462 DFU_ERROR,
463 DFU_ERROR_INTERNAL,
464 "compiled without libelf support");
465 return NULL;
466 #endif
467 }
+0
-42
libdfu/dfu-format-elf.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_ELF_H
22 #define __DFU_FORMAT_ELF_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_elf (GBytes *bytes);
32 GBytes *dfu_firmware_to_elf (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_elf (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_ELF_H */
+0
-421
libdfu/dfu-format-ihex.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-error.h"
27 #include "dfu-firmware-private.h"
28 #include "dfu-format-ihex.h"
29 #include "dfu-image.h"
30
31 /**
32 * dfu_firmware_detect_ihex: (skip)
33 * @bytes: data to parse
34 *
35 * Attempts to sniff the data and work out the firmware format
36 *
37 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW
38 **/
39 DfuFirmwareFormat
40 dfu_firmware_detect_ihex (GBytes *bytes)
41 {
42 guint8 *data;
43 gsize len;
44 data = (guint8 *) g_bytes_get_data (bytes, &len);
45 if (len < 12)
46 return DFU_FIRMWARE_FORMAT_UNKNOWN;
47 if (data[0] != ':')
48 return DFU_FIRMWARE_FORMAT_UNKNOWN;
49 return DFU_FIRMWARE_FORMAT_INTEL_HEX;
50 }
51
52 static guint8
53 dfu_firmware_ihex_parse_uint8 (const gchar *data, guint pos)
54 {
55 gchar buffer[3];
56 memcpy (buffer, data + pos, 2);
57 buffer[2] = '\0';
58 return (guint8) g_ascii_strtoull (buffer, NULL, 16);
59 }
60
61 static guint16
62 dfu_firmware_ihex_parse_uint16 (const gchar *data, guint pos)
63 {
64 gchar buffer[5];
65 memcpy (buffer, data + pos, 4);
66 buffer[4] = '\0';
67 return (guint16) g_ascii_strtoull (buffer, NULL, 16);
68 }
69
70 #define DFU_INHX32_RECORD_TYPE_DATA 0x00
71 #define DFU_INHX32_RECORD_TYPE_EOF 0x01
72 #define DFU_INHX32_RECORD_TYPE_EXTENDED 0x04
73 #define DFU_INHX32_RECORD_TYPE_SYMTAB 0xfe
74 #define DFU_INHX32_RECORD_TYPE_SIGNATURE 0xfd
75
76 static gboolean
77 dfu_firmware_ihex_symbol_name_valid (const GString *symbol_name)
78 {
79 if (symbol_name->len == 2 && symbol_name->str[0] == '$')
80 return FALSE;
81 return TRUE;
82 }
83
84 /**
85 * dfu_firmware_from_ihex: (skip)
86 * @firmware: a #DfuFirmware
87 * @bytes: data to parse
88 * @flags: some #DfuFirmwareParseFlags
89 * @error: a #GError, or %NULL
90 *
91 * Unpacks into a firmware object from raw data.
92 *
93 * Returns: %TRUE for success
94 **/
95 gboolean
96 dfu_firmware_from_ihex (DfuFirmware *firmware,
97 GBytes *bytes,
98 DfuFirmwareParseFlags flags,
99 GError **error)
100 {
101 const gchar *in_buffer;
102 gboolean got_eof = FALSE;
103 gsize len_in;
104 guint16 addr_high = 0;
105 guint16 addr_low = 0;
106 guint32 addr32 = 0;
107 guint32 addr32_last = 0;
108 guint32 element_address = 0;
109 guint8 checksum;
110 guint8 data_tmp;
111 guint8 len_tmp;
112 guint8 type;
113 guint end;
114 guint i;
115 guint j;
116 guint offset = 0;
117 g_autoptr(DfuElement) element = NULL;
118 g_autoptr(DfuImage) image = NULL;
119 g_autoptr(GBytes) contents = NULL;
120 g_autoptr(GString) string = NULL;
121 g_autoptr(GString) signature = g_string_new (NULL);
122
123 g_return_val_if_fail (bytes != NULL, FALSE);
124
125 /* create element */
126 image = dfu_image_new ();
127 dfu_image_set_name (image, "ihex");
128 element = dfu_element_new ();
129
130 /* parse records */
131 in_buffer = g_bytes_get_data (bytes, &len_in);
132 string = g_string_new ("");
133 while (offset < len_in) {
134
135 /* check starting token */
136 if (in_buffer[offset] != ':') {
137 g_set_error (error,
138 DFU_ERROR,
139 DFU_ERROR_INVALID_FILE,
140 "invalid starting token, got %c at %x",
141 in_buffer[offset], offset);
142 return FALSE;
143 }
144
145 /* check there's enough data for the smallest possible record */
146 if (offset + 12 > (guint) len_in) {
147 g_set_error (error,
148 DFU_ERROR,
149 DFU_ERROR_INVALID_FILE,
150 "record incomplete at %u, length %u",
151 offset, (guint) len_in);
152 return FALSE;
153 }
154
155 /* length, 16-bit address, type */
156 len_tmp = dfu_firmware_ihex_parse_uint8 (in_buffer, offset+1);
157 addr_low = dfu_firmware_ihex_parse_uint16 (in_buffer, offset+3);
158 type = dfu_firmware_ihex_parse_uint8 (in_buffer, offset+7);
159
160 /* position of checksum */
161 end = offset + 9 + len_tmp * 2;
162 if (end > (guint) len_in) {
163 g_set_error (error,
164 DFU_ERROR,
165 DFU_ERROR_INVALID_FILE,
166 "checksum > file length: %u",
167 end);
168 return FALSE;
169 }
170
171 /* verify checksum */
172 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
173 checksum = 0;
174 for (i = offset + 1; i < end + 2; i += 2) {
175 data_tmp = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
176 checksum += data_tmp;
177 }
178 if (checksum != 0) {
179 g_set_error_literal (error,
180 DFU_ERROR,
181 DFU_ERROR_INVALID_FILE,
182 "invalid record checksum");
183 return FALSE;
184 }
185 }
186
187 /* process different record types */
188 switch (type) {
189 case DFU_INHX32_RECORD_TYPE_DATA:
190 /* if not contiguous with previous record */
191 if ((addr_high + addr_low) != addr32) {
192 if (addr32 == 0x0) {
193 g_debug ("base address %08x", addr_low);
194 dfu_element_set_address (element, addr_low);
195 }
196 addr32 = ((guint32) addr_high << 16) + addr_low;
197 if (element_address == 0x0)
198 element_address = addr32;
199 }
200
201 /* does not make sense */
202 if (addr32 < addr32_last) {
203 g_set_error (error,
204 DFU_ERROR,
205 DFU_ERROR_INVALID_FILE,
206 "invalid address 0x%x, last was 0x%x",
207 (guint) addr32,
208 (guint) addr32_last);
209 return FALSE;
210 }
211
212 /* parse bytes from line */
213 g_debug ("writing data 0x%08x", (guint32) addr32);
214 for (i = offset + 9; i < end; i += 2) {
215 /* any holes in the hex record */
216 guint32 len_hole = addr32 - addr32_last;
217 if (addr32_last > 0x0 && len_hole > 1) {
218 for (j = 1; j < len_hole; j++) {
219 g_debug ("filling address 0x%08x",
220 addr32_last + j);
221 /* although 0xff might be clearer,
222 * we can't write 0xffff to pic14 */
223 g_string_append_c (string, 0x00);
224 }
225 }
226 /* write into buf */
227 data_tmp = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
228 g_string_append_c (string, (gchar) data_tmp);
229 addr32_last = addr32++;
230 }
231 break;
232 case DFU_INHX32_RECORD_TYPE_EOF:
233 if (got_eof) {
234 g_set_error_literal (error,
235 DFU_ERROR,
236 DFU_ERROR_INVALID_FILE,
237 "duplicate EOF, perhaps "
238 "corrupt file");
239 return FALSE;
240 }
241 got_eof = TRUE;
242 break;
243 case DFU_INHX32_RECORD_TYPE_EXTENDED:
244 addr_high = dfu_firmware_ihex_parse_uint16 (in_buffer, offset+9);
245 addr32 = ((guint32) addr_high << 16) + addr_low;
246 break;
247 case DFU_INHX32_RECORD_TYPE_SYMTAB:
248 {
249 g_autoptr(GString) str = g_string_new ("");
250 for (i = offset + 9; i < end; i += 2) {
251 guint8 tmp_c = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
252 g_string_append_c (str, tmp_c);
253 }
254 addr32 = ((guint32) addr_high << 16) + addr_low;
255 if (addr32 != 0x0 && dfu_firmware_ihex_symbol_name_valid (str)) {
256 g_debug ("symtab 0x%08x: %s", addr32, str->str);
257 dfu_firmware_add_symbol (firmware,
258 str->str,
259 (guint64) addr32);
260 }
261 break;
262 }
263 case DFU_INHX32_RECORD_TYPE_SIGNATURE:
264 for (i = offset + 9; i < end; i += 2) {
265 guint8 tmp_c = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
266 g_string_append_c (signature, tmp_c);
267 }
268 break;
269 default:
270 /* vendors sneak in nonstandard sections past the EOF */
271 if (got_eof)
272 break;
273 g_set_error (error,
274 DFU_ERROR,
275 DFU_ERROR_INVALID_FILE,
276 "invalid ihex record type %i",
277 type);
278 return FALSE;
279 }
280
281 /* ignore any line return */
282 offset = end + 2;
283 for (; offset < len_in; offset++) {
284 if (in_buffer[offset] != '\n' &&
285 in_buffer[offset] != '\r')
286 break;
287 }
288 }
289
290 /* no EOF */
291 if (!got_eof) {
292 g_set_error_literal (error,
293 DFU_ERROR,
294 DFU_ERROR_INVALID_FILE,
295 "no EOF, perhaps truncated file");
296 return FALSE;
297 }
298
299 /* add single image */
300 contents = g_bytes_new (string->str, string->len);
301 dfu_element_set_contents (element, contents);
302 dfu_element_set_address (element, element_address);
303 dfu_image_add_element (image, element);
304 dfu_firmware_add_image (firmware, image);
305 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
306
307 /* add optional signature */
308 if (signature->len > 0) {
309 g_autoptr(DfuElement) element_sig = dfu_element_new ();
310 g_autoptr(DfuImage) image_sig = dfu_image_new ();
311 g_autoptr(GBytes) data = g_bytes_new_static (signature->str, signature->len);
312 dfu_element_set_contents (element_sig, data);
313 dfu_image_add_element (image_sig, element_sig);
314 dfu_image_set_name (image_sig, "signature");
315 dfu_firmware_add_image (firmware, image_sig);
316 }
317 return TRUE;
318 }
319
320 static void
321 dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type,
322 guint32 address, GBytes *contents)
323 {
324 const guint8 *data;
325 const guint chunk_size = 16;
326 gsize len;
327
328 /* get number of chunks */
329 data = g_bytes_get_data (contents, &len);
330 for (gsize i = 0; i < len; i += chunk_size) {
331 guint8 checksum = 0;
332
333 /* length, 16-bit address, type */
334 gsize chunk_len = MIN (len - i, 16);
335 g_string_append_printf (str, ":%02X%04X%02X",
336 (guint) chunk_len,
337 (guint) (address + i),
338 (guint) record_type);
339 for (gsize j = 0; j < chunk_len; j++)
340 g_string_append_printf (str, "%02X", data[i+j]);
341
342 /* add checksum */
343 for (gsize j = 0; j < (chunk_len * 2) + 8; j++)
344 checksum += (guint8) str->str[str->len - (j + 1)];
345 g_string_append_printf (str, "%02X\n", checksum);
346 }
347 }
348
349 static gboolean
350 dfu_firmware_to_ihex_element (DfuElement *element, GString *str,
351 guint8 record_type, GError **error)
352 {
353 GBytes *contents = dfu_element_get_contents (element);
354 dfu_firmware_to_ihex_bytes (str, record_type,
355 dfu_element_get_address (element),
356 contents);
357 return TRUE;
358 }
359
360 static gboolean
361 dfu_firmware_to_ihex_image (DfuImage *image, GString *str, GError **error)
362 {
363 GPtrArray *elements;
364 guint8 record_type = DFU_INHX32_RECORD_TYPE_DATA;
365
366 if (g_strcmp0 (dfu_image_get_name (image), "signature") == 0)
367 record_type = DFU_INHX32_RECORD_TYPE_SIGNATURE;
368 elements = dfu_image_get_elements (image);
369 for (guint i = 0; i < elements->len; i++) {
370 DfuElement *element = g_ptr_array_index (elements, i);
371 if (!dfu_firmware_to_ihex_element (element,
372 str,
373 record_type,
374 error))
375 return FALSE;
376 }
377 return TRUE;
378 }
379
380 /**
381 * dfu_firmware_to_ihex: (skip)
382 * @firmware: a #DfuFirmware
383 * @error: a #GError, or %NULL
384 *
385 * Packs a IHEX firmware
386 *
387 * Returns: (transfer full): the packed data
388 **/
389 GBytes *
390 dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error)
391 {
392 GPtrArray *images;
393 g_autoptr(GPtrArray) symbols = NULL;
394 g_autoptr(GString) str = NULL;
395
396 /* write all the element data */
397 str = g_string_new ("");
398 images = dfu_firmware_get_images (firmware);
399 for (guint i = 0; i < images->len; i++) {
400 DfuImage *image = g_ptr_array_index (images, i);
401 if (!dfu_firmware_to_ihex_image (image, str, error))
402 return NULL;
403 }
404
405 /* add EOF */
406 g_string_append_printf (str, ":000000%02XFF\n",
407 (guint) DFU_INHX32_RECORD_TYPE_EOF);
408
409 /* add any symbol table */
410 symbols = dfu_firmware_get_symbols (firmware);
411 for (guint i = 0; i < symbols->len; i++) {
412 const gchar *name = g_ptr_array_index (symbols, i);
413 guint32 addr = dfu_firmware_lookup_symbol (firmware, name);
414 g_autoptr(GBytes) contents = g_bytes_new_static (name, strlen (name));
415 dfu_firmware_to_ihex_bytes (str, DFU_INHX32_RECORD_TYPE_SYMTAB,
416 addr, contents);
417 }
418
419 return g_bytes_new (str->str, str->len);
420 }
+0
-42
libdfu/dfu-format-ihex.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_IHEX_H
22 #define __DFU_FORMAT_IHEX_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_ihex (GBytes *bytes);
32 GBytes *dfu_firmware_to_ihex (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_ihex (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_IHEX_H */
+0
-218
libdfu/dfu-format-metadata.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-metadata.h"
27 #include "dfu-image.h"
28 #include "dfu-error.h"
29
30 /**
31 * dfu_firmware_from_metadata: (skip)
32 * @firmware: a #DfuFirmware
33 * @bytes: data to parse
34 * @flags: some #DfuFirmwareParseFlags
35 * @error: a #GError, or %NULL
36 *
37 * Unpacks into a firmware object from metadata data.
38 *
39 * The representation in memory is as follows:
40 *
41 * uint16 signature='MD'
42 * uint8 number_of_keys
43 * uint8 number_of_keys
44 * uint8 key(n)_length
45 * ... key(n) (no NUL)
46 * uint8 value(n)_length
47 * ... value(n) (no NUL)
48 * <existing DFU footer>
49
50 * Returns: %TRUE for success
51 **/
52 gboolean
53 dfu_firmware_from_metadata (DfuFirmware *firmware,
54 GBytes *bytes,
55 DfuFirmwareParseFlags flags,
56 GError **error)
57 {
58 const guint8 *data;
59 gsize data_length;
60 guint i;
61 guint idx = 2;
62 guint kvlen;
63 guint number_keys;
64
65 /* not big enough */
66 data = g_bytes_get_data (bytes, &data_length);
67 if (data_length <= 0x10)
68 return TRUE;
69
70 /* signature invalid */
71 if (memcmp (data, "MD", 2) != 0)
72 return TRUE;
73
74 /* parse key=value store */
75 number_keys = data[idx++];
76 for (i = 0; i < number_keys; i++) {
77 g_autofree gchar *key = NULL;
78 g_autofree gchar *value = NULL;
79
80 /* parse key */
81 kvlen = data[idx++];
82 if (kvlen > 233) {
83 g_set_error (error,
84 DFU_ERROR,
85 DFU_ERROR_INTERNAL,
86 "metadata table corrupt, key=%u",
87 kvlen);
88 return FALSE;
89 }
90 if (idx + kvlen + 0x10 > data_length) {
91 g_set_error (error,
92 DFU_ERROR,
93 DFU_ERROR_INTERNAL,
94 "metadata table corrupt, k-kvlen=%u",
95 kvlen);
96 return FALSE;
97 }
98 key = g_strndup ((const gchar *) data + idx, kvlen);
99 idx += kvlen;
100
101 /* parse value */
102 kvlen = data[idx++];
103 if (kvlen > 233) {
104 g_set_error (error,
105 DFU_ERROR,
106 DFU_ERROR_INTERNAL,
107 "metadata table corrupt, value=%u",
108 kvlen);
109 return FALSE;
110 }
111 if (idx + kvlen + 0x10 > data_length) {
112 g_set_error (error,
113 DFU_ERROR,
114 DFU_ERROR_INTERNAL,
115 "metadata table corrupt, v-kvlen=%u",
116 kvlen);
117 return FALSE;
118 }
119 value = g_strndup ((const gchar *) data + idx, kvlen);
120 idx += kvlen;
121 dfu_firmware_set_metadata (firmware, key, value);
122 }
123 return TRUE;
124 }
125
126 /**
127 * dfu_firmware_to_metadata: (skip)
128 * @firmware: a #DfuFirmware
129 * @error: a #GError, or %NULL
130 *
131 * Packs metadata firmware
132 *
133 * Returns: (transfer full): the packed data
134 **/
135 GBytes *
136 dfu_firmware_to_metadata (DfuFirmware *firmware, GError **error)
137 {
138 GList *l;
139 GHashTable *metadata;
140 guint8 mdbuf[239];
141 guint idx = 0;
142 guint number_keys;
143 g_autoptr(GList) keys = NULL;
144
145 /* no metadata */
146 metadata = dfu_firmware_get_metadata_table (firmware);
147 if (g_hash_table_size (metadata) == 0)
148 return g_bytes_new (NULL, 0);
149
150 /* check the number of keys */
151 keys = g_hash_table_get_keys (metadata);
152 number_keys = g_list_length (keys);
153 if (number_keys > 59) {
154 g_set_error (error,
155 DFU_ERROR,
156 DFU_ERROR_NOT_SUPPORTED,
157 "too many metadata keys (%u)",
158 number_keys);
159 return NULL;
160 }
161
162 /* write the signature */
163 mdbuf[idx++] = 'M';
164 mdbuf[idx++] = 'D';
165 mdbuf[idx++] = (guint8) number_keys;
166 for (l = keys; l != NULL; l = l->next) {
167 const gchar *key;
168 const gchar *value;
169 guint key_len;
170 guint value_len;
171
172 /* check key and value length */
173 key = l->data;
174 key_len = (guint) strlen (key);
175 if (key_len > 233) {
176 g_set_error (error,
177 DFU_ERROR,
178 DFU_ERROR_NOT_SUPPORTED,
179 "metdata key too long: %s",
180 key);
181 return NULL;
182 }
183 value = g_hash_table_lookup (metadata, key);
184 value_len = (guint) strlen (value);
185 if (value_len > 233) {
186 g_set_error (error,
187 DFU_ERROR,
188 DFU_ERROR_NOT_SUPPORTED,
189 "value too long: %s",
190 value);
191 return NULL;
192 }
193
194 /* do we still have space? */
195 if (idx + key_len + value_len + 2 > sizeof(mdbuf)) {
196 g_set_error (error,
197 DFU_ERROR,
198 DFU_ERROR_NOT_SUPPORTED,
199 "not enough space in metadata table, "
200 "already used %u bytes", idx);
201 return NULL;
202 }
203
204 /* write the key */
205 mdbuf[idx++] = (guint8) key_len;
206 memcpy(mdbuf + idx, key, key_len);
207 idx += key_len;
208
209 /* write the value */
210 mdbuf[idx++] = (guint8) value_len;
211 memcpy(mdbuf + idx, value, value_len);
212 idx += value_len;
213 }
214 g_debug ("metadata table was %u/%" G_GSIZE_FORMAT " bytes",
215 idx, sizeof(mdbuf));
216 return g_bytes_new (mdbuf, idx);
217 }
+0
-41
libdfu/dfu-format-metadata.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_METADATA_H
22 #define __DFU_FORMAT_METADATA_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 GBytes *dfu_firmware_to_metadata (DfuFirmware *firmware,
32 GError **error);
33 gboolean dfu_firmware_from_metadata (DfuFirmware *firmware,
34 GBytes *bytes,
35 DfuFirmwareParseFlags flags,
36 GError **error);
37
38 G_END_DECLS
39
40 #endif /* __DFU_FORMAT_METADATA_H */
+0
-106
libdfu/dfu-format-raw.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-raw.h"
27 #include "dfu-image.h"
28 #include "dfu-error.h"
29
30 /**
31 * dfu_firmware_detect_raw: (skip)
32 * @bytes: data to parse
33 *
34 * Attempts to sniff the data and work out the firmware format
35 *
36 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW
37 **/
38 DfuFirmwareFormat
39 dfu_firmware_detect_raw (GBytes *bytes)
40 {
41 return DFU_FIRMWARE_FORMAT_RAW;
42 }
43
44 /**
45 * dfu_firmware_from_raw: (skip)
46 * @firmware: a #DfuFirmware
47 * @bytes: data to parse
48 * @flags: some #DfuFirmwareParseFlags
49 * @error: a #GError, or %NULL
50 *
51 * Unpacks into a firmware object from raw data.
52 *
53 * Returns: %TRUE for success
54 **/
55 gboolean
56 dfu_firmware_from_raw (DfuFirmware *firmware,
57 GBytes *bytes,
58 DfuFirmwareParseFlags flags,
59 GError **error)
60 {
61 g_autoptr(DfuElement) element = NULL;
62 g_autoptr(DfuImage) image = NULL;
63 image = dfu_image_new ();
64 element = dfu_element_new ();
65 dfu_element_set_contents (element, bytes);
66 dfu_image_add_element (image, element);
67 dfu_firmware_add_image (firmware, image);
68 return TRUE;
69 }
70
71 /**
72 * dfu_firmware_to_raw: (skip)
73 * @firmware: a #DfuFirmware
74 * @error: a #GError, or %NULL
75 *
76 * Packs raw firmware
77 *
78 * Returns: (transfer full): the packed data
79 **/
80 GBytes *
81 dfu_firmware_to_raw (DfuFirmware *firmware, GError **error)
82 {
83 DfuElement *element;
84 DfuImage *image;
85 GBytes *contents;
86
87 image = dfu_firmware_get_image_default (firmware);
88 if (image == NULL) {
89 g_set_error_literal (error,
90 DFU_ERROR,
91 DFU_ERROR_NOT_FOUND,
92 "no firmware image data to write");
93 return NULL;
94 }
95 element = dfu_image_get_element (image, 0);
96 if (element == NULL) {
97 g_set_error_literal (error,
98 DFU_ERROR,
99 DFU_ERROR_NOT_FOUND,
100 "no firmware element data to write");
101 return NULL;
102 }
103 contents = dfu_element_get_contents (element);
104 return g_bytes_ref (contents);
105 }
+0
-42
libdfu/dfu-format-raw.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_RAW_H
22 #define __DFU_FORMAT_RAW_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_raw (GBytes *bytes);
32 GBytes *dfu_firmware_to_raw (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_raw (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_RAW_H */
+0
-318
libdfu/dfu-image.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-image
23 * @short_description: Object representing a a firmware image
24 *
25 * A #DfuImage is typically made up of several #DfuElements, although
26 * typically there will only be one.
27 *
28 * See also: #DfuElement
29 */
30
31 #include "config.h"
32
33 #include <string.h>
34 #include <stdio.h>
35
36 #include "dfu-common.h"
37 #include "dfu-element.h"
38 #include "dfu-error.h"
39 #include "dfu-image.h"
40
41 static void dfu_image_finalize (GObject *object);
42
43 typedef struct {
44 GPtrArray *elements;
45 gchar name[255];
46 guint8 alt_setting;
47 } DfuImagePrivate;
48
49 G_DEFINE_TYPE_WITH_PRIVATE (DfuImage, dfu_image, G_TYPE_OBJECT)
50 #define GET_PRIVATE(o) (dfu_image_get_instance_private (o))
51
52 static void
53 dfu_image_class_init (DfuImageClass *klass)
54 {
55 GObjectClass *object_class = G_OBJECT_CLASS (klass);
56 object_class->finalize = dfu_image_finalize;
57 }
58
59 static void
60 dfu_image_init (DfuImage *image)
61 {
62 DfuImagePrivate *priv = GET_PRIVATE (image);
63 priv->elements = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
64 memset (priv->name, 0x00, 255);
65 }
66
67 static void
68 dfu_image_finalize (GObject *object)
69 {
70 DfuImage *image = DFU_IMAGE (object);
71 DfuImagePrivate *priv = GET_PRIVATE (image);
72
73 g_ptr_array_unref (priv->elements);
74
75 G_OBJECT_CLASS (dfu_image_parent_class)->finalize (object);
76 }
77
78 /**
79 * dfu_image_new:
80 *
81 * Creates a new DFU image object.
82 *
83 * Return value: a new #DfuImage
84 *
85 * Since: 0.5.4
86 **/
87 DfuImage *
88 dfu_image_new (void)
89 {
90 DfuImage *image;
91 image = g_object_new (DFU_TYPE_IMAGE, NULL);
92 return image;
93 }
94
95 /**
96 * dfu_image_get_elements:
97 * @image: a #DfuImage
98 *
99 * Gets the element data.
100 *
101 * Return value: (transfer none) (element-type DfuElement): element data
102 *
103 * Since: 0.5.4
104 **/
105 GPtrArray *
106 dfu_image_get_elements (DfuImage *image)
107 {
108 DfuImagePrivate *priv = GET_PRIVATE (image);
109 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
110 return priv->elements;
111 }
112
113 /**
114 * dfu_image_get_element:
115 * @image: a #DfuImage
116 * @idx: an array index
117 *
118 * Gets the element.
119 *
120 * Return value: (transfer none): element data, or %NULL for invalid
121 *
122 * Since: 0.5.4
123 **/
124 DfuElement *
125 dfu_image_get_element (DfuImage *image, guint8 idx)
126 {
127 DfuImagePrivate *priv = GET_PRIVATE (image);
128 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
129 if (idx >= priv->elements->len)
130 return NULL;
131 return g_ptr_array_index (priv->elements, idx);
132 }
133
134 /**
135 * dfu_image_get_element_default:
136 * @image: a #DfuImage
137 *
138 * Gets the default element.
139 *
140 * Return value: (transfer none): element data, or %NULL for invalid
141 *
142 * Since: 0.7.1
143 **/
144 DfuElement *
145 dfu_image_get_element_default (DfuImage *image)
146 {
147 DfuImagePrivate *priv = GET_PRIVATE (image);
148 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
149 if (priv->elements->len == 0)
150 return NULL;
151 return g_ptr_array_index (priv->elements, 0);
152 }
153
154 /**
155 * dfu_image_get_alt_setting:
156 * @image: a #DfuImage
157 *
158 * Gets the alternate setting.
159 *
160 * Return value: integer, or 0x00 for unset
161 *
162 * Since: 0.5.4
163 **/
164 guint8
165 dfu_image_get_alt_setting (DfuImage *image)
166 {
167 DfuImagePrivate *priv = GET_PRIVATE (image);
168 g_return_val_if_fail (DFU_IS_IMAGE (image), 0xff);
169 return priv->alt_setting;
170 }
171
172 /**
173 * dfu_image_get_name:
174 * @image: a #DfuImage
175 *
176 * Gets the target name.
177 *
178 * Return value: a string, or %NULL for unset
179 *
180 * Since: 0.5.4
181 **/
182 const gchar *
183 dfu_image_get_name (DfuImage *image)
184 {
185 DfuImagePrivate *priv = GET_PRIVATE (image);
186 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
187 return priv->name;
188 }
189
190 /**
191 * dfu_image_get_size:
192 * @image: a #DfuImage
193 *
194 * Gets the size of all the elements in the image.
195 *
196 * This only returns actual data that would be sent to the device and
197 * does not include any padding.
198 *
199 * Return value: a integer value, or 0 if there are no elements.
200 *
201 * Since: 0.5.4
202 **/
203 guint32
204 dfu_image_get_size (DfuImage *image)
205 {
206 DfuImagePrivate *priv = GET_PRIVATE (image);
207 guint32 length = 0;
208 guint i;
209 g_return_val_if_fail (DFU_IS_IMAGE (image), 0);
210 for (i = 0; i < priv->elements->len; i++) {
211 DfuElement *element = g_ptr_array_index (priv->elements, i);
212 length += (guint32) g_bytes_get_size (dfu_element_get_contents (element));
213 }
214 return length;
215 }
216
217 /**
218 * dfu_image_add_element:
219 * @image: a #DfuImage
220 * @element: a #DfuElement
221 *
222 * Adds an element to the image.
223 *
224 * Since: 0.5.4
225 **/
226 void
227 dfu_image_add_element (DfuImage *image, DfuElement *element)
228 {
229 DfuImagePrivate *priv = GET_PRIVATE (image);
230 g_return_if_fail (DFU_IS_IMAGE (image));
231 g_return_if_fail (DFU_IS_ELEMENT (element));
232 g_ptr_array_add (priv->elements, g_object_ref (element));
233 }
234
235 /**
236 * dfu_image_set_alt_setting:
237 * @image: a #DfuImage
238 * @alt_setting: vendor ID, or 0xffff for unset
239 *
240 * Sets the vendor ID.
241 *
242 * Since: 0.5.4
243 **/
244 void
245 dfu_image_set_alt_setting (DfuImage *image, guint8 alt_setting)
246 {
247 DfuImagePrivate *priv = GET_PRIVATE (image);
248 g_return_if_fail (DFU_IS_IMAGE (image));
249 priv->alt_setting = alt_setting;
250 }
251
252 /**
253 * dfu_image_set_name:
254 * @image: a #DfuImage
255 * @name: a target string, or %NULL
256 *
257 * Sets the target name.
258 *
259 * Since: 0.5.4
260 **/
261 void
262 dfu_image_set_name (DfuImage *image, const gchar *name)
263 {
264 guint16 sz;
265 DfuImagePrivate *priv = GET_PRIVATE (image);
266 g_return_if_fail (DFU_IS_IMAGE (image));
267
268 /* this is a hard limit in DfuSe */
269 memset (priv->name, 0x00, 0xff);
270 if (name != NULL) {
271 sz = MIN ((guint16) strlen (name), 0xff - 1);
272 memcpy (priv->name, name, sz);
273 }
274
275 /* copy junk data in self tests for 1:1 copies */
276 if (name != NULL && G_UNLIKELY (g_getenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME") != NULL))
277 memcpy (priv->name, name, 0xff);
278 }
279
280 /**
281 * dfu_image_to_string:
282 * @image: a #DfuImage
283 *
284 * Returns a string representaiton of the object.
285 *
286 * Return value: NULL terminated string, or %NULL for invalid
287 *
288 * Since: 0.5.4
289 **/
290 gchar *
291 dfu_image_to_string (DfuImage *image)
292 {
293 DfuImagePrivate *priv = GET_PRIVATE (image);
294 GString *str;
295 guint i;
296
297 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
298
299 str = g_string_new ("");
300 g_string_append_printf (str, "alt_setting: 0x%02x\n", priv->alt_setting);
301 if (priv->name[0] != '\0')
302 g_string_append_printf (str, "name: %s\n", priv->name);
303 g_string_append_printf (str, "elements: 0x%02x\n",
304 priv->elements->len);
305
306 /* add elements */
307 for (i = 0; i < priv->elements->len; i++) {
308 DfuElement *element = g_ptr_array_index (priv->elements, i);
309 g_autofree gchar *tmp = NULL;
310 tmp = dfu_element_to_string (element);
311 g_string_append_printf (str, "== ELEMENT %u ==\n", i);
312 g_string_append_printf (str, "%s\n", tmp);
313 }
314
315 g_string_truncate (str, str->len - 1);
316 return g_string_free (str, FALSE);
317 }
+0
-73
libdfu/dfu-image.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_IMAGE_H
22 #define __DFU_IMAGE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-element.h"
28
29 G_BEGIN_DECLS
30
31 #define DFU_TYPE_IMAGE (dfu_image_get_type ())
32 G_DECLARE_DERIVABLE_TYPE (DfuImage, dfu_image, DFU, IMAGE, GObject)
33
34 struct _DfuImageClass
35 {
36 GObjectClass parent_class;
37 /*< private >*/
38 /* Padding for future expansion */
39 void (*_dfu_image_reserved1) (void);
40 void (*_dfu_image_reserved2) (void);
41 void (*_dfu_image_reserved3) (void);
42 void (*_dfu_image_reserved4) (void);
43 void (*_dfu_image_reserved5) (void);
44 void (*_dfu_image_reserved6) (void);
45 void (*_dfu_image_reserved7) (void);
46 void (*_dfu_image_reserved8) (void);
47 void (*_dfu_image_reserved9) (void);
48 };
49
50 DfuImage *dfu_image_new (void);
51
52 GPtrArray *dfu_image_get_elements (DfuImage *image);
53 DfuElement *dfu_image_get_element (DfuImage *image,
54 guint8 idx);
55 DfuElement *dfu_image_get_element_default (DfuImage *image);
56 guint8 dfu_image_get_alt_setting (DfuImage *image);
57 const gchar *dfu_image_get_name (DfuImage *image);
58 guint32 dfu_image_get_size (DfuImage *image);
59
60 void dfu_image_add_element (DfuImage *image,
61 DfuElement *element);
62
63 void dfu_image_set_alt_setting (DfuImage *image,
64 guint8 alt_setting);
65 void dfu_image_set_name (DfuImage *image,
66 const gchar *name);
67
68 gchar *dfu_image_to_string (DfuImage *image);
69
70 G_END_DECLS
71
72 #endif /* __DFU_IMAGE_H */
+0
-627
libdfu/dfu-patch.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-patch
23 * @short_description: Object representing a binary patch
24 *
25 * This object represents an binary patch that can be applied on a firmware
26 * image. The patch itself is made up of chunks of data that have an offset
27 * and that can replace the data to upgrade the firmware.
28 *
29 * Note: this is one way operation -- the patch can only be used to go forwards
30 * and also cannot be used to truncate the existing image.
31 *
32 * See also: #DfuImage, #DfuFirmware
33 */
34
35 #include "config.h"
36
37 #include <string.h>
38 #include <stdio.h>
39
40 #include "dfu-common.h"
41 #include "dfu-patch.h"
42 #include "dfu-error.h"
43
44 static void dfu_patch_finalize (GObject *object);
45
46 typedef struct __attribute__((packed)) {
47 guint32 off;
48 guint32 sz;
49 guint32 flags;
50 } DfuPatchChunkHeader;
51
52 typedef struct __attribute__((packed)) {
53 guint8 signature[4]; /* 'DfuP' */
54 guint8 reserved[4];
55 guint8 checksum_old[20]; /* SHA1 */
56 guint8 checksum_new[20]; /* SHA1 */
57 } DfuPatchFileHeader;
58
59 typedef struct {
60 GBytes *checksum_old;
61 GBytes *checksum_new;
62 GPtrArray *chunks; /* of DfuPatchChunk */
63 } DfuPatchPrivate;
64
65 typedef struct {
66 guint32 off;
67 GBytes *blob;
68 } DfuPatchChunk;
69
70 G_DEFINE_TYPE_WITH_PRIVATE (DfuPatch, dfu_patch, G_TYPE_OBJECT)
71 #define GET_PRIVATE(o) (dfu_patch_get_instance_private (o))
72
73 static void
74 dfu_patch_class_init (DfuPatchClass *klass)
75 {
76 GObjectClass *object_class = G_OBJECT_CLASS (klass);
77 object_class->finalize = dfu_patch_finalize;
78 }
79
80 static void
81 dfu_patch_chunk_free (DfuPatchChunk *chunk)
82 {
83 g_bytes_unref (chunk->blob);
84 g_free (chunk);
85 }
86
87 static void
88 dfu_patch_init (DfuPatch *self)
89 {
90 DfuPatchPrivate *priv = GET_PRIVATE (self);
91 priv->chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_patch_chunk_free);
92 }
93
94 static void
95 dfu_patch_finalize (GObject *object)
96 {
97 DfuPatch *self = DFU_PATCH (object);
98 DfuPatchPrivate *priv = GET_PRIVATE (self);
99
100 if (priv->checksum_old != NULL)
101 g_bytes_unref (priv->checksum_old);
102 if (priv->checksum_new != NULL)
103 g_bytes_unref (priv->checksum_new);
104 g_ptr_array_unref (priv->chunks);
105
106 G_OBJECT_CLASS (dfu_patch_parent_class)->finalize (object);
107 }
108
109 /**
110 * dfu_patch_export:
111 * @self: a #DfuPatch
112 * @error: a #GError, or %NULL
113 *
114 * Converts the patch to a binary blob that can be stored as a file.
115 *
116 * Return value: (transfer full): blob
117 *
118 * Since: 0.9.6
119 **/
120 GBytes *
121 dfu_patch_export (DfuPatch *self, GError **error)
122 {
123 DfuPatchPrivate *priv = GET_PRIVATE (self);
124 gsize addr;
125 gsize sz;
126 guint8 *data;
127
128 g_return_val_if_fail (DFU_IS_PATCH (self), NULL);
129
130 /* check we have something to write */
131 if (priv->chunks->len == 0) {
132 g_set_error_literal (error,
133 DFU_ERROR,
134 DFU_ERROR_INVALID_FILE,
135 "no chunks to process");
136 return NULL;
137 }
138
139 /* calculate the size of the new blob */
140 sz = sizeof(DfuPatchFileHeader);
141 for (guint i = 0; i < priv->chunks->len; i++) {
142 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
143 sz += sizeof(DfuPatchChunkHeader) + g_bytes_get_size (chunk->blob);
144 }
145 g_debug ("blob size is %" G_GSIZE_FORMAT, sz);
146
147 /* actually allocate and fill in the blob */
148 data = g_malloc0 (sz);
149 memcpy (data, "DfuP", 4);
150
151 /* add checksums */
152 if (priv->checksum_old != NULL) {
153 gsize csum_sz = 0;
154 const guint8 *csum_data = g_bytes_get_data (priv->checksum_old, &csum_sz);
155 memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old),
156 csum_data, csum_sz);
157 }
158 if (priv->checksum_new != NULL) {
159 gsize csum_sz = 0;
160 const guint8 *csum_data = g_bytes_get_data (priv->checksum_new, &csum_sz);
161 memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new),
162 csum_data, csum_sz);
163 }
164
165 addr = sizeof(DfuPatchFileHeader);
166 for (guint i = 0; i < priv->chunks->len; i++) {
167 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
168 DfuPatchChunkHeader chunkhdr;
169 gsize sz_tmp = 0;
170 const guint8 *data_new = g_bytes_get_data (chunk->blob, &sz_tmp);
171
172 /* build chunk header and append data */
173 chunkhdr.off = GUINT32_TO_LE (chunk->off);
174 chunkhdr.sz = GUINT32_TO_LE (sz_tmp);
175 chunkhdr.flags = 0;
176 memcpy (data + addr, &chunkhdr, sizeof(DfuPatchChunkHeader));
177 memcpy (data + addr + sizeof(DfuPatchChunkHeader), data_new, sz_tmp);
178
179 /* move up after the copied data */
180 addr += sizeof(DfuPatchChunkHeader) + sz_tmp;
181 }
182 return g_bytes_new_take (data, sz);
183
184 }
185
186 /**
187 * dfu_patch_import:
188 * @self: a #DfuPatch
189 * @blob: patch data
190 * @error: a #GError, or %NULL
191 *
192 * Creates a patch from a serialized patch, possibly from a file.
193 *
194 * Return value: %TRUE on success
195 *
196 * Since: 0.9.6
197 **/
198 gboolean
199 dfu_patch_import (DfuPatch *self, GBytes *blob, GError **error)
200 {
201 DfuPatchPrivate *priv = GET_PRIVATE (self);
202 const guint8 *data;
203 gsize sz = 0;
204 guint32 off;
205
206 g_return_val_if_fail (DFU_IS_PATCH (self), FALSE);
207 g_return_val_if_fail (blob != NULL, FALSE);
208
209 /* cannot reuse object */
210 if (priv->chunks->len > 0) {
211 g_set_error_literal (error,
212 DFU_ERROR,
213 DFU_ERROR_INVALID_FILE,
214 "patch has already been loaded");
215 return FALSE;
216 }
217
218 /* check minimum size */
219 data = g_bytes_get_data (blob, &sz);
220 if (sz < sizeof(DfuPatchFileHeader) + sizeof(DfuPatchChunkHeader) + 1) {
221 g_set_error_literal (error,
222 DFU_ERROR,
223 DFU_ERROR_INVALID_FILE,
224 "file is too small");
225 return FALSE;
226 }
227
228 /* check header */
229 if (memcmp (data, "DfuP", 4) != 0) {
230 g_set_error_literal (error,
231 DFU_ERROR,
232 DFU_ERROR_INVALID_FILE,
233 "header signature is not correct");
234 return FALSE;
235 }
236
237 /* get checksums */
238 priv->checksum_old = g_bytes_new (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old), 20);
239 priv->checksum_new = g_bytes_new (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new), 20);
240
241 /* look for each chunk */
242 off = sizeof(DfuPatchFileHeader);
243 while (off < (guint32) sz) {
244 DfuPatchChunkHeader *chunkhdr = (DfuPatchChunkHeader *) (data + off);
245 DfuPatchChunk *chunk;
246 guint32 chunk_sz = GUINT32_FROM_LE (chunkhdr->sz);
247 guint32 chunk_off = GUINT32_FROM_LE (chunkhdr->off);
248
249 /* check chunk size, assuming it can overflow */
250 if (chunk_sz > sz || off + chunk_sz > sz) {
251 g_set_error (error,
252 DFU_ERROR,
253 DFU_ERROR_INVALID_FILE,
254 "chunk offset 0x%04x outsize file size 0x%04x",
255 (guint) (off + chunk_sz), (guint) sz);
256 return FALSE;
257 }
258 chunk = g_new0 (DfuPatchChunk, 1);
259 chunk->off = chunk_off;
260 chunk->blob = g_bytes_new_from_bytes (blob, off + sizeof(DfuPatchChunkHeader), chunk_sz);
261 g_ptr_array_add (priv->chunks, chunk);
262 off += sizeof(DfuPatchChunkHeader) + chunk_sz;
263 }
264
265 /* check we finished properly */
266 if (off != sz) {
267 g_set_error_literal (error,
268 DFU_ERROR,
269 DFU_ERROR_INVALID_FILE,
270 "blob chunk sizes did not sum to total");
271 return FALSE;
272 }
273
274 /* success */
275 return TRUE;
276 }
277
278
279 static GBytes *
280 dfu_patch_calculate_checksum (GBytes *blob)
281 {
282 const guchar *data;
283 gsize digest_len = 20;
284 gsize sz = 0;
285 guint8 *buf = g_malloc0 (digest_len);
286 g_autoptr(GChecksum) csum = NULL;
287 csum = g_checksum_new (G_CHECKSUM_SHA1);
288 data = g_bytes_get_data (blob, &sz);
289 g_checksum_update (csum, data, (gssize) sz);
290 g_checksum_get_digest (csum, buf, &digest_len);
291 return g_bytes_new (buf, digest_len);
292 }
293
294 typedef struct {
295 guint32 diff_start;
296 guint32 diff_end;
297 GBytes *blob; /* no ref */
298 } DfuPatchCreateHelper;
299
300 static void
301 dfu_patch_flush (DfuPatch *self, DfuPatchCreateHelper *helper)
302 {
303 DfuPatchChunk *chunk;
304 DfuPatchPrivate *priv = GET_PRIVATE (self);
305
306 if (helper->diff_end == 0xffff)
307 return;
308 g_debug ("add chunk @0x%04x (len %" G_GUINT32_FORMAT ")",
309 (guint) helper->diff_start, helper->diff_end - helper->diff_start + 1);
310
311 chunk = g_new0 (DfuPatchChunk, 1);
312 chunk->off = helper->diff_start;
313 chunk->blob = g_bytes_new_from_bytes (helper->blob, chunk->off,
314 helper->diff_end - helper->diff_start + 1);
315 g_ptr_array_add (priv->chunks, chunk);
316 helper->diff_end = 0xffff;
317 }
318
319 /**
320 * dfu_patch_create:
321 * @self: a #DfuPatch
322 * @blob1: a #GBytes, typically the old firmware image
323 * @blob2: a #GBytes, typically the new firmware image
324 * @error: a #GError, or %NULL
325 *
326 * Creates a patch from two blobs of memory.
327 *
328 * The blobs should ideally be the same size. If @blob2 is has grown in size
329 * the binary diff will still work but the algorithm will probably not perform
330 * well unless the majority of data has just been appended.
331 *
332 * As an additional constrainst, @blob2 cannot be smaller than @blob1, i.e.
333 * the firmware cannot be truncated by this format.
334 *
335 * Return value: %TRUE on success
336 *
337 * Since: 0.9.6
338 **/
339 gboolean
340 dfu_patch_create (DfuPatch *self, GBytes *blob1, GBytes *blob2, GError **error)
341 {
342 DfuPatchPrivate *priv = GET_PRIVATE (self);
343 DfuPatchCreateHelper helper;
344 const guint8 *data1;
345 const guint8 *data2;
346 gsize sz1 = 0;
347 gsize sz2 = 0;
348 guint32 same_sz = 0;
349
350 g_return_val_if_fail (DFU_IS_PATCH (self), FALSE);
351 g_return_val_if_fail (blob1 != NULL, FALSE);
352 g_return_val_if_fail (blob2 != NULL, FALSE);
353
354 /* are the blobs the same */
355 if (g_bytes_equal (blob1, blob2)) {
356 g_set_error_literal (error,
357 DFU_ERROR,
358 DFU_ERROR_INVALID_FILE,
359 "old and new binaries are the same");
360 return FALSE;
361 }
362
363 /* cannot reuse object */
364 if (priv->chunks->len > 0) {
365 g_set_error_literal (error,
366 DFU_ERROR,
367 DFU_ERROR_INVALID_FILE,
368 "patch has already been loaded");
369 return FALSE;
370 }
371
372 /* get the hash of the old firmware file */
373 priv->checksum_old = dfu_patch_calculate_checksum (blob1);
374 priv->checksum_new = dfu_patch_calculate_checksum (blob2);
375
376 /* get the raw data, and ensure they are the same size */
377 data1 = g_bytes_get_data (blob1, &sz1);
378 data2 = g_bytes_get_data (blob2, &sz2);
379 if (sz1 > sz2) {
380 g_set_error (error,
381 DFU_ERROR,
382 DFU_ERROR_NOT_SUPPORTED,
383 "firmware binary cannot go down, got "
384 "%" G_GSIZE_FORMAT " and %" G_GSIZE_FORMAT,
385 sz1, sz2);
386 return FALSE;
387 }
388 if (sz1 == sz2) {
389 g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz1);
390 } else {
391 g_debug ("binary growing from: %" G_GSIZE_FORMAT
392 " to %" G_GSIZE_FORMAT, sz1, sz2);
393 }
394
395 /* start the dumb comparison algorithm */
396 helper.diff_start = 0;
397 helper.diff_end = 0xffff;
398 helper.blob = blob2;
399 for (gsize i = 0; i < sz1 || i < sz2; i++) {
400 if (i < sz1 && i < sz2 &&
401 data1[i] == data2[i]) {
402 /* if we got enough the same, dump what is pending */
403 if (++same_sz > sizeof(DfuPatchChunkHeader) * 2)
404 dfu_patch_flush (self, &helper);
405 continue;
406 }
407 if (helper.diff_end == 0xffff)
408 helper.diff_start = (guint32) i;
409 helper.diff_end = (guint32) i;
410 same_sz = 0;
411 }
412 dfu_patch_flush (self, &helper);
413 return TRUE;
414 }
415
416 static gchar *
417 _g_bytes_to_string (GBytes *blob)
418 {
419 gsize sz = 0;
420 const guint8 *data = g_bytes_get_data (blob, &sz);
421 GString *str = g_string_new (NULL);
422 for (gsize i = 0; i < sz; i++)
423 g_string_append_printf (str, "%02x", (guint) data[i]);
424 return g_string_free (str, FALSE);
425 }
426
427 /**
428 * dfu_patch_get_checksum_old:
429 * @self: a #DfuPatch
430 *
431 * Get the checksum for the old firmware image.
432 *
433 * Return value: A #GBytes, or %NULL if nothing has been loaded.
434 *
435 * Since: 0.9.6
436 **/
437 GBytes *
438 dfu_patch_get_checksum_old (DfuPatch *self)
439 {
440 DfuPatchPrivate *priv = GET_PRIVATE (self);
441 return priv->checksum_old;
442 }
443
444 /**
445 * dfu_patch_get_checksum_new:
446 * @self: a #DfuPatch
447 *
448 * Get the checksum for the new firmware image.
449 *
450 * Return value: A #GBytes, or %NULL if nothing has been loaded.
451 *
452 * Since: 0.9.6
453 **/
454 GBytes *
455 dfu_patch_get_checksum_new (DfuPatch *self)
456 {
457 DfuPatchPrivate *priv = GET_PRIVATE (self);
458 return priv->checksum_new;
459 }
460
461 /**
462 * dfu_patch_apply:
463 * @self: a #DfuPatch
464 * @blob: a #GBytes, typically the old firmware image
465 * @flags: a #DfuPatchApplyFlags, e.g. %DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM
466 * @error: a #GError, or %NULL
467 *
468 * Apply the currently loaded patch to a new firmware image.
469 *
470 * Return value: A #GBytes, typically saved as the new firmware file
471 *
472 * Since: 0.9.6
473 **/
474 GBytes *
475 dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError **error)
476 {
477 DfuPatchPrivate *priv = GET_PRIVATE (self);
478 const guint8 *data_old;
479 gsize sz;
480 gsize sz_max = 0;
481 g_autofree guint8 *data_new = NULL;
482 g_autoptr(GBytes) blob_checksum_new = NULL;
483 g_autoptr(GBytes) blob_checksum = NULL;
484 g_autoptr(GBytes) blob_new = NULL;
485
486 /* not loaded yet */
487 if (priv->chunks->len == 0) {
488 g_set_error_literal (error,
489 DFU_ERROR,
490 DFU_ERROR_INVALID_DEVICE,
491 "no patches loaded");
492 return NULL;
493 }
494
495 /* get the hash of the old firmware file */
496 blob_checksum = dfu_patch_calculate_checksum (blob);
497 if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 &&
498 !g_bytes_equal (blob_checksum, priv->checksum_old)) {
499 g_autofree gchar *actual = _g_bytes_to_string (blob_checksum);
500 g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_old);
501 g_set_error (error,
502 DFU_ERROR,
503 DFU_ERROR_INVALID_DEVICE,
504 "checksum for source did not match, expected %s, got %s",
505 expect, actual);
506 return NULL;
507 }
508
509 /* get the size of the new image size */
510 for (guint i = 0; i < priv->chunks->len; i++) {
511 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
512 gsize chunk_sz = g_bytes_get_size (chunk->blob);
513 if (chunk->off + chunk_sz > sz_max)
514 sz_max = chunk->off + chunk_sz;
515 }
516
517 /* first, copy the data buffer */
518 data_old = g_bytes_get_data (blob, &sz);
519 if (sz_max < sz) {
520 g_set_error_literal (error,
521 DFU_ERROR,
522 DFU_ERROR_INVALID_FILE,
523 "binary patch cannot truncate binary");
524 return NULL;
525 }
526 if (sz == sz_max) {
527 g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz);
528 } else {
529 g_debug ("binary growing from: %" G_GSIZE_FORMAT
530 " to %" G_GSIZE_FORMAT, sz, sz_max);
531 }
532
533 data_new = g_malloc0 (sz_max);
534 memcpy (data_new, data_old, sz_max);
535 for (guint i = 0; i < priv->chunks->len; i++) {
536 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
537 const guint8 *chunk_data;
538 gsize chunk_sz;
539
540 /* bigger than the total size */
541 chunk_data = g_bytes_get_data (chunk->blob, &chunk_sz);
542 if (chunk->off + chunk_sz > sz_max) {
543 g_set_error (error,
544 DFU_ERROR,
545 DFU_ERROR_INVALID_FILE,
546 "cannot apply chunk as larger than max size");
547 return NULL;
548 }
549
550 /* apply one chunk */
551 g_debug ("applying chunk %u/%u @0x%04x (length %" G_GSIZE_FORMAT ")",
552 i + 1, priv->chunks->len, chunk->off, chunk_sz);
553 memcpy (data_new + chunk->off, chunk_data, chunk_sz);
554 }
555
556 /* check we got the desired hash */
557 blob_new = g_bytes_new (data_new, sz_max);
558 blob_checksum_new = dfu_patch_calculate_checksum (blob_new);
559 if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 &&
560 !g_bytes_equal (blob_checksum_new, priv->checksum_new)) {
561 g_autofree gchar *actual = _g_bytes_to_string (blob_checksum_new);
562 g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_new);
563 g_set_error (error,
564 DFU_ERROR,
565 DFU_ERROR_INVALID_DEVICE,
566 "checksum for result did not match, expected %s, got %s",
567 expect, actual);
568 return NULL;
569 }
570
571 /* success */
572 return g_steal_pointer (&blob_new);
573 }
574
575 /**
576 * dfu_patch_to_string:
577 * @self: a #DfuPatch
578 *
579 * Returns a string representaiton of the object.
580 *
581 * Return value: NULL terminated string, or %NULL for invalid
582 *
583 * Since: 0.9.6
584 **/
585 gchar *
586 dfu_patch_to_string (DfuPatch *self)
587 {
588 DfuPatchPrivate *priv = GET_PRIVATE (self);
589 GString *str = g_string_new (NULL);
590 g_autofree gchar *checksum_old = NULL;
591 g_autofree gchar *checksum_new = NULL;
592
593 g_return_val_if_fail (DFU_IS_PATCH (self), NULL);
594
595 /* add checksums */
596 checksum_old = _g_bytes_to_string (priv->checksum_old);
597 g_string_append_printf (str, "checksum-old: %s\n", checksum_old);
598 checksum_new = _g_bytes_to_string (priv->checksum_new);
599 g_string_append_printf (str, "checksum-new: %s\n", checksum_new);
600
601 /* add chunks */
602 for (guint i = 0; i < priv->chunks->len; i++) {
603 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
604 g_string_append_printf (str, "chunk #%02u 0x%04x, length %" G_GSIZE_FORMAT "\n",
605 i, chunk->off, g_bytes_get_size (chunk->blob));
606 }
607 g_string_truncate (str, str->len - 1);
608 return g_string_free (str, FALSE);
609 }
610
611 /**
612 * dfu_patch_new:
613 *
614 * Creates a new DFU patch object.
615 *
616 * Return value: a new #DfuPatch
617 *
618 * Since: 0.9.6
619 **/
620 DfuPatch *
621 dfu_patch_new (void)
622 {
623 DfuPatch *self;
624 self = g_object_new (DFU_TYPE_PATCH, NULL);
625 return self;
626 }
+0
-83
libdfu/dfu-patch.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_PATCH_H
22 #define __DFU_PATCH_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 #define DFU_TYPE_PATCH (dfu_patch_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (DfuPatch, dfu_patch, DFU, PATCH, GObject)
31
32 struct _DfuPatchClass
33 {
34 GObjectClass parent_class;
35 /*< private >*/
36 void (*_dfu_patch_reserved1) (void);
37 void (*_dfu_patch_reserved2) (void);
38 void (*_dfu_patch_reserved3) (void);
39 void (*_dfu_patch_reserved4) (void);
40 void (*_dfu_patch_reserved5) (void);
41 void (*_dfu_patch_reserved6) (void);
42 void (*_dfu_patch_reserved7) (void);
43 void (*_dfu_patch_reserved8) (void);
44 void (*_dfu_patch_reserved9) (void);
45 };
46
47 /**
48 * DfuPatchApplyFlags:
49 * @DFU_PATCH_APPLY_FLAG_NONE: No flags set
50 * @DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM: Do not check the checksum
51 *
52 * The optional flags used for applying a patch.
53 **/
54 typedef enum {
55 DFU_PATCH_APPLY_FLAG_NONE = 0,
56 DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM = (1 << 0),
57 /*< private >*/
58 DFU_PATCH_APPLY_FLAG_LAST
59 } DfuPatchApplyFlags;
60
61 DfuPatch *dfu_patch_new (void);
62
63 gchar *dfu_patch_to_string (DfuPatch *self);
64 GBytes *dfu_patch_export (DfuPatch *self,
65 GError **error);
66 gboolean dfu_patch_import (DfuPatch *self,
67 GBytes *blob,
68 GError **error);
69 gboolean dfu_patch_create (DfuPatch *self,
70 GBytes *blob1,
71 GBytes *blob2,
72 GError **error);
73 GBytes *dfu_patch_apply (DfuPatch *self,
74 GBytes *blob,
75 DfuPatchApplyFlags flags,
76 GError **error);
77 GBytes *dfu_patch_get_checksum_old (DfuPatch *self);
78 GBytes *dfu_patch_get_checksum_new (DfuPatch *self);
79
80 G_END_DECLS
81
82 #endif /* __DFU_PATCH_H */
+0
-330
libdfu/dfu-progress-bar.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2008-20 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <glib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27
28 #include "dfu-progress-bar.h"
29
30 typedef struct {
31 guint position;
32 gboolean move_forward;
33 } DfuProgressBarPulseState;
34
35 struct _DfuProgressBar {
36 GObject parent_instance;
37 guint size;
38 gint percentage;
39 guint padding;
40 guint timer_id;
41 DfuProgressBarPulseState pulse_state;
42 gint tty_fd;
43 gchar *old_start_text;
44 };
45
46 #define DFU_PROGRESS_BAR_PERCENTAGE_INVALID 101
47 #define DFU_PROGRESS_BAR_PULSE_TIMEOUT 40 /* ms */
48
49 G_DEFINE_TYPE (DfuProgressBar, dfu_progress_bar, G_TYPE_OBJECT)
50
51 static void
52 dfu_progress_bar_console (DfuProgressBar *self, const gchar *tmp)
53 {
54 gssize count;
55 gssize wrote;
56 count = strlen (tmp) + 1;
57 wrote = write (self->tty_fd, tmp, count);
58 if (wrote != count) {
59 g_warning ("Only wrote %" G_GSSIZE_FORMAT
60 " of %" G_GSSIZE_FORMAT " bytes",
61 wrote, count);
62 }
63 }
64
65 void
66 dfu_progress_bar_set_padding (DfuProgressBar *self, guint padding)
67 {
68 g_return_if_fail (DFU_IS_PROGRESS_BAR (self));
69 g_return_if_fail (padding < 100);
70 self->padding = padding;
71 }
72
73 void
74 dfu_progress_bar_set_size (DfuProgressBar *self, guint size)
75 {
76 g_return_if_fail (DFU_IS_PROGRESS_BAR (self));
77 g_return_if_fail (size < 100);
78 self->size = size;
79 }
80
81 static gboolean
82 dfu_progress_bar_draw (DfuProgressBar *self, gint percentage)
83 {
84 guint section;
85 guint i;
86 GString *str;
87
88 /* no value yet */
89 if (percentage == G_MININT)
90 return FALSE;
91
92 /* restore cursor */
93 str = g_string_new ("");
94 g_string_append_printf (str, "%c8", 0x1B);
95
96 section = (guint) ((gfloat) self->size / (gfloat) 100.0 * (gfloat) percentage);
97 g_string_append (str, "[");
98 for (i = 0; i < section; i++)
99 g_string_append (str, "=");
100 for (i = 0; i < self->size - section; i++)
101 g_string_append (str, " ");
102 g_string_append (str, "] ");
103 if (percentage >= 0 && percentage < 100)
104 g_string_append_printf (str, "(%i%%) ", percentage);
105 else
106 g_string_append (str, " ");
107 dfu_progress_bar_console (self, str->str);
108 g_string_free (str, TRUE);
109 return TRUE;
110 }
111
112 static gboolean
113 dfu_progress_bar_pulse_bar (DfuProgressBar *self)
114 {
115 gint i;
116 g_autoptr(GString) str = NULL;
117
118 /* restore cursor */
119 str = g_string_new ("");
120 g_string_append_printf (str, "%c8", 0x1B);
121
122 if (self->pulse_state.move_forward) {
123 if (self->pulse_state.position == self->size - 1)
124 self->pulse_state.move_forward = FALSE;
125 else
126 self->pulse_state.position++;
127 } else if (!self->pulse_state.move_forward) {
128 if (self->pulse_state.position == 1)
129 self->pulse_state.move_forward = TRUE;
130 else
131 self->pulse_state.position--;
132 }
133
134 g_string_append (str, "[");
135 for (i = 0; i < (gint)self->pulse_state.position-1; i++)
136 g_string_append (str, " ");
137 g_string_append (str, "==");
138 for (i = 0; i < (gint) (self->size - self->pulse_state.position - 1); i++)
139 g_string_append (str, " ");
140 g_string_append (str, "] ");
141 if (self->percentage >= 0 && self->percentage != DFU_PROGRESS_BAR_PERCENTAGE_INVALID)
142 g_string_append_printf (str, "(%i%%) ", self->percentage);
143 else
144 g_string_append (str, " ");
145 dfu_progress_bar_console (self, str->str);
146
147 return TRUE;
148 }
149
150 static void
151 dfu_progress_bar_draw_pulse_bar (DfuProgressBar *self)
152 {
153 /* have we already got zero percent? */
154 if (self->timer_id != 0)
155 return;
156 if (TRUE) {
157 self->pulse_state.position = 1;
158 self->pulse_state.move_forward = TRUE;
159 self->timer_id = g_timeout_add (DFU_PROGRESS_BAR_PULSE_TIMEOUT,
160 (GSourceFunc) dfu_progress_bar_pulse_bar, self);
161 g_source_set_name_by_id (self->timer_id, "[DfuProgressBar] pulse");
162 }
163 }
164
165 void
166 dfu_progress_bar_set_percentage (DfuProgressBar *self, gint percentage)
167 {
168 g_return_if_fail (DFU_IS_PROGRESS_BAR (self));
169 g_return_if_fail (percentage <= DFU_PROGRESS_BAR_PERCENTAGE_INVALID);
170
171 /* never called dfu_progress_bar_start() */
172 if (self->percentage == G_MININT)
173 dfu_progress_bar_start (self, "FIXME: need to call dfu_progress_bar_start() earlier!");
174
175 /* check for old percentage */
176 if (percentage == self->percentage) {
177 g_debug ("skipping as the same");
178 return;
179 }
180
181 /* save */
182 self->percentage = percentage;
183
184 /* either pulse or display */
185 if (percentage < 0 || percentage > 100) {
186 dfu_progress_bar_draw (self, 0);
187 dfu_progress_bar_draw_pulse_bar (self);
188 } else {
189 if (self->timer_id != 0) {
190 g_source_remove (self->timer_id);
191 self->timer_id = 0;
192 }
193 dfu_progress_bar_draw (self, percentage);
194 }
195 }
196
197 /**
198 * pk_strpad:
199 * @data: the input string
200 * @length: the desired length of the output string, with padding
201 *
202 * Returns the text padded to a length with spaces. If the string is
203 * longer than length then a longer string is returned.
204 *
205 * Return value: The padded string
206 **/
207 static gchar *
208 pk_strpad (const gchar *data, guint length)
209 {
210 gint size;
211 guint data_len;
212 gchar *text;
213 gchar *padding;
214
215 if (data == NULL)
216 return g_strnfill (length, ' ');
217
218 /* ITS4: ignore, only used for formatting */
219 data_len = strlen (data);
220
221 /* calculate */
222 size = (length - data_len);
223 if (size <= 0)
224 return g_strdup (data);
225
226 padding = g_strnfill (size, ' ');
227 text = g_strdup_printf ("%s%s", data, padding);
228 g_free (padding);
229 return text;
230 }
231
232 void
233 dfu_progress_bar_start (DfuProgressBar *self, const gchar *text)
234 {
235 g_autofree gchar *text_pad = NULL;
236 g_autoptr(GString) str = NULL;
237
238 g_return_if_fail (DFU_IS_PROGRESS_BAR (self));
239
240 /* same as last time */
241 if (g_strcmp0 (self->old_start_text, text) != 0) {
242 g_free (self->old_start_text);
243 self->old_start_text = g_strdup (text);
244 }
245
246 /* finish old value */
247 str = g_string_new ("");
248 if (self->percentage != G_MININT) {
249 dfu_progress_bar_draw (self, 100);
250 g_string_append (str, "\n");
251 }
252
253 /* make these all the same length */
254 text_pad = pk_strpad (text, self->padding);
255 g_string_append (str, text_pad);
256
257 /* save cursor in new position */
258 g_string_append_printf (str, "%c7", 0x1B);
259 dfu_progress_bar_console (self, str->str);
260
261 /* reset */
262 if (self->percentage == G_MININT)
263 self->percentage = 0;
264 dfu_progress_bar_draw (self, 0);
265 }
266
267 void
268 dfu_progress_bar_end (DfuProgressBar *self)
269 {
270 GString *str;
271
272 g_return_if_fail (DFU_IS_PROGRESS_BAR (self));
273
274 /* never drawn */
275 if (self->percentage == G_MININT)
276 return;
277
278 self->percentage = G_MININT;
279 dfu_progress_bar_draw (self, 100);
280 str = g_string_new ("");
281 g_string_append_printf (str, "\n");
282 dfu_progress_bar_console (self, str->str);
283 g_string_free (str, TRUE);
284 }
285
286 static void
287 dfu_progress_bar_finalize (GObject *object)
288 {
289 DfuProgressBar *self;
290 g_return_if_fail (DFU_IS_PROGRESS_BAR (object));
291 self = DFU_PROGRESS_BAR (object);
292
293 g_free (self->old_start_text);
294 if (self->timer_id != 0)
295 g_source_remove (self->timer_id);
296 if (self->tty_fd > 0)
297 close (self->tty_fd);
298 G_OBJECT_CLASS (dfu_progress_bar_parent_class)->finalize (object);
299 }
300
301 static void
302 dfu_progress_bar_class_init (DfuProgressBarClass *klass)
303 {
304 GObjectClass *object_class = G_OBJECT_CLASS (klass);
305 object_class->finalize = dfu_progress_bar_finalize;
306 }
307
308 static void
309 dfu_progress_bar_init (DfuProgressBar *self)
310 {
311 self->size = 10;
312 self->percentage = G_MININT;
313 self->padding = 0;
314 self->timer_id = 0;
315 self->tty_fd = open ("/dev/tty", O_RDWR, 0);
316 if (self->tty_fd < 0)
317 self->tty_fd = open ("/dev/console", O_RDWR, 0);
318 if (self->tty_fd < 0)
319 self->tty_fd = open ("/dev/stdout", O_RDWR, 0);
320 g_assert (self->tty_fd > 0);
321 }
322
323 DfuProgressBar *
324 dfu_progress_bar_new (void)
325 {
326 DfuProgressBar *self;
327 self = g_object_new (DFU_TYPE_PROGRESS_BAR, NULL);
328 return DFU_PROGRESS_BAR (self);
329 }
+0
-46
libdfu/dfu-progress-bar.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2009-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_PROGRESS_BAR_H
22 #define __DFU_PROGRESS_BAR_H
23
24 #include <glib-object.h>
25
26 G_BEGIN_DECLS
27
28 #define DFU_TYPE_PROGRESS_BAR (dfu_progress_bar_get_type ())
29
30 G_DECLARE_FINAL_TYPE (DfuProgressBar, dfu_progress_bar, DFU, PROGRESS_BAR, GObject)
31
32 DfuProgressBar *dfu_progress_bar_new (void);
33 void dfu_progress_bar_set_size (DfuProgressBar *progress_bar,
34 guint size);
35 void dfu_progress_bar_set_padding (DfuProgressBar *progress_bar,
36 guint padding);
37 void dfu_progress_bar_set_percentage (DfuProgressBar *progress_bar,
38 gint percentage);
39 void dfu_progress_bar_start (DfuProgressBar *progress_bar,
40 const gchar *text);
41 void dfu_progress_bar_end (DfuProgressBar *progress_bar);
42
43 G_END_DECLS
44
45 #endif /* __DFU_PROGRESS_BAR_H */
+0
-38
libdfu/dfu-sector-private.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_SECTOR_PRIVATE_H
22 #define __DFU_SECTOR_PRIVATE_H
23
24 #include "dfu-sector.h"
25
26 G_BEGIN_DECLS
27
28 DfuSector *dfu_sector_new (guint32 address,
29 guint32 size,
30 guint32 size_left,
31 guint16 zone,
32 guint16 number,
33 DfuSectorCap cap);
34
35 G_END_DECLS
36
37 #endif /* __DFU_SECTOR_PRIVATE_H */
+0
-269
libdfu/dfu-sector.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-sector
23 * @short_description: Object representing a sector on a chip
24 *
25 * This object represents an sector of memory at a specific address on the
26 * device itself.
27 *
28 * This allows relocatable data segments to be stored in different
29 * locations on the device itself.
30 *
31 * You can think of these objects as flash segments on devices, where a
32 * complete block can be erased and then written to.
33 *
34 * See also: #DfuElement
35 */
36
37 #include "config.h"
38
39 #include <string.h>
40 #include <stdio.h>
41
42 #include "dfu-common.h"
43 #include "dfu-sector-private.h"
44
45 typedef struct {
46 guint32 address;
47 guint32 size;
48 guint32 size_left;
49 guint16 zone;
50 guint16 number;
51 DfuSectorCap cap;
52 } DfuSectorPrivate;
53
54 G_DEFINE_TYPE_WITH_PRIVATE (DfuSector, dfu_sector, G_TYPE_OBJECT)
55 #define GET_PRIVATE(o) (dfu_sector_get_instance_private (o))
56
57 static void
58 dfu_sector_class_init (DfuSectorClass *klass)
59 {
60 }
61
62 static void
63 dfu_sector_init (DfuSector *sector)
64 {
65 }
66
67 /**
68 * dfu_sector_new: (skip)
69 * address: the address for the sector
70 * size: the size of this sector
71 * size_left: the size of the rest of the sector
72 * zone: the zone of memory the setor belongs
73 * number: the sector number in the zone
74 * cap: the #DfuSectorCap
75 *
76 * Creates a new DFU sector object.
77 *
78 * Return value: a new #DfuSector
79 *
80 * Since: 0.5.4
81 **/
82 DfuSector *
83 dfu_sector_new (guint32 address, guint32 size, guint32 size_left,
84 guint16 zone, guint16 number, DfuSectorCap cap)
85 {
86 DfuSectorPrivate *priv;
87 DfuSector *sector;
88 sector = g_object_new (DFU_TYPE_SECTOR, NULL);
89 priv = GET_PRIVATE (sector);
90 priv->address = address;
91 priv->size = size;
92 priv->size_left = size_left;
93 priv->zone = zone;
94 priv->number = number;
95 priv->cap = cap;
96 return sector;
97 }
98
99 /**
100 * dfu_sector_get_address:
101 * @sector: a #DfuSector
102 *
103 * Gets the alternate setting.
104 *
105 * Return value: integer, or 0x00 for unset
106 *
107 * Since: 0.5.4
108 **/
109 guint32
110 dfu_sector_get_address (DfuSector *sector)
111 {
112 DfuSectorPrivate *priv = GET_PRIVATE (sector);
113 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
114 return priv->address;
115 }
116
117 /**
118 * dfu_sector_get_size:
119 * @sector: a #DfuSector
120 *
121 * Gets the sector size.
122 *
123 * Return value: integer, or 0x00 for unset
124 *
125 * Since: 0.5.4
126 **/
127 guint32
128 dfu_sector_get_size (DfuSector *sector)
129 {
130 DfuSectorPrivate *priv = GET_PRIVATE (sector);
131 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
132 return priv->size;
133 }
134
135 /**
136 * dfu_sector_get_size_left:
137 * @sector: a #DfuSector
138 *
139 * Gets the size of the rest of the sector.
140 *
141 * Return value: integer, or 0x00 for unset
142 *
143 * Since: 0.5.4
144 **/
145 guint32
146 dfu_sector_get_size_left (DfuSector *sector)
147 {
148 DfuSectorPrivate *priv = GET_PRIVATE (sector);
149 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
150 return priv->size_left;
151 }
152
153 /**
154 * dfu_sector_get_zone:
155 * @sector: a #DfuSector
156 *
157 * Gets the sector zone number.
158 *
159 * Return value: integer, or 0x00 for unset
160 *
161 * Since: 0.7.5
162 **/
163 guint16
164 dfu_sector_get_zone (DfuSector *sector)
165 {
166 DfuSectorPrivate *priv = GET_PRIVATE (sector);
167 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
168 return priv->zone;
169 }
170
171 /**
172 * dfu_sector_get_number:
173 * @sector: a #DfuSector
174 *
175 * Gets the sector index number.
176 *
177 * Return value: integer, or 0x00 for unset
178 *
179 * Since: 0.7.5
180 **/
181 guint16
182 dfu_sector_get_number (DfuSector *sector)
183 {
184 DfuSectorPrivate *priv = GET_PRIVATE (sector);
185 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
186 return priv->number;
187 }
188
189 /**
190 * dfu_sector_get_id:
191 * @sector: a #DfuSector
192 *
193 * Gets the sector ID which is a combination of the zone and sector number.
194 * You can use this number to check if the segment is the 'same' as the last
195 * written or read sector.
196 *
197 * Return value: integer ID, or 0x00 for unset
198 *
199 * Since: 0.5.4
200 **/
201 guint32
202 dfu_sector_get_id (DfuSector *sector)
203 {
204 DfuSectorPrivate *priv = GET_PRIVATE (sector);
205 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
206 return (((guint32) priv->zone) << 16) | priv->number;
207 }
208
209 /**
210 * dfu_sector_has_cap:
211 * @sector: a #DfuSector
212 * @cap: a #DfuSectorCap, e.g. %DFU_SECTOR_CAP_ERASEABLE
213 *
214 * Finds out if the sector has the required capability.
215 *
216 * Return value: %TRUE if the sector has the capabilily
217 *
218 * Since: 0.5.4
219 **/
220 gboolean
221 dfu_sector_has_cap (DfuSector *sector, DfuSectorCap cap)
222 {
223 DfuSectorPrivate *priv = GET_PRIVATE (sector);
224 g_return_val_if_fail (DFU_IS_SECTOR (sector), FALSE);
225 return (priv->cap & cap) > 0;
226 }
227
228 static gchar *
229 dfu_sector_cap_to_string (DfuSectorCap cap)
230 {
231 GString *str = g_string_new (NULL);
232 if (cap & DFU_SECTOR_CAP_READABLE)
233 g_string_append (str, "R");
234 if (cap & DFU_SECTOR_CAP_ERASEABLE)
235 g_string_append (str, "E");
236 if (cap & DFU_SECTOR_CAP_WRITEABLE)
237 g_string_append (str, "W");
238 return g_string_free (str, FALSE);
239 }
240
241 /**
242 * dfu_sector_to_string:
243 * @sector: a #DfuSector
244 *
245 * Returns a string representaiton of the object.
246 *
247 * Return value: NULL terminated string, or %NULL for invalid
248 *
249 * Since: 0.5.4
250 **/
251 gchar *
252 dfu_sector_to_string (DfuSector *sector)
253 {
254 DfuSectorPrivate *priv = GET_PRIVATE (sector);
255 GString *str;
256 g_autofree gchar *caps_str = NULL;
257
258 g_return_val_if_fail (DFU_IS_SECTOR (sector), NULL);
259
260 str = g_string_new ("");
261 caps_str = dfu_sector_cap_to_string (priv->cap);
262 g_string_append_printf (str,
263 "Zone:%i, Sec#:%i, Addr:0x%08x, "
264 "Size:0x%04x, Caps:0x%01x [%s]",
265 priv->zone, priv->number, priv->address,
266 priv->size, priv->cap, caps_str);
267 return g_string_free (str, FALSE);
268 }
+0
-79
libdfu/dfu-sector.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_SECTOR_H
22 #define __DFU_SECTOR_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 #define DFU_TYPE_SECTOR (dfu_sector_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (DfuSector, dfu_sector, DFU, SECTOR, GObject)
31
32 struct _DfuSectorClass
33 {
34 GObjectClass parent_class;
35 /*< private >*/
36 /* Padding for future expansion */
37 void (*_dfu_sector_reserved1) (void);
38 void (*_dfu_sector_reserved2) (void);
39 void (*_dfu_sector_reserved3) (void);
40 void (*_dfu_sector_reserved4) (void);
41 void (*_dfu_sector_reserved5) (void);
42 void (*_dfu_sector_reserved6) (void);
43 void (*_dfu_sector_reserved7) (void);
44 void (*_dfu_sector_reserved8) (void);
45 void (*_dfu_sector_reserved9) (void);
46 };
47
48 /**
49 * DfuSectorCap:
50 * @DFU_SECTOR_CAP_NONE: No operations possible
51 * @DFU_SECTOR_CAP_READABLE: Sector can be read
52 * @DFU_SECTOR_CAP_WRITEABLE: Sector can be written
53 * @DFU_SECTOR_CAP_ERASEABLE: Sector can be erased
54 *
55 * The flags indicating what the sector can do.
56 **/
57 typedef enum {
58 DFU_SECTOR_CAP_NONE = 0,
59 DFU_SECTOR_CAP_READABLE = 1 << 0,
60 DFU_SECTOR_CAP_WRITEABLE = 1 << 1,
61 DFU_SECTOR_CAP_ERASEABLE = 1 << 2,
62 /*< private >*/
63 DFU_SECTOR_CAP_LAST
64 } DfuSectorCap;
65
66 guint32 dfu_sector_get_id (DfuSector *sector);
67 guint32 dfu_sector_get_address (DfuSector *sector);
68 guint32 dfu_sector_get_size (DfuSector *sector);
69 guint32 dfu_sector_get_size_left (DfuSector *sector);
70 guint16 dfu_sector_get_zone (DfuSector *sector);
71 guint16 dfu_sector_get_number (DfuSector *sector);
72 gboolean dfu_sector_has_cap (DfuSector *sector,
73 DfuSectorCap cap);
74 gchar *dfu_sector_to_string (DfuSector *sector);
75
76 G_END_DECLS
77
78 #endif /* __DFU_SECTOR_H */
+0
-1025
libdfu/dfu-self-test.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "config.h"
22
23 #include <glib-object.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <fnmatch.h>
27
28 #include "dfu-cipher-xtea.h"
29 #include "dfu-common.h"
30 #include "dfu-context.h"
31 #include "dfu-device.h"
32 #include "dfu-error.h"
33 #include "dfu-firmware.h"
34 #include "dfu-patch.h"
35 #include "dfu-sector-private.h"
36 #include "dfu-target-private.h"
37
38 static gchar *
39 dfu_test_get_filename (const gchar *filename)
40 {
41 gchar *tmp;
42 char full_tmp[PATH_MAX];
43 g_autofree gchar *path = NULL;
44 path = g_build_filename (TESTDATADIR, filename, NULL);
45 tmp = realpath (path, full_tmp);
46 if (tmp == NULL)
47 return NULL;
48 return g_strdup (full_tmp);
49 }
50
51 static gboolean
52 dfu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error)
53 {
54 g_autofree gchar *output = NULL;
55
56 /* exactly the same */
57 if (g_strcmp0 (txt1, txt2) == 0)
58 return TRUE;
59
60 /* matches a pattern */
61 if (fnmatch (txt2, txt1, FNM_NOESCAPE) == 0)
62 return TRUE;
63
64 /* save temp files and diff them */
65 if (!g_file_set_contents ("/tmp/a", txt1, -1, error))
66 return FALSE;
67 if (!g_file_set_contents ("/tmp/b", txt2, -1, error))
68 return FALSE;
69 if (!g_spawn_command_line_sync ("diff -urNp /tmp/b /tmp/a",
70 &output, NULL, NULL, error))
71 return FALSE;
72
73 /* just output the diff */
74 g_set_error_literal (error, 1, 0, output);
75 return FALSE;
76 }
77
78 static gchar *
79 _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2)
80 {
81 const guint8 *data1;
82 const guint8 *data2;
83 gsize length1;
84 gsize length2;
85 guint i;
86
87 data1 = g_bytes_get_data (bytes1, &length1);
88 data2 = g_bytes_get_data (bytes2, &length2);
89
90 /* not the same length */
91 if (length1 != length2) {
92 return g_strdup_printf ("got %" G_GSIZE_FORMAT " bytes, "
93 "expected %" G_GSIZE_FORMAT,
94 length1, length2);
95 }
96
97 /* return 00 01 02 03 */
98 for (i = 0; i < length1; i++) {
99 if (data1[i] != data2[i]) {
100 return g_strdup_printf ("got 0x%02x, expected 0x%02x @ 0x%04x",
101 data1[i], data2[i], i);
102 }
103 }
104 return NULL;
105 }
106
107 static void
108 dfu_cipher_xtea_func (void)
109 {
110 gboolean ret;
111 guint8 buf[] = { 'H', 'i', 'y', 'a', 'D', 'a', 'v', 'e' };
112 g_autoptr(GError) error = NULL;
113
114 ret = dfu_cipher_encrypt_xtea ("test", buf, sizeof(buf), &error);
115 g_assert_no_error (error);
116 g_assert (ret);
117
118 g_assert_cmpint (buf[0], ==, 128);
119 g_assert_cmpint (buf[1], ==, 220);
120 g_assert_cmpint (buf[2], ==, 23);
121 g_assert_cmpint (buf[3], ==, 55);
122 g_assert_cmpint (buf[4], ==, 201);
123 g_assert_cmpint (buf[5], ==, 207);
124 g_assert_cmpint (buf[6], ==, 182);
125 g_assert_cmpint (buf[7], ==, 177);
126
127 ret = dfu_cipher_decrypt_xtea ("test", buf, sizeof(buf), &error);
128 g_assert_no_error (error);
129 g_assert (ret);
130
131 g_assert_cmpint (buf[0], ==, 'H');
132 g_assert_cmpint (buf[1], ==, 'i');
133 g_assert_cmpint (buf[2], ==, 'y');
134 g_assert_cmpint (buf[3], ==, 'a');
135 g_assert_cmpint (buf[4], ==, 'D');
136 g_assert_cmpint (buf[5], ==, 'a');
137 g_assert_cmpint (buf[6], ==, 'v');
138 g_assert_cmpint (buf[7], ==, 'e');
139 }
140
141 static void
142 dfu_firmware_xdfu_func (void)
143 {
144 gboolean ret;
145 g_autofree gchar *fn = NULL;
146 g_autoptr(DfuFirmware) firmware = NULL;
147 g_autoptr(GError) error = NULL;
148 g_autoptr(GFile) file = NULL;
149
150 fn = dfu_test_get_filename ("example.xdfu");
151 g_assert (fn != NULL);
152 firmware = dfu_firmware_new ();
153 file = g_file_new_for_path (fn);
154 ret = dfu_firmware_parse_file (firmware, file,
155 DFU_FIRMWARE_PARSE_FLAG_NONE,
156 NULL, &error);
157 g_assert_no_error (error);
158 g_assert (ret);
159 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_XTEA);
160 }
161
162 static void
163 dfu_enums_func (void)
164 {
165 guint i;
166 for (i = 0; i < DFU_STATE_LAST; i++)
167 g_assert_cmpstr (dfu_state_to_string (i), !=, NULL);
168 for (i = 0; i < DFU_STATUS_LAST; i++)
169 g_assert_cmpstr (dfu_status_to_string (i), !=, NULL);
170 }
171
172 static GBytes *
173 dfu_self_test_get_bytes_for_file (GFile *file, GError **error)
174 {
175 gchar *contents = NULL;
176 gsize length = 0;
177 if (!g_file_load_contents (file, NULL, &contents, &length, NULL, error))
178 return NULL;
179 return g_bytes_new_take (contents, length);
180 }
181
182 static void
183 dfu_firmware_raw_func (void)
184 {
185 DfuElement *element;
186 DfuImage *image_tmp;
187 GBytes *no_suffix_contents;
188 gchar buf[256];
189 guint i;
190 gboolean ret;
191 g_autoptr(DfuFirmware) firmware = NULL;
192 g_autoptr(GBytes) fw = NULL;
193 g_autoptr(GBytes) roundtrip = NULL;
194 g_autoptr(GError) error = NULL;
195
196 /* set up some dummy data */
197 for (i = 0; i < 256; i++)
198 buf[i] = (gchar) i;
199 fw = g_bytes_new_static (buf, 256);
200
201 /* load a non DFU firmware */
202 firmware = dfu_firmware_new ();
203 ret = dfu_firmware_parse_data (firmware, fw, DFU_FIRMWARE_PARSE_FLAG_NONE, &error);
204 g_assert_no_error (error);
205 g_assert (ret);
206 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0xffff);
207 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xffff);
208 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff);
209 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_RAW);
210 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
211 image_tmp = dfu_firmware_get_image (firmware, 0xfe);
212 g_assert (image_tmp == NULL);
213 image_tmp = dfu_firmware_get_image (firmware, 0);
214 g_assert (image_tmp != NULL);
215 g_assert_cmpint (dfu_image_get_size (image_tmp), ==, 256);
216 element = dfu_image_get_element (image_tmp, 0);
217 g_assert (element != NULL);
218 no_suffix_contents = dfu_element_get_contents (element);
219 g_assert (no_suffix_contents != NULL);
220 g_assert_cmpint (g_bytes_compare (no_suffix_contents, fw), ==, 0);
221
222 /* can we roundtrip without adding data */
223 roundtrip = dfu_firmware_write_data (firmware, &error);
224 g_assert_no_error (error);
225 g_assert (roundtrip != NULL);
226 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, fw), ==, NULL);
227 }
228
229 static void
230 dfu_firmware_dfu_func (void)
231 {
232 gchar buf[256];
233 guint i;
234 gboolean ret;
235 g_autofree gchar *filename = NULL;
236 g_autoptr(DfuFirmware) firmware = NULL;
237 g_autoptr(DfuImage) image = NULL;
238 g_autoptr(DfuElement) element = NULL;
239 g_autoptr(GBytes) data = NULL;
240 g_autoptr(GBytes) fw = NULL;
241 g_autoptr(GBytes) roundtrip_orig = NULL;
242 g_autoptr(GBytes) roundtrip = NULL;
243 g_autoptr(GError) error = NULL;
244 g_autoptr(GFile) file = NULL;
245
246 /* set up some dummy data */
247 for (i = 0; i < 256; i++)
248 buf[i] = (gchar) i;
249 fw = g_bytes_new_static (buf, 256);
250
251 /* write DFU format */
252 firmware = dfu_firmware_new ();
253 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU);
254 dfu_firmware_set_vid (firmware, 0x1234);
255 dfu_firmware_set_pid (firmware, 0x5678);
256 dfu_firmware_set_release (firmware, 0xfedc);
257 image = dfu_image_new ();
258 element = dfu_element_new ();
259 dfu_element_set_contents (element, fw);
260 dfu_image_add_element (image, element);
261 dfu_firmware_add_image (firmware, image);
262 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 256);
263 data = dfu_firmware_write_data (firmware, &error);
264 g_assert_no_error (error);
265 g_assert (data != NULL);
266
267 /* can we load it again? */
268 g_ptr_array_set_size (dfu_firmware_get_images (firmware), 0);
269 ret = dfu_firmware_parse_data (firmware, data, DFU_FIRMWARE_PARSE_FLAG_NONE, &error);
270 g_assert_no_error (error);
271 g_assert (ret);
272 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x1234);
273 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0x5678);
274 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xfedc);
275 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFU);
276 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 256);
277
278 /* load a real firmware */
279 filename = dfu_test_get_filename ("kiibohd.dfu.bin");
280 g_assert (filename != NULL);
281 file = g_file_new_for_path (filename);
282 g_ptr_array_set_size (dfu_firmware_get_images (firmware), 0);
283 ret = dfu_firmware_parse_file (firmware, file,
284 DFU_FIRMWARE_PARSE_FLAG_NONE,
285 NULL, &error);
286 g_assert_no_error (error);
287 g_assert (ret);
288 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x1c11);
289 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xb007);
290 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff);
291 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFU);
292 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x8eB4);
293 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
294
295 /* can we roundtrip without loosing data */
296 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
297 g_assert_no_error (error);
298 g_assert (roundtrip_orig != NULL);
299 roundtrip = dfu_firmware_write_data (firmware, &error);
300 g_assert_no_error (error);
301 g_assert (roundtrip != NULL);
302 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
303 }
304
305 static void
306 dfu_firmware_dfuse_func (void)
307 {
308 gboolean ret;
309 g_autofree gchar *filename = NULL;
310 g_autoptr(DfuFirmware) firmware = NULL;
311 g_autoptr(GBytes) roundtrip_orig = NULL;
312 g_autoptr(GBytes) roundtrip = NULL;
313 g_autoptr(GError) error = NULL;
314 g_autoptr(GFile) file = NULL;
315
316 /* load a DeFUse firmware */
317 g_setenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME", "", FALSE);
318 filename = dfu_test_get_filename ("dev_VRBRAIN.dfu");
319 g_assert (filename != NULL);
320 file = g_file_new_for_path (filename);
321 firmware = dfu_firmware_new ();
322 ret = dfu_firmware_parse_file (firmware, file,
323 DFU_FIRMWARE_PARSE_FLAG_NONE,
324 NULL, &error);
325 g_assert_no_error (error);
326 g_assert (ret);
327 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x0483);
328 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0x0000);
329 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0x0000);
330 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFUSE);
331 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x168d5);
332 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
333
334 /* can we roundtrip without loosing data */
335 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
336 g_assert_no_error (error);
337 g_assert (roundtrip_orig != NULL);
338 roundtrip = dfu_firmware_write_data (firmware, &error);
339 g_assert_no_error (error);
340 g_assert (roundtrip != NULL);
341
342 // g_file_set_contents ("/tmp/1.bin",
343 // g_bytes_get_data (roundtrip, NULL),
344 // g_bytes_get_size (roundtrip), NULL);
345
346 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
347
348 /* use usual image name copying */
349 g_unsetenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME");
350 }
351
352 static void
353 dfu_firmware_metadata_func (void)
354 {
355 gboolean ret;
356 g_autofree gchar *filename = NULL;
357 g_autoptr(DfuFirmware) firmware = NULL;
358 g_autoptr(GBytes) roundtrip_orig = NULL;
359 g_autoptr(GBytes) roundtrip = NULL;
360 g_autoptr(GError) error = NULL;
361 g_autoptr(GFile) file = NULL;
362
363 /* load a DFU firmware with a metadata table */
364 filename = dfu_test_get_filename ("metadata.dfu");
365 g_assert (filename != NULL);
366 file = g_file_new_for_path (filename);
367 firmware = dfu_firmware_new ();
368 ret = dfu_firmware_parse_file (firmware, file,
369 DFU_FIRMWARE_PARSE_FLAG_NONE,
370 NULL, &error);
371 g_assert_no_error (error);
372 g_assert (ret);
373 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 6);
374 g_assert_cmpstr (dfu_firmware_get_metadata (firmware, "key"), ==, "value");
375 g_assert_cmpstr (dfu_firmware_get_metadata (firmware, "???"), ==, NULL);
376
377 /* can we roundtrip without loosing data */
378 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
379 g_assert_no_error (error);
380 g_assert (roundtrip_orig != NULL);
381 roundtrip = dfu_firmware_write_data (firmware, &error);
382 g_assert_no_error (error);
383 g_assert (roundtrip != NULL);
384
385 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
386 }
387
388 static void
389 dfu_firmware_elf_func (void)
390 {
391 DfuElement *element;
392 DfuImage *image;
393 GBytes *contents;
394 const gchar *data;
395 gboolean ret;
396 g_autofree gchar *filename = NULL;
397 g_autoptr(DfuFirmware) firmware = NULL;
398 g_autoptr(GBytes) roundtrip_orig = NULL;
399 g_autoptr(GBytes) roundtrip = NULL;
400 g_autoptr(GError) error = NULL;
401 g_autoptr(GFile) file = NULL;
402
403 #ifndef HAVE_LIBELF
404 g_test_skip ("compiled without libelf support");
405 return;
406 #endif
407
408 /* load a ELF firmware */
409 filename = dfu_test_get_filename ("example.elf");
410 g_assert (filename != NULL);
411 file = g_file_new_for_path (filename);
412 firmware = dfu_firmware_new ();
413 ret = dfu_firmware_parse_file (firmware, file,
414 DFU_FIRMWARE_PARSE_FLAG_NONE,
415 NULL, &error);
416 g_assert_no_error (error);
417 g_assert (ret);
418 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0xffff);
419 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xffff);
420 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff);
421 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_ELF);
422 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x0c);
423 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
424
425 /* check the data */
426 image = dfu_firmware_get_image_default (firmware);
427 g_assert (image != NULL);
428 element = dfu_image_get_element_default (image);
429 g_assert (element != NULL);
430 contents = dfu_element_get_contents (element);
431 g_assert (contents != NULL);
432 g_assert_cmpint (g_bytes_get_size (contents), ==, 12);
433 data = g_bytes_get_data (contents, NULL);
434 g_assert (data != NULL);
435 g_assert (memcmp (data, "hello world\n", 12) == 0);
436
437 /* can we roundtrip without loosing data */
438 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
439 g_assert_no_error (error);
440 g_assert (roundtrip_orig != NULL);
441 roundtrip = dfu_firmware_write_data (firmware, &error);
442 g_assert_no_error (error);
443 g_assert (roundtrip != NULL);
444
445 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
446 }
447
448 static void
449 dfu_firmware_intel_hex_func (void)
450 {
451 const guint8 *data;
452 gboolean ret;
453 gsize len;
454 g_autofree gchar *filename_hex = NULL;
455 g_autofree gchar *filename_ref = NULL;
456 g_autofree gchar *str = NULL;
457 g_autoptr(DfuFirmware) firmware = NULL;
458 g_autoptr(GBytes) data_bin2 = NULL;
459 g_autoptr(GBytes) data_bin = NULL;
460 g_autoptr(GBytes) data_hex = NULL;
461 g_autoptr(GBytes) data_ref = NULL;
462 g_autoptr(GError) error = NULL;
463 g_autoptr(GFile) file_bin = NULL;
464 g_autoptr(GFile) file_hex = NULL;
465
466 /* load a Intel hex32 file */
467 filename_hex = dfu_test_get_filename ("firmware.hex");
468 g_assert (filename_hex != NULL);
469 file_hex = g_file_new_for_path (filename_hex);
470 firmware = dfu_firmware_new ();
471 ret = dfu_firmware_parse_file (firmware, file_hex,
472 DFU_FIRMWARE_PARSE_FLAG_NONE,
473 NULL, &error);
474 g_assert_no_error (error);
475 g_assert (ret);
476 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 136);
477 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
478 data_bin = dfu_firmware_write_data (firmware, &error);
479 g_assert_no_error (error);
480 g_assert (data_bin != NULL);
481
482 /* did we match the reference file? */
483 filename_ref = dfu_test_get_filename ("firmware.bin");
484 g_assert (filename_ref != NULL);
485 file_bin = g_file_new_for_path (filename_ref);
486 data_ref = dfu_self_test_get_bytes_for_file (file_bin, &error);
487 g_assert_no_error (error);
488 g_assert (data_ref != NULL);
489 g_assert_cmpstr (_g_bytes_compare_verbose (data_bin, data_ref), ==, NULL);
490
491 /* export a ihex file (which will be slightly different due to
492 * non-continous regions being expanded */
493 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
494 data_hex = dfu_firmware_write_data (firmware, &error);
495 g_assert_no_error (error);
496 g_assert (data_hex != NULL);
497 data = g_bytes_get_data (data_hex, &len);
498 str = g_strndup ((const gchar *) data, len);
499 g_assert_cmpstr (str, ==,
500 ":104000003DEF20F000000000FACF01F0FBCF02F0AF\n"
501 ":10401000E9CF03F0EACF04F0E1CF05F0E2CF06F005\n"
502 ":10402000D9CF07F0DACF08F0F3CF09F0F4CF0AF021\n"
503 ":10403000F6CF0BF0F7CF0CF0F8CF0DF0F5CF0EF044\n"
504 ":104040000EC0F5FF0DC0F8FF0CC0F7FF0BC0F6FF45\n"
505 ":104050000AC0F4FF09C0F3FF08C0DAFF07C0D9FF24\n"
506 ":1040600006C0E2FF05C0E1FF04C0EAFF03C0E9FF0A\n"
507 ":1040700002C0FBFF01C0FAFF11003FEF20F00001BB\n"
508 ":0840800042EF20F03DEF20F037\n"
509 ":00000001FF\n");
510
511 /* do we match the binary file again */
512 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
513 data_bin2 = dfu_firmware_write_data (firmware, &error);
514 g_assert_no_error (error);
515 g_assert (data_bin2 != NULL);
516 g_assert_cmpstr (_g_bytes_compare_verbose (data_bin, data_bin2), ==, NULL);
517 }
518
519 static void
520 dfu_firmware_intel_hex_signed_func (void)
521 {
522 DfuElement *element;
523 DfuImage *image;
524 GBytes *data_sig;
525 const guint8 *data;
526 gboolean ret;
527 gsize len;
528 g_autofree gchar *filename_hex = NULL;
529 g_autoptr(DfuFirmware) firmware = NULL;
530 g_autoptr(GError) error = NULL;
531 g_autoptr(GFile) file_hex = NULL;
532
533 /* load a Intel hex32 file */
534 filename_hex = dfu_test_get_filename ("firmware.shex");
535 g_assert (filename_hex != NULL);
536 file_hex = g_file_new_for_path (filename_hex);
537 firmware = dfu_firmware_new ();
538 ret = dfu_firmware_parse_file (firmware, file_hex,
539 DFU_FIRMWARE_PARSE_FLAG_NONE,
540 NULL, &error);
541 g_assert_no_error (error);
542 g_assert (ret);
543 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 144);
544
545 /* get the signed image element */
546 image = dfu_firmware_get_image_by_name (firmware, "signature");
547 g_assert (image != NULL);
548 element = dfu_image_get_element_default (image);
549 data_sig = dfu_element_get_contents (element);
550 g_assert (data_sig != NULL);
551 data = g_bytes_get_data (data_sig, &len);
552 g_assert_cmpint (len, ==, 8);
553 g_assert (data != NULL);
554 }
555
556 static void
557 dfu_device_func (void)
558 {
559 GPtrArray *targets;
560 gboolean ret;
561 g_autoptr(DfuDevice) device = NULL;
562 g_autoptr(DfuTarget) target1 = NULL;
563 g_autoptr(DfuTarget) target2 = NULL;
564 g_autoptr(GError) error = NULL;
565 g_autoptr(GUsbContext) usb_ctx = NULL;
566 g_autoptr(GUsbDevice) usb_device = NULL;
567
568 /* find any DFU in appIDLE mode */
569 usb_ctx = g_usb_context_new (&error);
570 g_assert_no_error (error);
571 g_assert (usb_ctx != NULL);
572 g_usb_context_enumerate (usb_ctx);
573 usb_device = g_usb_context_find_by_vid_pid (usb_ctx,
574 0x273f,
575 0x1005,
576 &error);
577 if (usb_device == NULL)
578 return;
579 g_assert_no_error (error);
580 g_assert (usb_device != NULL);
581
582 /* check it's DFU-capable */
583 device = dfu_device_new (usb_device);
584 g_assert (device != NULL);
585
586 /* get targets */
587 targets = dfu_device_get_targets (device);
588 g_assert_cmpint (targets->len, ==, 2);
589
590 /* get by ID */
591 target1 = dfu_device_get_target_by_alt_setting (device, 1, &error);
592 g_assert_no_error (error);
593 g_assert (target1 != NULL);
594
595 /* ensure open */
596 ret = dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE, NULL, &error);
597 g_assert_no_error (error);
598 g_assert (ret);
599
600 /* get by name */
601 target2 = dfu_device_get_target_by_alt_name (device, "sram", &error);
602 g_assert_no_error (error);
603 g_assert (target2 != NULL);
604
605 /* close */
606 ret = dfu_device_close (device, &error);
607 g_assert_no_error (error);
608 g_assert (ret);
609 }
610
611 static void
612 dfu_colorhug_plus_func (void)
613 {
614 GPtrArray *elements;
615 gboolean ret;
616 gboolean seen_app_idle = FALSE;
617 g_autoptr(DfuContext) context = NULL;
618 g_autoptr(DfuDevice) device = NULL;
619 g_autoptr(DfuDevice) device2 = NULL;
620 g_autoptr(DfuTarget) target = NULL;
621 g_autoptr(DfuImage) image = NULL;
622 g_autoptr(GError) error = NULL;
623
624 /* create context */
625 context = dfu_context_new ();
626 ret = dfu_context_enumerate (context, &error);
627 g_assert_no_error (error);
628 g_assert (ret);
629
630 /* push appIDLE into dfuIDLE */
631 device2 = dfu_context_get_device_by_vid_pid (context,
632 0x273f,
633 0x1002,
634 NULL);
635 if (device2 != NULL) {
636 ret = dfu_device_open (device2, DFU_DEVICE_OPEN_FLAG_NONE, NULL, &error);
637 g_assert_no_error (error);
638 g_assert (ret);
639 ret = dfu_device_detach (device2, NULL, &error);
640 g_assert_no_error (error);
641 g_assert (ret);
642
643 /* wait for it to come back as 273f:1005 */
644 ret = dfu_device_wait_for_replug (device2, 5000, NULL, &error);
645 g_assert_no_error (error);
646 g_assert (ret);
647
648 /* close it */
649 ret = dfu_device_close (device2, &error);
650 g_assert_no_error (error);
651 g_assert (ret);
652 }
653
654 /* find any DFU in dfuIDLE mode */
655 device = dfu_context_get_device_by_vid_pid (context,
656 0x273f,
657 0x1003,
658 NULL);
659 if (device == NULL)
660 return;
661
662 /* we don't know this unless we went from appIDLE -> dfuIDLE */
663 if (device2 == NULL) {
664 g_assert_cmpint (dfu_device_get_runtime_vid (device), ==, 0xffff);
665 g_assert_cmpint (dfu_device_get_runtime_pid (device), ==, 0xffff);
666 }
667
668 /* open it */
669 ret = dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE, NULL, &error);
670 g_assert_no_error (error);
671 g_assert (ret);
672
673 /* is in dfuIDLE mode */
674 g_assert_cmpstr (dfu_state_to_string (dfu_device_get_state (device)), ==, "dfuIDLE");
675
676 /* lets try and flash something inappropriate */
677 if (seen_app_idle) {
678 g_autoptr(DfuFirmware) firmware = NULL;
679 g_autoptr(GFile) file = NULL;
680 g_autofree gchar *filename = NULL;
681
682 filename = dfu_test_get_filename ("kiibohd.dfu.bin");
683 g_assert (filename != NULL);
684 file = g_file_new_for_path (filename);
685 firmware = dfu_firmware_new ();
686 ret = dfu_firmware_parse_file (firmware, file,
687 DFU_FIRMWARE_PARSE_FLAG_NONE,
688 NULL, &error);
689 g_assert_no_error (error);
690 g_assert (ret);
691 ret = dfu_device_download (device, firmware,
692 DFU_TARGET_TRANSFER_FLAG_DETACH |
693 DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME,
694 NULL, &error);
695 g_assert_error (error,
696 DFU_ERROR,
697 DFU_ERROR_INTERNAL);
698 g_assert (ret);
699 g_clear_error (&error);
700 }
701
702 /* get a dump of the existing firmware */
703 target = dfu_device_get_target_by_alt_setting (device, 0, &error);
704 g_assert_no_error (error);
705 g_assert (target != NULL);
706 image = dfu_target_upload (target, DFU_TARGET_TRANSFER_FLAG_NONE,
707 NULL, &error);
708 g_assert_no_error (error);
709 g_assert (DFU_IS_IMAGE (image));
710 elements = dfu_image_get_elements (image);
711 g_assert (elements != NULL);
712 g_assert_cmpint (elements->len, ==, 1);
713
714 /* download a new firmware */
715 ret = dfu_target_download (target, image,
716 DFU_TARGET_TRANSFER_FLAG_VERIFY |
717 DFU_TARGET_TRANSFER_FLAG_ATTACH,
718 NULL, &error);
719 g_assert_no_error (error);
720 g_assert (ret);
721
722 /* wait for it to come back as 273f:1004 */
723 ret = dfu_device_wait_for_replug (device, 5000, NULL, &error);
724 g_assert_no_error (error);
725 g_assert (ret);
726
727 /* we should know now */
728 g_assert_cmpint (dfu_device_get_runtime_vid (device), ==, 0x273f);
729 g_assert_cmpint (dfu_device_get_runtime_pid (device), ==, 0x1002);
730 }
731
732 static gchar *
733 dfu_target_sectors_to_string (DfuTarget *target)
734 {
735 DfuSector *sector;
736 GPtrArray *sectors;
737 GString *str;
738 guint i;
739
740 str = g_string_new ("");
741 sectors = dfu_target_get_sectors (target);
742 for (i = 0; i < sectors->len; i++) {
743 g_autofree gchar *tmp = NULL;
744 sector = g_ptr_array_index (sectors, i);
745 tmp = dfu_sector_to_string (sector);
746 g_string_append_printf (str, "%s\n", tmp);
747 }
748 if (str->len > 0)
749 g_string_truncate (str, str->len - 1);
750 return g_string_free (str, FALSE);
751 }
752
753 static void
754 dfu_target_dfuse_func (void)
755 {
756 gboolean ret;
757 gchar *tmp;
758 g_autoptr(DfuTarget) target = NULL;
759 g_autoptr(GError) error = NULL;
760
761 /* NULL */
762 target = g_object_new (DFU_TYPE_TARGET, NULL);
763 ret = dfu_target_parse_sectors (target, NULL, &error);
764 g_assert_no_error (error);
765 g_assert (ret);
766 tmp = dfu_target_sectors_to_string (target);
767 g_assert_cmpstr (tmp, ==, "");
768 g_free (tmp);
769
770 /* no addresses */
771 ret = dfu_target_parse_sectors (target, "@Flash3", &error);
772 g_assert_no_error (error);
773 g_assert (ret);
774 tmp = dfu_target_sectors_to_string (target);
775 g_assert_cmpstr (tmp, ==, "");
776 g_free (tmp);
777
778 /* one sector, no space */
779 ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000/2*001Ka", &error);
780 g_assert_no_error (error);
781 g_assert (ret);
782 tmp = dfu_target_sectors_to_string (target);
783 ret = dfu_test_compare_lines (tmp,
784 "Zone:0, Sec#:0, Addr:0x08000000, Size:0x0400, Caps:0x1 [R]\n"
785 "Zone:0, Sec#:0, Addr:0x08000400, Size:0x0400, Caps:0x1 [R]",
786 &error);
787 g_assert_no_error (error);
788 g_assert (ret);
789 g_free (tmp);
790
791 /* multiple sectors */
792 ret = dfu_target_parse_sectors (target, "@Flash1 /0x08000000/2*001Ka,4*001Kg", &error);
793 g_assert_no_error (error);
794 g_assert (ret);
795 tmp = dfu_target_sectors_to_string (target);
796 ret = dfu_test_compare_lines (tmp,
797 "Zone:0, Sec#:0, Addr:0x08000000, Size:0x0400, Caps:0x1 [R]\n"
798 "Zone:0, Sec#:0, Addr:0x08000400, Size:0x0400, Caps:0x1 [R]\n"
799 "Zone:0, Sec#:1, Addr:0x08000800, Size:0x0400, Caps:0x7 [REW]\n"
800 "Zone:0, Sec#:1, Addr:0x08000c00, Size:0x0400, Caps:0x7 [REW]\n"
801 "Zone:0, Sec#:1, Addr:0x08001000, Size:0x0400, Caps:0x7 [REW]\n"
802 "Zone:0, Sec#:1, Addr:0x08001400, Size:0x0400, Caps:0x7 [REW]",
803 &error);
804 g_assert_no_error (error);
805 g_assert (ret);
806 g_free (tmp);
807
808 /* non-contiguous */
809 ret = dfu_target_parse_sectors (target, "@Flash2 /0xF000/4*100Ba/0xE000/3*8Kg/0x80000/2*24Kg", &error);
810 g_assert_no_error (error);
811 g_assert (ret);
812 tmp = dfu_target_sectors_to_string (target);
813 ret = dfu_test_compare_lines (tmp,
814 "Zone:0, Sec#:0, Addr:0x0000f000, Size:0x0064, Caps:0x1 [R]\n"
815 "Zone:0, Sec#:0, Addr:0x0000f064, Size:0x0064, Caps:0x1 [R]\n"
816 "Zone:0, Sec#:0, Addr:0x0000f0c8, Size:0x0064, Caps:0x1 [R]\n"
817 "Zone:0, Sec#:0, Addr:0x0000f12c, Size:0x0064, Caps:0x1 [R]\n"
818 "Zone:1, Sec#:0, Addr:0x0000e000, Size:0x2000, Caps:0x7 [REW]\n"
819 "Zone:1, Sec#:0, Addr:0x00010000, Size:0x2000, Caps:0x7 [REW]\n"
820 "Zone:1, Sec#:0, Addr:0x00012000, Size:0x2000, Caps:0x7 [REW]\n"
821 "Zone:2, Sec#:0, Addr:0x00080000, Size:0x6000, Caps:0x7 [REW]\n"
822 "Zone:2, Sec#:0, Addr:0x00086000, Size:0x6000, Caps:0x7 [REW]",
823 &error);
824 g_assert_no_error (error);
825 g_assert (ret);
826 g_free (tmp);
827
828 /* invalid */
829 ret = dfu_target_parse_sectors (target, "Flash", NULL);
830 g_assert (ret);
831 ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000", NULL);
832 g_assert (!ret);
833 ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000/12*001a", NULL);
834 g_assert (!ret);
835
836 /* indicate a cipher being used */
837 g_assert_cmpint (dfu_target_get_cipher_kind (target), ==, DFU_CIPHER_KIND_NONE);
838 ret = dfu_target_parse_sectors (target, "@Flash|XTEA", &error);
839 g_assert_no_error (error);
840 g_assert (ret);
841 g_assert_cmpint (dfu_target_get_cipher_kind (target), ==, DFU_CIPHER_KIND_XTEA);
842 }
843
844 static gboolean
845 dfu_patch_create_from_strings (DfuPatch *patch,
846 const gchar *dold,
847 const gchar *dnew,
848 GError **error)
849 {
850 guint32 sz1 = strlen (dold);
851 guint32 sz2 = strlen (dnew);
852 g_autoptr(GBytes) blob1 = g_bytes_new (dold, sz1);
853 g_autoptr(GBytes) blob2 = g_bytes_new (dnew, sz2);
854 g_debug ("compare:\n%s\n%s", dold, dnew);
855 return dfu_patch_create (patch, blob1, blob2, error);
856 }
857
858 static void
859 dfu_patch_merges_func (void)
860 {
861 const guint8 *data;
862 gboolean ret;
863 gsize sz;
864 g_autoptr(DfuPatch) patch = dfu_patch_new ();
865 g_autoptr(GBytes) blob = NULL;
866 g_autoptr(GError) error = NULL;
867
868 /* check merges happen */
869 ret = dfu_patch_create_from_strings (patch, "XXX", "YXY", &error);
870 g_assert_no_error (error);
871 g_assert (ret);
872 blob = dfu_patch_export (patch, &error);
873 g_assert_no_error (error);
874 g_assert (ret);
875 data = g_bytes_get_data (blob, &sz);
876 g_assert_cmpint (data[0x00], ==, 'D');
877 g_assert_cmpint (data[0x01], ==, 'f');
878 g_assert_cmpint (data[0x02], ==, 'u');
879 g_assert_cmpint (data[0x03], ==, 'P');
880 g_assert_cmpint (data[0x04], ==, 0x00); /* reserved */
881 g_assert_cmpint (data[0x05], ==, 0x00);
882 g_assert_cmpint (data[0x06], ==, 0x00);
883 g_assert_cmpint (data[0x07], ==, 0x00);
884 g_assert_cmpint (data[0x08 + 0x28], ==, 0x00); /* chunk1, offset */
885 g_assert_cmpint (data[0x09 + 0x28], ==, 0x00);
886 g_assert_cmpint (data[0x0a + 0x28], ==, 0x00);
887 g_assert_cmpint (data[0x0b + 0x28], ==, 0x00);
888 g_assert_cmpint (data[0x0c + 0x28], ==, 0x03); /* chunk1, size */
889 g_assert_cmpint (data[0x0d + 0x28], ==, 0x00);
890 g_assert_cmpint (data[0x0e + 0x28], ==, 0x00);
891 g_assert_cmpint (data[0x0f + 0x28], ==, 0x00);
892 g_assert_cmpint (data[0x10 + 0x28], ==, 0x00); /* reserved */
893 g_assert_cmpint (data[0x11 + 0x28], ==, 0x00);
894 g_assert_cmpint (data[0x12 + 0x28], ==, 0x00);
895 g_assert_cmpint (data[0x13 + 0x28], ==, 0x00);
896 g_assert_cmpint (data[0x14 + 0x28], ==, 'Y');
897 g_assert_cmpint (data[0x15 + 0x28], ==, 'X');
898 g_assert_cmpint (data[0x16 + 0x28], ==, 'Y');
899 g_assert_cmpint (sz, ==, 48 /* hdr */ + 12 /* chunk */ + 3 /* data */);
900 }
901
902 static void
903 dfu_patch_apply_func (void)
904 {
905 gboolean ret;
906 g_autoptr(DfuPatch) patch = dfu_patch_new ();
907 g_autoptr(GBytes) blob_new2 = NULL;
908 g_autoptr(GBytes) blob_new3 = NULL;
909 g_autoptr(GBytes) blob_new4 = NULL;
910 g_autoptr(GBytes) blob_new = NULL;
911 g_autoptr(GBytes) blob_old = NULL;
912 g_autoptr(GBytes) blob_wrong = NULL;
913 g_autoptr(GError) error = NULL;
914
915 /* create a patch */
916 blob_old = g_bytes_new_static ("helloworldhelloworldhelloworldhelloworld", 40);
917 blob_new = g_bytes_new_static ("XelloXorldhelloworldhelloworldhelloworlXXX", 42);
918 ret = dfu_patch_create (patch, blob_old, blob_new, &error);
919 g_assert_no_error (error);
920 g_assert (ret);
921
922 /* apply the patch */
923 blob_new2 = dfu_patch_apply (patch, blob_old, DFU_PATCH_APPLY_FLAG_NONE, &error);
924 g_assert_no_error (error);
925 g_assert (blob_new2 != NULL);
926 g_assert_cmpint (g_bytes_compare (blob_new, blob_new2), ==, 0);
927
928 /* check we force the patch to an unrelated blob */
929 blob_wrong = g_bytes_new_static ("wrongwrongwrongwrongwrongwrongwrongwrong", 40);
930 blob_new3 = dfu_patch_apply (patch, blob_wrong, DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM, &error);
931 g_assert_no_error (error);
932 g_assert (blob_new3 != NULL);
933
934 /* check we can't apply the patch to an unrelated blob */
935 blob_new4 = dfu_patch_apply (patch, blob_wrong, DFU_PATCH_APPLY_FLAG_NONE, &error);
936 g_assert_error (error, DFU_ERROR, DFU_ERROR_INVALID_DEVICE);
937 g_assert (blob_new4 == NULL);
938 }
939
940 static void
941 dfu_patch_func (void)
942 {
943 const guint8 *data;
944 gboolean ret;
945 gsize sz;
946 g_autoptr(DfuPatch) patch = dfu_patch_new ();
947 g_autoptr(DfuPatch) patch2 = dfu_patch_new ();
948 g_autoptr(GBytes) blob = NULL;
949 g_autoptr(GError) error = NULL;
950 g_autofree gchar *serialized_str = NULL;
951
952 /* create binary diff */
953 ret = dfu_patch_create_from_strings (patch, "XXX", "XYY", &error);
954 g_assert_no_error (error);
955 g_assert (ret);
956
957 /* check we can serialize this object to a blob */
958 blob = dfu_patch_export (patch, &error);
959 g_assert_no_error (error);
960 g_assert (ret);
961 data = g_bytes_get_data (blob, &sz);
962 g_assert_cmpint (data[0x00], ==, 'D');
963 g_assert_cmpint (data[0x01], ==, 'f');
964 g_assert_cmpint (data[0x02], ==, 'u');
965 g_assert_cmpint (data[0x03], ==, 'P');
966 g_assert_cmpint (data[0x04], ==, 0x00); /* reserved */
967 g_assert_cmpint (data[0x05], ==, 0x00);
968 g_assert_cmpint (data[0x06], ==, 0x00);
969 g_assert_cmpint (data[0x07], ==, 0x00);
970 g_assert_cmpint (data[0x08 + 0x28], ==, 0x01); /* chunk1, offset */
971 g_assert_cmpint (data[0x09 + 0x28], ==, 0x00);
972 g_assert_cmpint (data[0x0a + 0x28], ==, 0x00);
973 g_assert_cmpint (data[0x0b + 0x28], ==, 0x00);
974 g_assert_cmpint (data[0x0c + 0x28], ==, 0x02); /* chunk1, size */
975 g_assert_cmpint (data[0x0d + 0x28], ==, 0x00);
976 g_assert_cmpint (data[0x0e + 0x28], ==, 0x00);
977 g_assert_cmpint (data[0x0f + 0x28], ==, 0x00);
978 g_assert_cmpint (data[0x10 + 0x28], ==, 0x00); /* reserved */
979 g_assert_cmpint (data[0x11 + 0x28], ==, 0x00);
980 g_assert_cmpint (data[0x12 + 0x28], ==, 0x00);
981 g_assert_cmpint (data[0x13 + 0x28], ==, 0x00);
982 g_assert_cmpint (data[0x14 + 0x28], ==, 'Y');
983 g_assert_cmpint (data[0x15 + 0x28], ==, 'Y');
984 g_assert_cmpint (sz, ==, 48 /* hdr */ + 12 /* chunk */ + 2 /* data */);
985
986 /* try to load it from the serialized blob */
987 ret = dfu_patch_import (patch2, blob, &error);
988 g_assert_no_error (error);
989 g_assert (ret);
990 serialized_str = dfu_patch_to_string (patch2);
991 g_debug ("serialized blob %s", serialized_str);
992 }
993
994 int
995 main (int argc, char **argv)
996 {
997 g_test_init (&argc, &argv, NULL);
998
999 /* only critical and error are fatal */
1000 g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
1001
1002 /* log everything */
1003 g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
1004
1005 /* tests go here */
1006 g_test_add_func ("/libdfu/patch", dfu_patch_func);
1007 g_test_add_func ("/libdfu/patch{merges}", dfu_patch_merges_func);
1008 g_test_add_func ("/libdfu/patch{apply}", dfu_patch_apply_func);
1009 g_test_add_func ("/libdfu/enums", dfu_enums_func);
1010 g_test_add_func ("/libdfu/target(DfuSe}", dfu_target_dfuse_func);
1011 g_test_add_func ("/libdfu/cipher{xtea}", dfu_cipher_xtea_func);
1012 g_test_add_func ("/libdfu/firmware{raw}", dfu_firmware_raw_func);
1013 g_test_add_func ("/libdfu/firmware{dfu}", dfu_firmware_dfu_func);
1014 g_test_add_func ("/libdfu/firmware{dfuse}", dfu_firmware_dfuse_func);
1015 g_test_add_func ("/libdfu/firmware{xdfu}", dfu_firmware_xdfu_func);
1016 g_test_add_func ("/libdfu/firmware{metadata}", dfu_firmware_metadata_func);
1017 g_test_add_func ("/libdfu/firmware{intel-hex}", dfu_firmware_intel_hex_func);
1018 g_test_add_func ("/libdfu/firmware{intel-hex-signed}", dfu_firmware_intel_hex_signed_func);
1019 g_test_add_func ("/libdfu/firmware{elf}", dfu_firmware_elf_func);
1020 g_test_add_func ("/libdfu/device", dfu_device_func);
1021 g_test_add_func ("/libdfu/colorhug+", dfu_colorhug_plus_func);
1022 return g_test_run ();
1023 }
1024
+0
-52
libdfu/dfu-target-private.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_TARGET_PRIVATE_H
22 #define __DFU_TARGET_PRIVATE_H
23
24 #include <gusb.h>
25
26 #include "dfu-device.h"
27 #include "dfu-target.h"
28
29 G_BEGIN_DECLS
30
31 DfuTarget *dfu_target_new (DfuDevice *device,
32 GUsbInterface *iface);
33
34 GBytes *dfu_target_upload_chunk (DfuTarget *target,
35 guint8 index,
36 GCancellable *cancellable,
37 GError **error);
38 gboolean dfu_target_download_chunk (DfuTarget *target,
39 guint8 index,
40 GBytes *bytes,
41 GCancellable *cancellable,
42 GError **error);
43
44 /* export this just for the self tests */
45 gboolean dfu_target_parse_sectors (DfuTarget *target,
46 const gchar *alt_name,
47 GError **error);
48
49 G_END_DECLS
50
51 #endif /* __DFU_TARGET_PRIVATE_H */
+0
-1908
libdfu/dfu-target.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-target
23 * @short_description: Object representing a DFU-capable target
24 *
25 * This object allows uploading and downloading an image onto a
26 * specific DFU-capable target.
27 *
28 * You only need to use this in preference to #DfuDevice if you only
29 * want to update one target on the device. Most users will want to
30 * update all the targets on the device at the same time.
31 *
32 * See also: #DfuDevice, #DfuImage
33 */
34
35 #include "config.h"
36
37 #include <string.h>
38 #include <math.h>
39
40 #include "dfu-common.h"
41 #include "dfu-device-private.h"
42 #include "dfu-error.h"
43 #include "dfu-sector-private.h"
44 #include "dfu-target-private.h"
45
46 static void dfu_target_finalize (GObject *object);
47
48 typedef enum {
49 DFU_CMD_DFUSE_GET_COMMAND = 0x00,
50 DFU_CMD_DFUSE_SET_ADDRESS_POINTER = 0x21,
51 DFU_CMD_DFUSE_ERASE = 0x41,
52 DFU_CMD_DFUSE_READ_UNPROTECT = 0x92,
53 DFU_CMD_DFUSE_LAST
54 } DfuCmdDfuse;
55
56 typedef struct {
57 DfuDevice *device; /* not refcounted */
58 DfuCipherKind cipher_kind;
59 gboolean done_setup;
60 guint8 alt_setting;
61 guint8 alt_idx;
62 gchar *alt_name;
63 gchar *alt_name_for_display;
64 GPtrArray *sectors; /* of DfuSector */
65 guint old_percentage;
66 DfuAction old_action;
67 } DfuTargetPrivate;
68
69 enum {
70 SIGNAL_PERCENTAGE_CHANGED,
71 SIGNAL_ACTION_CHANGED,
72 SIGNAL_LAST
73 };
74
75 static guint signals [SIGNAL_LAST] = { 0 };
76
77 G_DEFINE_TYPE_WITH_PRIVATE (DfuTarget, dfu_target, G_TYPE_OBJECT)
78 #define GET_PRIVATE(o) (dfu_target_get_instance_private (o))
79
80 static void
81 dfu_target_class_init (DfuTargetClass *klass)
82 {
83 GObjectClass *object_class = G_OBJECT_CLASS (klass);
84
85 /**
86 * DfuTarget::percentage-changed:
87 * @device: the #DfuTarget instance that emitted the signal
88 * @percentage: the new percentage
89 *
90 * The ::percentage-changed signal is emitted when the percentage changes.
91 *
92 * Since: 0.5.4
93 **/
94 signals [SIGNAL_PERCENTAGE_CHANGED] =
95 g_signal_new ("percentage-changed",
96 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
97 G_STRUCT_OFFSET (DfuTargetClass, percentage_changed),
98 NULL, NULL, g_cclosure_marshal_VOID__UINT,
99 G_TYPE_NONE, 1, G_TYPE_UINT);
100
101 /**
102 * DfuTarget::action-changed:
103 * @device: the #DfuTarget instance that emitted the signal
104 * @action: the new DfuAction
105 *
106 * The ::action-changed signal is emitted when the high level action changes.
107 *
108 * Since: 0.7.5
109 **/
110 signals [SIGNAL_ACTION_CHANGED] =
111 g_signal_new ("action-changed",
112 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
113 G_STRUCT_OFFSET (DfuTargetClass, action_changed),
114 NULL, NULL, g_cclosure_marshal_VOID__UINT,
115 G_TYPE_NONE, 1, G_TYPE_UINT);
116
117 object_class->finalize = dfu_target_finalize;
118 }
119
120 static void
121 dfu_target_init (DfuTarget *target)
122 {
123 DfuTargetPrivate *priv = GET_PRIVATE (target);
124 priv->sectors = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
125 priv->old_percentage = G_MAXUINT;
126 priv->old_action = DFU_ACTION_IDLE;
127 }
128
129 static void
130 dfu_target_finalize (GObject *object)
131 {
132 DfuTarget *target = DFU_TARGET (object);
133 DfuTargetPrivate *priv = GET_PRIVATE (target);
134
135 g_free (priv->alt_name);
136 g_free (priv->alt_name_for_display);
137 g_ptr_array_unref (priv->sectors);
138
139 /* we no longer care */
140 if (priv->device != NULL) {
141 g_object_remove_weak_pointer (G_OBJECT (priv->device),
142 (gpointer *) &priv->device);
143 }
144
145 G_OBJECT_CLASS (dfu_target_parent_class)->finalize (object);
146 }
147
148 static gchar *
149 dfu_target_sectors_to_string (DfuTarget *target)
150 {
151 DfuTargetPrivate *priv = GET_PRIVATE (target);
152 DfuSector *sector;
153 GString *str;
154 guint i;
155
156 str = g_string_new ("");
157 for (i = 0; i < priv->sectors->len; i++) {
158 g_autofree gchar *tmp = NULL;
159 sector = g_ptr_array_index (priv->sectors, i);
160 tmp = dfu_sector_to_string (sector);
161 g_string_append_printf (str, "%s\n", tmp);
162 }
163 if (str->len > 0)
164 g_string_truncate (str, str->len - 1);
165 return g_string_free (str, FALSE);
166 }
167
168 static DfuSector *
169 dfu_target_get_sector_for_addr (DfuTarget *target, guint32 addr)
170 {
171 DfuTargetPrivate *priv = GET_PRIVATE (target);
172 DfuSector *sector;
173 guint i;
174
175 for (i = 0; i < priv->sectors->len; i++) {
176 sector = g_ptr_array_index (priv->sectors, i);
177 if (addr < dfu_sector_get_address (sector))
178 continue;
179 if (addr > dfu_sector_get_address (sector) +
180 dfu_sector_get_size (sector))
181 continue;
182 return sector;
183 }
184 return NULL;
185 }
186
187 static gboolean
188 dfu_target_parse_sector (DfuTarget *target,
189 const gchar *dfuse_sector_id,
190 guint32 *addr,
191 guint16 zone,
192 guint16 number,
193 GError **error)
194 {
195 DfuTargetPrivate *priv = GET_PRIVATE (target);
196 DfuSectorCap cap = DFU_SECTOR_CAP_NONE;
197 gchar *tmp;
198 guint32 addr_offset = 0;
199 guint64 nr_sectors;
200 guint64 sector_size;
201 guint i;
202
203 /* parse # of sectors */
204 nr_sectors = g_ascii_strtoull (dfuse_sector_id, &tmp, 10);
205 if (nr_sectors > 999) {
206 g_set_error (error,
207 DFU_ERROR,
208 DFU_ERROR_NOT_SUPPORTED,
209 "Invalid number of sectors: %s",
210 dfuse_sector_id);
211 return FALSE;
212 }
213
214 /* check this is the delimiter */
215 if (tmp[0] != '*') {
216 g_set_error (error,
217 DFU_ERROR,
218 DFU_ERROR_NOT_SUPPORTED,
219 "Invalid sector ID: %s",
220 dfuse_sector_id);
221 return FALSE;
222 }
223
224 /* parse sector size */
225 sector_size = g_ascii_strtoull (tmp + 1, &tmp, 10);
226 if (sector_size > 999) {
227 g_set_error (error,
228 DFU_ERROR,
229 DFU_ERROR_NOT_SUPPORTED,
230 "Invalid sector size: %s",
231 dfuse_sector_id);
232 return FALSE;
233 }
234
235 /* get multiplier */
236 switch (tmp[0]) {
237 case 'B': /* byte */
238 case ' ': /* byte, ST reference bootloader :/ */
239 break;
240 case 'K': /* Kilo */
241 sector_size *= 0x400;
242 break;
243 case 'M': /* Mega */
244 sector_size *= 0x100000 ;
245 break;
246 default:
247 g_set_error (error,
248 DFU_ERROR,
249 DFU_ERROR_NOT_SUPPORTED,
250 "Invalid sector multiplier: %s",
251 tmp);
252 return FALSE;
253 }
254
255 /* get sector type */
256 switch (tmp[1]) {
257 case 'a':
258 cap = DFU_SECTOR_CAP_READABLE;
259 break;
260 case 'b':
261 cap = DFU_SECTOR_CAP_ERASEABLE;
262 break;
263 case 'c':
264 cap = DFU_SECTOR_CAP_READABLE |
265 DFU_SECTOR_CAP_ERASEABLE;
266 break;
267 case 'd':
268 cap = DFU_SECTOR_CAP_WRITEABLE;
269 break;
270 case 'e':
271 cap = DFU_SECTOR_CAP_READABLE |
272 DFU_SECTOR_CAP_WRITEABLE;
273 break;
274 case 'f':
275 cap = DFU_SECTOR_CAP_ERASEABLE |
276 DFU_SECTOR_CAP_WRITEABLE;
277 break;
278 case 'g':
279 cap = DFU_SECTOR_CAP_READABLE |
280 DFU_SECTOR_CAP_ERASEABLE |
281 DFU_SECTOR_CAP_WRITEABLE;
282 break;
283 default:
284 g_set_error (error,
285 DFU_ERROR,
286 DFU_ERROR_NOT_SUPPORTED,
287 "Invalid sector type: %s",
288 tmp);
289 return FALSE;
290 }
291
292 /* add all the sectors */
293 for (i = 0; i < nr_sectors; i++) {
294 DfuSector *sector;
295 sector = dfu_sector_new (*addr + addr_offset,
296 (guint32) sector_size,
297 (guint32) ((nr_sectors * sector_size) - addr_offset),
298 zone,
299 number,
300 cap);
301 g_ptr_array_add (priv->sectors, sector);
302 addr_offset += dfu_sector_get_size (sector);
303 }
304
305 /* update for next sector */
306 *addr += addr_offset;
307 return TRUE;
308 }
309
310 gboolean
311 dfu_target_parse_sectors (DfuTarget *target, const gchar *alt_name, GError **error)
312 {
313 DfuTargetPrivate *priv = GET_PRIVATE (target);
314 g_autofree gchar *str_debug = NULL;
315 g_auto(GStrv) zones = NULL;
316
317 /* not set */
318 if (alt_name == NULL)
319 return TRUE;
320
321 /* do we have any hint for the cipher */
322 if (g_strstr_len (alt_name, -1, "|XTEA") != NULL)
323 priv->cipher_kind = DFU_CIPHER_KIND_XTEA;
324
325 /* From the Neo Freerunner */
326 if (g_str_has_prefix (alt_name, "RAM 0x")) {
327 DfuSector *sector;
328 guint64 addr_tmp;
329 addr_tmp = g_ascii_strtoull (alt_name + 6, NULL, 16);
330 if (addr_tmp == 0 || addr_tmp > G_MAXUINT32)
331 return FALSE;
332 g_debug ("RAM description, so parsing");
333 sector = dfu_sector_new ((guint32) addr_tmp,
334 0x0, /* size */
335 0x0, /* size_left */
336 0x0, /* zone */
337 0x0, /* number */
338 DFU_SECTOR_CAP_READABLE |
339 DFU_SECTOR_CAP_WRITEABLE);
340 g_ptr_array_add (priv->sectors, sector);
341 }
342
343 /* not a DfuSe alternative name */
344 if (alt_name[0] != '@')
345 return TRUE;
346
347 /* clear any existing zones */
348 g_ptr_array_set_size (priv->sectors, 0);
349
350 /* parse zones */
351 zones = g_strsplit (alt_name, "/", -1);
352 g_free (priv->alt_name_for_display);
353 priv->alt_name_for_display = g_strdup (g_strchomp (zones[0] + 1));
354 for (guint i = 1; zones[i] != NULL; i += 2) {
355 guint32 addr;
356 guint64 addr_tmp;
357 g_auto(GStrv) sectors = NULL;
358
359 /* parse address */
360 if (!g_str_has_prefix (zones[i], "0x")) {
361 g_set_error_literal (error,
362 DFU_ERROR,
363 DFU_ERROR_NOT_SUPPORTED,
364 "No sector address");
365 return FALSE;
366 }
367 addr_tmp = g_ascii_strtoull (zones[i] + 2, NULL, 16);
368 if (addr_tmp > G_MAXUINT32) {
369 g_set_error_literal (error,
370 DFU_ERROR,
371 DFU_ERROR_NOT_SUPPORTED,
372 "Sector address too large");
373 return FALSE;
374 }
375 addr = (guint32) addr_tmp;
376
377 /* no sectors?! */
378 if (zones[i+1] == NULL) {
379 g_set_error_literal (error,
380 DFU_ERROR,
381 DFU_ERROR_NOT_SUPPORTED,
382 "No sector section");
383 return FALSE;
384 }
385
386 /* parse sectors */
387 sectors = g_strsplit (zones[i+1], ",", -1);
388 for (guint16 j = 0; sectors[j] != NULL; j++) {
389 if (!dfu_target_parse_sector (target,
390 sectors[j],
391 &addr,
392 (i - 1) / 2, j,
393 error)) {
394 g_prefix_error (error,
395 "Failed to parse: '%s': ",
396 sectors[j]);
397 return FALSE;
398 }
399 }
400 }
401
402 /* success */
403 str_debug = dfu_target_sectors_to_string (target);
404 g_debug ("%s", str_debug);
405 return TRUE;
406 }
407
408 /**
409 * dfu_target_new: (skip)
410 * @device: a #DfuDevice
411 * @iface: a #GUsbInterface
412 *
413 * Creates a new DFU target, which represents an alt-setting on a
414 * DFU-capable device.
415 *
416 * Return value: a #DfuTarget, or %NULL if @iface was not DFU-capable
417 *
418 * Since: 0.5.4
419 **/
420 DfuTarget *
421 dfu_target_new (DfuDevice *device, GUsbInterface *iface)
422 {
423 DfuTargetPrivate *priv;
424 DfuTarget *target;
425 target = g_object_new (DFU_TYPE_TARGET, NULL);
426 priv = GET_PRIVATE (target);
427 priv->device = device;
428 priv->alt_idx = g_usb_interface_get_index (iface);
429 priv->alt_setting = g_usb_interface_get_alternate (iface);
430
431 /* if we try to ref the target and destroy the device */
432 g_object_add_weak_pointer (G_OBJECT (priv->device),
433 (gpointer *) &priv->device);
434
435 return target;
436 }
437
438 /**
439 * dfu_target_get_sectors:
440 * @target: a #GUsbDevice
441 *
442 * Gets the sectors exported by the device.
443 *
444 * Return value: (transfer none) (element-type DfuSector): sectors
445 *
446 * Since: 0.5.4
447 **/
448 GPtrArray *
449 dfu_target_get_sectors (DfuTarget *target)
450 {
451 DfuTargetPrivate *priv = GET_PRIVATE (target);
452 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
453 return priv->sectors;
454 }
455
456 /**
457 * dfu_target_status_to_error_msg:
458 * @status: a #DfuStatus, e.g. %DFU_STATUS_ERR_ERASE
459 *
460 * Converts an enumerated value to an error description.
461 *
462 * Return value: a string
463 *
464 * Since: 0.5.4
465 **/
466 static const gchar *
467 dfu_target_status_to_error_msg (DfuStatus status)
468 {
469 if (status == DFU_STATUS_OK)
470 return "No error condition is present";
471 if (status == DFU_STATUS_ERR_TARGET)
472 return "Firmware is not for designed this device";
473 if (status == DFU_STATUS_ERR_FILE)
474 return "Firmware is for this device but fails verification";
475 if (status == DFU_STATUS_ERR_WRITE)
476 return "Device is unable to write memory";
477 if (status == DFU_STATUS_ERR_ERASE)
478 return "Memory erase function failed";
479 if (status == DFU_STATUS_ERR_CHECK_ERASED)
480 return "Memory erase check failed";
481 if (status == DFU_STATUS_ERR_PROG)
482 return "Program memory function failed";
483 if (status == DFU_STATUS_ERR_VERIFY)
484 return "Programmed memory failed verification";
485 if (status == DFU_STATUS_ERR_ADDRESS)
486 return "Cannot program memory due to address out of range";
487 if (status == DFU_STATUS_ERR_NOTDONE)
488 return "Received zero-length download but data is incomplete";
489 if (status == DFU_STATUS_ERR_FIRMWARE)
490 return "Device firmware is corrupt";
491 if (status == DFU_STATUS_ERR_VENDOR)
492 return "Vendor-specific error";
493 if (status == DFU_STATUS_ERR_USBR)
494 return "Device detected unexpected USB reset signaling";
495 if (status == DFU_STATUS_ERR_POR)
496 return "Device detected unexpected power on reset";
497 if (status == DFU_STATUS_ERR_UNKNOWN)
498 return "Something unexpected went wrong";
499 if (status == DFU_STATUS_ERR_STALLDPKT)
500 return "Device stalled an unexpected request";
501 return NULL;
502 }
503
504 static gboolean
505 dfu_target_check_status (DfuTarget *target,
506 GCancellable *cancellable,
507 GError **error)
508 {
509 DfuTargetPrivate *priv = GET_PRIVATE (target);
510 DfuStatus status;
511
512 /* get the status */
513 if (!dfu_device_refresh (priv->device, cancellable, error))
514 return FALSE;
515
516 /* wait for dfuDNBUSY to not be set */
517 if (dfu_device_has_dfuse_support (priv->device)) {
518 while (dfu_device_get_state (priv->device) == DFU_STATE_DFU_DNBUSY) {
519 g_debug ("waiting for DFU_STATE_DFU_DNBUSY to clear");
520 g_usleep (dfu_device_get_download_timeout (priv->device) * 1000);
521 if (!dfu_device_refresh (priv->device, cancellable, error))
522 return FALSE;
523 }
524 }
525
526 /* not in an error state */
527 if (dfu_device_get_state (priv->device) != DFU_STATE_DFU_ERROR)
528 return TRUE;
529
530 /* DfuSe-specific long errors */
531 status = dfu_device_get_status (priv->device);
532 if (dfu_device_has_dfuse_support (priv->device)) {
533 if (status == DFU_STATUS_ERR_VENDOR) {
534 g_set_error (error,
535 DFU_ERROR,
536 DFU_ERROR_NOT_SUPPORTED,
537 "Read protection is active");
538 return FALSE;
539 }
540 if (status == DFU_STATUS_ERR_TARGET) {
541 g_set_error (error,
542 DFU_ERROR,
543 DFU_ERROR_NOT_SUPPORTED,
544 "Address is wrong or unsupported");
545 return FALSE;
546 }
547 }
548
549 /* use a proper error description */
550 g_set_error_literal (error,
551 DFU_ERROR,
552 DFU_ERROR_NOT_SUPPORTED,
553 dfu_target_status_to_error_msg (status));
554 return FALSE;
555 }
556
557 /**
558 * dfu_target_use_alt_setting:
559 * @target: a #DfuTarget
560 * @error: a #GError, or %NULL
561 *
562 * Opens a DFU-capable target.
563 *
564 * Return value: %TRUE for success
565 *
566 * Since: 0.5.4
567 **/
568 static gboolean
569 dfu_target_use_alt_setting (DfuTarget *target, GError **error)
570 {
571 DfuTargetPrivate *priv = GET_PRIVATE (target);
572 GUsbDevice *dev;
573 g_autoptr(GError) error_local = NULL;
574
575 g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
576 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
577
578 /* ensure interface is claimed */
579 if (!dfu_device_ensure_interface (priv->device, NULL, error))
580 return FALSE;
581
582 /* use the correct setting */
583 dev = dfu_device_get_usb_dev (priv->device);
584 if (dfu_device_get_mode (priv->device) == DFU_MODE_DFU) {
585 if (!g_usb_device_set_interface_alt (dev,
586 (gint) dfu_device_get_interface (priv->device),
587 (gint) priv->alt_setting,
588 &error_local)) {
589 g_set_error (error,
590 DFU_ERROR,
591 DFU_ERROR_NOT_SUPPORTED,
592 "cannot set alternate setting 0x%02x on interface %i: %s",
593 priv->alt_setting,
594 dfu_device_get_interface (priv->device),
595 error_local->message);
596 return FALSE;
597 }
598 }
599
600 return TRUE;
601 }
602
603 /**
604 * dfu_target_setup:
605 * @target: a #DfuTarget
606 * @error: a #GError, or %NULL
607 *
608 * Opens a DFU-capable target.
609 *
610 * Return value: %TRUE for success
611 *
612 * Since: 0.5.4
613 **/
614 static gboolean
615 dfu_target_setup (DfuTarget *target, GError **error)
616 {
617 DfuTargetPrivate *priv = GET_PRIVATE (target);
618
619 g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
620 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
621
622 /* already done */
623 if (priv->done_setup)
624 return TRUE;
625
626 /* get string */
627 if (priv->alt_idx != 0x00) {
628 GUsbDevice *dev;
629 dev = dfu_device_get_usb_dev (priv->device);
630 priv->alt_name =
631 g_usb_device_get_string_descriptor (dev,
632 priv->alt_idx,
633 NULL);
634 }
635
636 /* parse the DfuSe format according to UM0424 */
637 if (!dfu_target_parse_sectors (target,
638 priv->alt_name,
639 error))
640 return FALSE;
641
642 /* add a dummy entry */
643 if (priv->sectors->len == 0) {
644 DfuSector *sector;
645 sector = dfu_sector_new (0x0, /* addr */
646 0x0, /* size */
647 0x0, /* size_left */
648 0x0, /* zone */
649 0x0, /* number */
650 DFU_SECTOR_CAP_READABLE |
651 DFU_SECTOR_CAP_WRITEABLE);
652 g_debug ("no UM0424 sector description in %s", priv->alt_name);
653 g_ptr_array_add (priv->sectors, sector);
654 }
655
656 priv->done_setup = TRUE;
657 return TRUE;
658 }
659
660 gboolean
661 dfu_target_download_chunk (DfuTarget *target, guint8 index, GBytes *bytes,
662 GCancellable *cancellable, GError **error)
663 {
664 DfuTargetPrivate *priv = GET_PRIVATE (target);
665 g_autoptr(GError) error_local = NULL;
666 gsize actual_length;
667
668 if (!g_usb_device_control_transfer (dfu_device_get_usb_dev (priv->device),
669 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
670 G_USB_DEVICE_REQUEST_TYPE_CLASS,
671 G_USB_DEVICE_RECIPIENT_INTERFACE,
672 DFU_REQUEST_DNLOAD,
673 index,
674 dfu_device_get_interface (priv->device),
675 (guint8 *) g_bytes_get_data (bytes, NULL),
676 g_bytes_get_size (bytes),
677 &actual_length,
678 dfu_device_get_timeout (priv->device),
679 cancellable,
680 &error_local)) {
681 /* refresh the error code */
682 dfu_device_error_fixup (priv->device, cancellable, &error_local);
683 g_set_error (error,
684 DFU_ERROR,
685 DFU_ERROR_NOT_SUPPORTED,
686 "cannot download data: %s",
687 error_local->message);
688 return FALSE;
689 }
690
691 /* for ST devices, the action only occurs when we do GetStatus */
692 if (!dfu_device_refresh (priv->device, cancellable, error))
693 return FALSE;
694
695 /* give the target a chance to update */
696 g_usleep (dfu_device_get_download_timeout (priv->device) * 1000);
697
698 g_assert (actual_length == g_bytes_get_size (bytes));
699 return TRUE;
700 }
701
702 /**
703 * dfu_target_set_address:
704 * @target: a #DfuTarget
705 * @address: memory address
706 * @cancellable: a #GCancellable, or %NULL
707 * @error: a #GError, or %NULL
708 *
709 * Sets the address used for the next download or upload request.
710 *
711 * IMPORTANT: This only works on DfuSe-capable devices from ST.
712 *
713 * Return value: %TRUE for success
714 *
715 * Since: 0.5.4
716 **/
717 static gboolean
718 dfu_target_set_address (DfuTarget *target,
719 guint32 address,
720 GCancellable *cancellable,
721 GError **error)
722 {
723 DfuTargetPrivate *priv = GET_PRIVATE (target);
724 GBytes *data_in;
725 guint8 buf[5];
726
727 /* invalid */
728 if (!dfu_device_has_dfuse_support (priv->device)) {
729 g_set_error_literal (error,
730 DFU_ERROR,
731 DFU_ERROR_NOT_SUPPORTED,
732 "only supported for DfuSe targets");
733 return FALSE;
734 }
735
736 /* format buffer */
737 buf[0] = DFU_CMD_DFUSE_SET_ADDRESS_POINTER;
738 memcpy (buf + 1, &address, 4);
739 data_in = g_bytes_new_static (buf, sizeof(buf));
740 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
741 g_prefix_error (error, "cannot set address 0x%x: ", address);
742 return FALSE;
743 }
744
745 /* 2nd check required to get error code */
746 g_debug ("doing actual check status");
747 return dfu_target_check_status (target, cancellable, error);
748 }
749
750 /**
751 * dfu_target_erase_address:
752 * @target: a #DfuTarget
753 * @address: memory address
754 * @cancellable: a #GCancellable, or %NULL
755 * @error: a #GError, or %NULL
756 *
757 * Erases a memory sector at a given address.
758 *
759 * IMPORTANT: This only works on DfuSe-capable devices from ST.
760 *
761 * Return value: %TRUE for success
762 *
763 * Since: 0.5.4
764 **/
765 static gboolean
766 dfu_target_erase_address (DfuTarget *target,
767 guint32 address,
768 GCancellable *cancellable,
769 GError **error)
770 {
771 DfuTargetPrivate *priv = GET_PRIVATE (target);
772 GBytes *data_in;
773 guint8 buf[5];
774
775 /* invalid */
776 if (!dfu_device_has_dfuse_support (priv->device)) {
777 g_set_error_literal (error,
778 DFU_ERROR,
779 DFU_ERROR_NOT_SUPPORTED,
780 "only supported for DfuSe targets");
781 return FALSE;
782 }
783
784 /* format buffer */
785 buf[0] = DFU_CMD_DFUSE_ERASE;
786 memcpy (buf + 1, &address, 4);
787 data_in = g_bytes_new_static (buf, sizeof(buf));
788 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
789 g_prefix_error (error, "cannot erase address 0x%x: ", address);
790 return FALSE;
791 }
792
793 /* 2nd check required to get error code */
794 g_debug ("doing actual check status");
795 return dfu_target_check_status (target, cancellable, error);
796 }
797
798 #if 0
799
800 /**
801 * dfu_target_mass_erase:
802 * @target: a #DfuTarget
803 * @cancellable: a #GCancellable, or %NULL
804 * @error: a #GError, or %NULL
805 *
806 * Mass erases the device clearing all SRAM and EEPROM memory.
807 *
808 * This may not be supported on all devices, a better way of doing this action
809 * is to enable read protection and then doing dfu_target_read_unprotect().
810 *
811 * IMPORTANT: This only works on DfuSe-capable devices from ST.
812 *
813 * Return value: %TRUE for success
814 *
815 * Since: 0.5.4
816 **/
817 static gboolean
818 dfu_target_mass_erase (DfuTarget *target,
819 GCancellable *cancellable,
820 GError **error)
821 {
822 DfuTargetPrivate *priv = GET_PRIVATE (target);
823 GBytes *data_in;
824 guint8 buf[1];
825
826 /* invalid */
827 if (!dfu_device_has_dfuse_support (priv->device)) {
828 g_set_error_literal (error,
829 DFU_ERROR,
830 DFU_ERROR_NOT_SUPPORTED,
831 "only supported for DfuSe targets");
832 return FALSE;
833 }
834
835 /* format buffer */
836 buf[0] = DFU_CMD_DFUSE_ERASE;
837 data_in = g_bytes_new_static (buf, sizeof(buf));
838 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
839 g_prefix_error (error, "cannot mass-erase: ");
840 return FALSE;
841 }
842
843 /* 2nd check required to get error code */
844 return dfu_target_check_status (target, cancellable, error);
845 }
846
847 /**
848 * dfu_target_read_unprotect:
849 * @target: a #DfuTarget
850 * @cancellable: a #GCancellable, or %NULL
851 * @error: a #GError, or %NULL
852 *
853 * Turns of read protection on the device, clearing all SRAM and EEPROM memory.
854 *
855 * IMPORTANT: This only works on DfuSe-capable devices from ST.
856 *
857 * Return value: %TRUE for success
858 *
859 * Since: 0.5.4
860 **/
861 static gboolean
862 dfu_target_read_unprotect (DfuTarget *target,
863 GCancellable *cancellable,
864 GError **error)
865 {
866 DfuTargetPrivate *priv = GET_PRIVATE (target);
867 GBytes *data_in;
868 guint8 buf[5];
869
870 /* invalid */
871 if (!dfu_device_has_dfuse_support (priv->device)) {
872 g_set_error_literal (error,
873 DFU_ERROR,
874 DFU_ERROR_NOT_SUPPORTED,
875 "only supported for DfuSe targets");
876 return FALSE;
877 }
878
879 /* format buffer */
880 buf[0] = DFU_CMD_DFUSE_READ_UNPROTECT;
881 memcpy (buf + 1, &address, 4);
882 data_in = g_bytes_new_static (buf, sizeof(buf));
883 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
884 g_prefix_error (error, "cannot read-unprotect: ");
885 return FALSE;
886 }
887
888 /* for ST devices, the action only occurs when we do GetStatus */
889 return dfu_target_check_status (target, cancellable, error);
890 }
891
892 #endif
893
894 GBytes *
895 dfu_target_upload_chunk (DfuTarget *target, guint8 index,
896 GCancellable *cancellable, GError **error)
897 {
898 DfuTargetPrivate *priv = GET_PRIVATE (target);
899 g_autoptr(GError) error_local = NULL;
900 guint8 *buf;
901 gsize actual_length;
902 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
903
904 buf = g_new0 (guint8, transfer_size);
905 if (!g_usb_device_control_transfer (dfu_device_get_usb_dev (priv->device),
906 G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
907 G_USB_DEVICE_REQUEST_TYPE_CLASS,
908 G_USB_DEVICE_RECIPIENT_INTERFACE,
909 DFU_REQUEST_UPLOAD,
910 index,
911 dfu_device_get_interface (priv->device),
912 buf, (gsize) transfer_size,
913 &actual_length,
914 dfu_device_get_timeout (priv->device),
915 cancellable,
916 &error_local)) {
917 /* refresh the error code */
918 dfu_device_error_fixup (priv->device, cancellable, &error_local);
919 g_set_error (error,
920 DFU_ERROR,
921 DFU_ERROR_NOT_SUPPORTED,
922 "cannot upload data: %s",
923 error_local->message);
924 return NULL;
925 }
926
927 return g_bytes_new_take (buf, actual_length);
928 }
929
930 static void
931 dfu_target_set_action (DfuTarget *target, DfuAction action)
932 {
933 DfuTargetPrivate *priv = GET_PRIVATE (target);
934
935 /* unchanged */
936 if (priv->old_action == action)
937 return;
938 if (priv->old_action != DFU_ACTION_IDLE &&
939 action != DFU_ACTION_IDLE) {
940 g_debug ("ignoring action %s as %s already set and not idle",
941 dfu_action_to_string (action),
942 dfu_action_to_string (priv->old_action));
943 return;
944 }
945 g_debug ("setting action %s", dfu_action_to_string (action));
946 g_signal_emit (target, signals[SIGNAL_ACTION_CHANGED], 0, action);
947 priv->old_action = action;
948 }
949
950 static void
951 dfu_target_set_percentage_raw (DfuTarget *target, guint percentage)
952 {
953 DfuTargetPrivate *priv = GET_PRIVATE (target);
954 if (percentage == priv->old_percentage)
955 return;
956 g_debug ("setting percentage %u%% of %s",
957 percentage, dfu_action_to_string (priv->old_action));
958 g_signal_emit (target,
959 signals[SIGNAL_PERCENTAGE_CHANGED],
960 0, percentage);
961 priv->old_percentage = percentage;
962 }
963
964 static void
965 dfu_target_set_percentage (DfuTarget *target, guint value, guint total)
966 {
967 guint percentage;
968
969 g_return_if_fail (total > 0);
970
971 percentage = (value * 100) / total;
972 if (percentage >= 100)
973 return;
974 dfu_target_set_percentage_raw (target, percentage);
975 }
976
977 static GBytes *
978 _g_bytes_array_join (GPtrArray *chunks)
979 {
980 gsize total_size = 0;
981 guint32 offset = 0;
982 guint8 *buffer;
983 guint i;
984
985 /* get the size of all the chunks */
986 for (i = 0; i < chunks->len; i++) {
987 GBytes *chunk_tmp = g_ptr_array_index (chunks, i);
988 total_size += g_bytes_get_size (chunk_tmp);
989 }
990
991 /* copy them into a buffer */
992 buffer = g_malloc0 (total_size);
993 for (i = 0; i < chunks->len; i++) {
994 const guint8 *chunk_data;
995 gsize chunk_size = 0;
996 GBytes *chunk_tmp = g_ptr_array_index (chunks, i);
997 chunk_data = g_bytes_get_data (chunk_tmp, &chunk_size);
998 if (chunk_size == 0)
999 continue;
1000 memcpy (buffer + offset, chunk_data, chunk_size);
1001 offset += chunk_size;
1002 }
1003 return g_bytes_new_take (buffer, total_size);
1004 }
1005
1006 static DfuElement *
1007 dfu_target_upload_element_dfuse (DfuTarget *target,
1008 guint32 address,
1009 gsize expected_size,
1010 gsize maximum_size,
1011 GCancellable *cancellable,
1012 GError **error)
1013 {
1014 DfuTargetPrivate *priv = GET_PRIVATE (target);
1015 DfuSector *sector;
1016 DfuElement *element = NULL;
1017 GBytes *chunk_tmp;
1018 guint32 offset = address;
1019 guint percentage_size = expected_size > 0 ? expected_size : maximum_size;
1020 gsize total_size = 0;
1021 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1022 guint idx;
1023 g_autoptr(GBytes) contents = NULL;
1024 g_autoptr(GBytes) contents_truncated = NULL;
1025 g_autoptr(GPtrArray) chunks = NULL;
1026
1027 /* for DfuSe devices we need to handle the address manually */
1028 sector = dfu_target_get_sector_for_addr (target, offset);
1029 if (sector == NULL) {
1030 g_set_error (error,
1031 DFU_ERROR,
1032 DFU_ERROR_INVALID_DEVICE,
1033 "no memory sector at 0x%04x",
1034 (guint) offset);
1035 return NULL;
1036 }
1037 g_debug ("using sector %u for read of %x",
1038 dfu_sector_get_id (sector),
1039 offset);
1040 if (!dfu_sector_has_cap (sector, DFU_SECTOR_CAP_READABLE)) {
1041 g_set_error (error,
1042 DFU_ERROR,
1043 DFU_ERROR_INVALID_DEVICE,
1044 "memory sector at 0x%04x is not readble",
1045 (guint) offset);
1046 return NULL;
1047 }
1048
1049 /* update UI */
1050 dfu_target_set_action (target, DFU_ACTION_READ);
1051
1052 /* manually set the sector address */
1053 g_debug ("setting DfuSe address to 0x%04x", (guint) offset);
1054 if (!dfu_target_set_address (target,
1055 offset,
1056 cancellable,
1057 error))
1058 return NULL;
1059
1060 /* abort back to IDLE */
1061 if (!dfu_device_abort (priv->device, cancellable, error))
1062 return NULL;
1063
1064 /* get all the chunks from the hardware */
1065 chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
1066 for (idx = 0; idx < G_MAXUINT16; idx++) {
1067 guint32 chunk_size;
1068
1069 /* read chunk of data -- ST uses wBlockNum=0 for DfuSe commands
1070 * and wBlockNum=1 is reserved */
1071 chunk_tmp = dfu_target_upload_chunk (target,
1072 (guint8) (idx + 2),
1073 cancellable,
1074 error);
1075 if (chunk_tmp == NULL)
1076 return NULL;
1077
1078 /* add to array */
1079 chunk_size = (guint32) g_bytes_get_size (chunk_tmp);
1080 g_debug ("got #%04x chunk @0x%x of size %" G_GUINT32_FORMAT,
1081 idx, offset, chunk_size);
1082 g_ptr_array_add (chunks, chunk_tmp);
1083 total_size += chunk_size;
1084 offset += chunk_size;
1085
1086 /* update UI */
1087 if (chunk_size > 0)
1088 dfu_target_set_percentage (target, total_size, percentage_size);
1089
1090 /* detect short write as EOF */
1091 if (chunk_size < transfer_size)
1092 break;
1093
1094 /* more data than we needed */
1095 if (maximum_size > 0 && total_size > maximum_size)
1096 break;
1097 }
1098
1099 /* abort back to IDLE */
1100 if (dfu_device_has_dfuse_support (priv->device)) {
1101 if (!dfu_device_abort (priv->device, cancellable, error))
1102 return NULL;
1103 }
1104
1105 /* check final size */
1106 if (expected_size > 0) {
1107 if (total_size < expected_size) {
1108 g_set_error (error,
1109 DFU_ERROR,
1110 DFU_ERROR_INVALID_FILE,
1111 "invalid size, got %" G_GSIZE_FORMAT ", "
1112 "expected %" G_GSIZE_FORMAT ,
1113 total_size, expected_size);
1114 return NULL;
1115 }
1116 }
1117
1118 /* done */
1119 dfu_target_set_percentage_raw (target, 100);
1120 dfu_target_set_action (target, DFU_ACTION_IDLE);
1121
1122 /* create new image */
1123 contents = _g_bytes_array_join (chunks);
1124 if (expected_size > 0)
1125 contents_truncated = g_bytes_new_from_bytes (contents, 0, expected_size);
1126 else
1127 contents_truncated = g_bytes_ref (contents);
1128 element = dfu_element_new ();
1129 dfu_element_set_contents (element, contents_truncated);
1130 dfu_element_set_address (element, address);
1131 return element;
1132 }
1133
1134 static DfuElement *
1135 dfu_target_upload_element_dfu (DfuTarget *target,
1136 guint32 address,
1137 gsize expected_size,
1138 gsize maximum_size,
1139 GCancellable *cancellable,
1140 GError **error)
1141 {
1142 DfuTargetPrivate *priv = GET_PRIVATE (target);
1143 DfuElement *element = NULL;
1144 GBytes *chunk_tmp;
1145 guint32 offset = 0;
1146 guint percentage_size = expected_size > 0 ? expected_size : maximum_size;
1147 gsize total_size = 0;
1148 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1149 guint idx;
1150 g_autoptr(GBytes) contents = NULL;
1151 g_autoptr(GPtrArray) chunks = NULL;
1152
1153 /* update UI */
1154 dfu_target_set_action (target, DFU_ACTION_READ);
1155
1156 /* get all the chunks from the hardware */
1157 chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
1158 for (idx = 0; idx < G_MAXUINT16; idx++) {
1159 guint32 chunk_size;
1160
1161 /* read chunk of data */
1162 chunk_tmp = dfu_target_upload_chunk (target,
1163 (guint8) idx,
1164 cancellable,
1165 error);
1166 if (chunk_tmp == NULL)
1167 return NULL;
1168
1169 /* keep a sum of all the chunks */
1170 chunk_size = (guint32) g_bytes_get_size (chunk_tmp);
1171 total_size += chunk_size;
1172 offset += chunk_size;
1173
1174 /* add to array */
1175 g_debug ("got #%04x chunk of size %" G_GUINT32_FORMAT,
1176 idx, chunk_size);
1177 g_ptr_array_add (chunks, chunk_tmp);
1178
1179 /* update UI */
1180 if (chunk_size > 0)
1181 dfu_target_set_percentage (target, total_size, percentage_size);
1182
1183 /* detect short write as EOF */
1184 if (chunk_size < transfer_size)
1185 break;
1186 }
1187
1188 /* check final size */
1189 if (expected_size > 0) {
1190 if (total_size != expected_size) {
1191 g_set_error (error,
1192 DFU_ERROR,
1193 DFU_ERROR_INVALID_FILE,
1194 "invalid size, got %" G_GSIZE_FORMAT ", "
1195 "expected %" G_GSIZE_FORMAT ,
1196 total_size, expected_size);
1197 return NULL;
1198 }
1199 }
1200
1201 /* done */
1202 dfu_target_set_percentage_raw (target, 100);
1203 dfu_target_set_action (target, DFU_ACTION_IDLE);
1204
1205 /* create new image */
1206 contents = _g_bytes_array_join (chunks);
1207 element = dfu_element_new ();
1208 dfu_element_set_contents (element, contents);
1209 return element;
1210 }
1211
1212 static DfuElement *
1213 dfu_target_upload_element (DfuTarget *target,
1214 guint32 address,
1215 gsize expected_size,
1216 gsize maximum_size,
1217 GCancellable *cancellable,
1218 GError **error)
1219 {
1220 DfuTargetPrivate *priv = GET_PRIVATE (target);
1221 if (dfu_device_has_dfuse_support (priv->device)) {
1222 return dfu_target_upload_element_dfuse (target,
1223 address,
1224 expected_size,
1225 maximum_size,
1226 cancellable,
1227 error);
1228 }
1229 return dfu_target_upload_element_dfu (target,
1230 address,
1231 expected_size,
1232 maximum_size,
1233 cancellable,
1234 error);
1235 }
1236
1237 static guint32
1238 dfu_target_get_size_of_zone (DfuTarget *target, guint16 zone)
1239 {
1240 DfuTargetPrivate *priv = GET_PRIVATE (target);
1241 guint i;
1242 guint32 len = 0;
1243 for (i = 0; i < priv->sectors->len; i++) {
1244 DfuSector *sector = g_ptr_array_index (priv->sectors, i);
1245 if (dfu_sector_get_zone (sector) != zone)
1246 continue;
1247 len += dfu_sector_get_size (sector);
1248 }
1249 return len;
1250 }
1251
1252 /**
1253 * dfu_target_upload:
1254 * @target: a #DfuTarget
1255 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1256 * @cancellable: a #GCancellable, or %NULL
1257 * @error: a #GError, or %NULL
1258 *
1259 * Uploads firmware from the target to the host.
1260 *
1261 * Return value: (transfer full): the uploaded image, or %NULL for error
1262 *
1263 * Since: 0.5.4
1264 **/
1265 DfuImage *
1266 dfu_target_upload (DfuTarget *target,
1267 DfuTargetTransferFlags flags,
1268 GCancellable *cancellable,
1269 GError **error)
1270 {
1271 DfuTargetPrivate *priv = GET_PRIVATE (target);
1272 DfuSector *sector;
1273 guint i;
1274 guint16 zone_cur;
1275 guint32 zone_size = 0;
1276 guint32 zone_last = G_MAXUINT;
1277 g_autoptr(DfuImage) image = NULL;
1278
1279 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
1280 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1281
1282 /* ensure populated */
1283 if (!dfu_target_setup (target, error))
1284 return NULL;
1285
1286 /* can the target do this? */
1287 if (!dfu_device_can_upload (priv->device)) {
1288 g_set_error_literal (error,
1289 DFU_ERROR,
1290 DFU_ERROR_NOT_SUPPORTED,
1291 "target cannot do uploading");
1292 return NULL;
1293 }
1294
1295 /* use correct alt */
1296 if (!dfu_target_use_alt_setting (target, error))
1297 return NULL;
1298
1299 /* no open?! */
1300 if (priv->sectors->len == 0) {
1301 g_set_error_literal (error,
1302 DFU_ERROR,
1303 DFU_ERROR_NOT_SUPPORTED,
1304 "no sectors defined for target");
1305 return NULL;
1306 }
1307
1308 /* create a new image */
1309 image = dfu_image_new ();
1310 dfu_image_set_name (image, priv->alt_name);
1311 dfu_image_set_alt_setting (image, priv->alt_setting);
1312
1313 /* get all the sectors for the device */
1314 for (i = 0; i < priv->sectors->len; i++) {
1315 g_autoptr(DfuElement) element = NULL;
1316
1317 /* only upload to the start of any zone:sector */
1318 sector = g_ptr_array_index (priv->sectors, i);
1319 zone_cur = dfu_sector_get_zone (sector);
1320 if (zone_cur == zone_last)
1321 continue;
1322
1323 /* get the size of the entire continous zone */
1324 zone_size = dfu_target_get_size_of_zone (target, zone_cur);
1325 zone_last = zone_cur;
1326
1327 /* get the first element from the hardware */
1328 g_debug ("starting upload from 0x%08x (0x%04x)",
1329 dfu_sector_get_address (sector),
1330 zone_size);
1331 element = dfu_target_upload_element (target,
1332 dfu_sector_get_address (sector),
1333 0, /* expected */
1334 zone_size, /* maximum */
1335 cancellable,
1336 error);
1337 if (element == NULL)
1338 return NULL;
1339
1340 /* this element was uploaded okay */
1341 dfu_image_add_element (image, element);
1342 }
1343
1344 /* do host reset */
1345 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
1346 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
1347 if (!dfu_device_attach (priv->device, error))
1348 return NULL;
1349 }
1350
1351 /* boot to runtime */
1352 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
1353 g_debug ("booting to runtime");
1354 if (!dfu_device_wait_for_replug (priv->device,
1355 DFU_DEVICE_REPLUG_TIMEOUT,
1356 cancellable,
1357 error))
1358 return NULL;
1359 }
1360
1361 /* success */
1362 return g_object_ref (image);
1363 }
1364
1365 static gchar *
1366 _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2)
1367 {
1368 const guint8 *data1;
1369 const guint8 *data2;
1370 gsize length1;
1371 gsize length2;
1372 guint i;
1373
1374 data1 = g_bytes_get_data (bytes1, &length1);
1375 data2 = g_bytes_get_data (bytes2, &length2);
1376
1377 /* not the same length */
1378 if (length1 != length2) {
1379 return g_strdup_printf ("got %" G_GSIZE_FORMAT " bytes, "
1380 "expected %" G_GSIZE_FORMAT,
1381 length1, length2);
1382 }
1383
1384 /* return 00 01 02 03 */
1385 for (i = 0; i < length1; i++) {
1386 if (data1[i] != data2[i]) {
1387 return g_strdup_printf ("got 0x%02x, expected 0x%02x @ 0x%04x",
1388 data1[i], data2[i], i);
1389 }
1390 }
1391 return NULL;
1392 }
1393
1394 static gboolean
1395 dfu_target_download_element_dfu (DfuTarget *target,
1396 DfuElement *element,
1397 DfuTargetTransferFlags flags,
1398 GCancellable *cancellable,
1399 GError **error)
1400 {
1401 DfuTargetPrivate *priv = GET_PRIVATE (target);
1402 GBytes *bytes;
1403 guint i;
1404 guint nr_chunks;
1405 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1406
1407 /* round up as we have to transfer incomplete blocks */
1408 bytes = dfu_element_get_contents (element);
1409 nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) /
1410 (gdouble) transfer_size);
1411 if (nr_chunks == 0) {
1412 g_set_error_literal (error,
1413 DFU_ERROR,
1414 DFU_ERROR_INVALID_FILE,
1415 "zero-length firmware");
1416 return FALSE;
1417 }
1418 dfu_target_set_action (target, DFU_ACTION_WRITE);
1419 for (i = 0; i < nr_chunks + 1; i++) {
1420 gsize length;
1421 guint32 offset;
1422 g_autoptr(GBytes) bytes_tmp = NULL;
1423
1424 /* caclulate the offset into the element data */
1425 offset = i * transfer_size;
1426
1427 /* we have to write one final zero-sized chunk for EOF */
1428 if (i < nr_chunks) {
1429 length = g_bytes_get_size (bytes) - offset;
1430 if (length > transfer_size)
1431 length = transfer_size;
1432 bytes_tmp = g_bytes_new_from_bytes (bytes, offset, length);
1433 } else {
1434 bytes_tmp = g_bytes_new (NULL, 0);
1435 }
1436 g_debug ("writing #%04x chunk of size %" G_GSIZE_FORMAT,
1437 i, g_bytes_get_size (bytes_tmp));
1438 if (!dfu_target_download_chunk (target,
1439 (guint8) i,
1440 bytes_tmp,
1441 cancellable,
1442 error))
1443 return FALSE;
1444
1445 /* update UI */
1446 dfu_target_set_percentage (target, offset, g_bytes_get_size (bytes));
1447 }
1448
1449 /* done */
1450 dfu_target_set_percentage_raw (target, 100);
1451 dfu_target_set_action (target, DFU_ACTION_IDLE);
1452
1453 /* success */
1454 return TRUE;
1455 }
1456
1457 static gboolean
1458 dfu_target_download_element_dfuse (DfuTarget *target,
1459 DfuElement *element,
1460 DfuTargetTransferFlags flags,
1461 GCancellable *cancellable,
1462 GError **error)
1463 {
1464 DfuTargetPrivate *priv = GET_PRIVATE (target);
1465 DfuSector *sector;
1466 GBytes *bytes;
1467 guint i;
1468 guint nr_chunks;
1469 guint zone_last = G_MAXUINT;
1470 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1471 g_autoptr(GPtrArray) sectors_array = NULL;
1472 g_autoptr(GHashTable) sectors_hash = NULL;
1473
1474 /* round up as we have to transfer incomplete blocks */
1475 bytes = dfu_element_get_contents (element);
1476 nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) /
1477 (gdouble) transfer_size);
1478 if (nr_chunks == 0) {
1479 g_set_error_literal (error,
1480 DFU_ERROR,
1481 DFU_ERROR_INVALID_FILE,
1482 "zero-length firmware");
1483 return FALSE;
1484 }
1485
1486 /* 1st pass: work out which sectors need erasing */
1487 sectors_array = g_ptr_array_new ();
1488 sectors_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
1489 for (i = 0; i < nr_chunks; i++) {
1490 guint32 offset_dev;
1491
1492 /* for DfuSe devices we need to handle the erase and setting
1493 * the sectory address manually */
1494 offset_dev = dfu_element_get_address (element) + (i * transfer_size);
1495 sector = dfu_target_get_sector_for_addr (target, offset_dev);
1496 if (sector == NULL) {
1497 g_set_error (error,
1498 DFU_ERROR,
1499 DFU_ERROR_INVALID_DEVICE,
1500 "no memory sector at 0x%04x",
1501 (guint) offset_dev);
1502 return FALSE;
1503 }
1504 if (!dfu_sector_has_cap (sector, DFU_SECTOR_CAP_WRITEABLE)) {
1505 g_set_error (error,
1506 DFU_ERROR,
1507 DFU_ERROR_INVALID_DEVICE,
1508 "memory sector at 0x%04x is not writable",
1509 (guint) offset_dev);
1510 return FALSE;
1511 }
1512
1513 /* if it's erasable and not yet blanked */
1514 if (dfu_sector_has_cap (sector, DFU_SECTOR_CAP_ERASEABLE) &&
1515 g_hash_table_lookup (sectors_hash, sector) == NULL) {
1516 g_hash_table_insert (sectors_hash,
1517 sector,
1518 GINT_TO_POINTER (1));
1519 g_ptr_array_add (sectors_array, sector);
1520 g_debug ("marking sector 0x%04x-%04x to be erased",
1521 dfu_sector_get_address (sector),
1522 dfu_sector_get_address (sector) + dfu_sector_get_size (sector));
1523 }
1524 }
1525
1526 /* 2nd pass: actually erase sectors */
1527 dfu_target_set_action (target, DFU_ACTION_ERASE);
1528 for (i = 0; i < sectors_array->len; i++) {
1529 sector = g_ptr_array_index (sectors_array, i);
1530 g_debug ("erasing sector at 0x%04x",
1531 dfu_sector_get_address (sector));
1532 if (!dfu_target_erase_address (target,
1533 dfu_sector_get_address (sector),
1534 cancellable,
1535 error))
1536 return FALSE;
1537 dfu_target_set_percentage (target, i + 1, sectors_array->len);
1538 }
1539 dfu_target_set_percentage_raw (target, 100);
1540 dfu_target_set_action (target, DFU_ACTION_IDLE);
1541
1542 /* 3rd pass: write data */
1543 dfu_target_set_action (target, DFU_ACTION_WRITE);
1544 for (i = 0; i < nr_chunks; i++) {
1545 gsize length;
1546 guint32 offset;
1547 guint32 offset_dev;
1548 g_autoptr(GBytes) bytes_tmp = NULL;
1549
1550 /* caclulate the offset into the element data */
1551 offset = i * transfer_size;
1552 offset_dev = dfu_element_get_address (element) + offset;
1553
1554 /* for DfuSe devices we need to set the address manually */
1555 sector = dfu_target_get_sector_for_addr (target, offset_dev);
1556 g_assert (sector != NULL);
1557
1558 /* manually set the sector address */
1559 if (dfu_sector_get_zone (sector) != zone_last) {
1560 g_debug ("setting address to 0x%04x",
1561 (guint) offset_dev);
1562 if (!dfu_target_set_address (target,
1563 (guint32) offset_dev,
1564 cancellable,
1565 error))
1566 return FALSE;
1567 zone_last = dfu_sector_get_zone (sector);
1568 }
1569
1570 /* we have to write one final zero-sized chunk for EOF */
1571 length = g_bytes_get_size (bytes) - offset;
1572 if (length > transfer_size)
1573 length = transfer_size;
1574 bytes_tmp = g_bytes_new_from_bytes (bytes, offset, length);
1575 g_debug ("writing sector at 0x%04x (0x%" G_GSIZE_FORMAT ")",
1576 offset_dev,
1577 g_bytes_get_size (bytes_tmp));
1578 /* ST uses wBlockNum=0 for DfuSe commands and wBlockNum=1 is reserved */
1579 if (!dfu_target_download_chunk (target,
1580 (guint8) (i + 2),
1581 bytes_tmp,
1582 cancellable,
1583 error))
1584 return FALSE;
1585
1586 /* getting the status moves the state machine to DNLOAD-IDLE */
1587 if (!dfu_target_check_status (target, cancellable, error))
1588 return FALSE;
1589
1590 /* update UI */
1591 dfu_target_set_percentage (target, offset, g_bytes_get_size (bytes));
1592 }
1593
1594 /* done */
1595 dfu_target_set_percentage_raw (target, 100);
1596 dfu_target_set_action (target, DFU_ACTION_IDLE);
1597
1598 /* success */
1599 return TRUE;
1600 }
1601
1602 static gboolean
1603 dfu_target_download_element (DfuTarget *target,
1604 DfuElement *element,
1605 DfuTargetTransferFlags flags,
1606 GCancellable *cancellable,
1607 GError **error)
1608 {
1609 DfuTargetPrivate *priv = GET_PRIVATE (target);
1610
1611 /* DfuSe specific */
1612 if (dfu_device_has_dfuse_support (priv->device)) {
1613 if (!dfu_target_download_element_dfuse (target,
1614 element,
1615 flags,
1616 cancellable,
1617 error))
1618 return FALSE;
1619 } else {
1620 if (!dfu_target_download_element_dfu (target,
1621 element,
1622 flags,
1623 cancellable,
1624 error))
1625 return FALSE;
1626 }
1627
1628 /* verify */
1629 if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY) {
1630 GBytes *bytes;
1631 GBytes *bytes_tmp;
1632 g_autoptr(DfuElement) element_tmp = NULL;
1633 dfu_target_set_action (target, DFU_ACTION_VERIFY);
1634 bytes = dfu_element_get_contents (element);
1635 element_tmp = dfu_target_upload_element (target,
1636 dfu_element_get_address (element),
1637 g_bytes_get_size (bytes),
1638 g_bytes_get_size (bytes),
1639 cancellable,
1640 error);
1641 if (element_tmp == NULL)
1642 return FALSE;
1643 bytes_tmp = dfu_element_get_contents (element_tmp);
1644 if (g_bytes_compare (bytes_tmp, bytes) != 0) {
1645 g_autofree gchar *bytes_cmp_str = NULL;
1646 bytes_cmp_str = _g_bytes_compare_verbose (bytes_tmp, bytes);
1647 g_set_error (error,
1648 DFU_ERROR,
1649 DFU_ERROR_VERIFY_FAILED,
1650 "verify failed: %s",
1651 bytes_cmp_str);
1652 return FALSE;
1653 }
1654 dfu_target_set_action (target, DFU_ACTION_IDLE);
1655 }
1656
1657 return TRUE;
1658 }
1659
1660 /**
1661 * dfu_target_download:
1662 * @target: a #DfuTarget
1663 * @image: a #DfuImage
1664 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1665 * @cancellable: a #GCancellable, or %NULL
1666 * @error: a #GError, or %NULL
1667 *
1668 * Downloads firmware from the host to the target, optionally verifying
1669 * the transfer.
1670 *
1671 * Return value: %TRUE for success
1672 *
1673 * Since: 0.5.4
1674 **/
1675 gboolean
1676 dfu_target_download (DfuTarget *target, DfuImage *image,
1677 DfuTargetTransferFlags flags,
1678 GCancellable *cancellable,
1679 GError **error)
1680 {
1681 DfuTargetPrivate *priv = GET_PRIVATE (target);
1682 DfuElement *element;
1683 GPtrArray *elements;
1684 gboolean ret;
1685 guint i;
1686
1687 g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
1688 g_return_val_if_fail (DFU_IS_IMAGE (image), FALSE);
1689 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1690
1691 /* ensure populated */
1692 if (!dfu_target_setup (target, error))
1693 return FALSE;
1694
1695 /* can the target do this? */
1696 if (!dfu_device_can_download (priv->device)) {
1697 g_set_error_literal (error,
1698 DFU_ERROR,
1699 DFU_ERROR_NOT_SUPPORTED,
1700 "target cannot do downloading");
1701 return FALSE;
1702 }
1703
1704 /* use correct alt */
1705 if (!dfu_target_use_alt_setting (target, error))
1706 return FALSE;
1707
1708 /* download all elements in the image to the device */
1709 elements = dfu_image_get_elements (image);
1710 if (elements->len == 0) {
1711 g_set_error_literal (error,
1712 DFU_ERROR,
1713 DFU_ERROR_INVALID_FILE,
1714 "no image elements");
1715 return FALSE;
1716 }
1717 for (i = 0; i < elements->len; i++) {
1718 element = dfu_image_get_element (image, (guint8) i);
1719 g_debug ("downloading element at 0x%04x",
1720 dfu_element_get_address (element));
1721
1722 /* auto-detect missing firmware address -- this assumes
1723 * that the first target is the main program memory and that
1724 * there is only one element in the firmware file */
1725 if (flags & DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC &&
1726 dfu_element_get_address (element) == 0x0 &&
1727 elements->len == 1 &&
1728 priv->sectors->len > 0) {
1729 DfuSector *sector = g_ptr_array_index (priv->sectors, 0);
1730 g_debug ("fixing up firmware address from 0x0 to 0x%x",
1731 dfu_sector_get_address (sector));
1732 dfu_element_set_address (element, dfu_sector_get_address (sector));
1733 }
1734
1735 /* download to device */
1736 ret = dfu_target_download_element (target,
1737 element,
1738 flags,
1739 cancellable,
1740 error);
1741 if (!ret)
1742 return FALSE;
1743 }
1744
1745 /* attempt to switch back to runtime */
1746 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
1747 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
1748 if (!dfu_device_attach (priv->device, error))
1749 return FALSE;
1750 }
1751
1752 /* boot to runtime */
1753 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
1754 g_debug ("booting to runtime to set auto-boot");
1755 if (!dfu_device_wait_for_replug (priv->device,
1756 DFU_DEVICE_REPLUG_TIMEOUT,
1757 cancellable,
1758 error))
1759 return FALSE;
1760 }
1761
1762 /* success */
1763 return TRUE;
1764 }
1765
1766 #if 0
1767 static gboolean
1768 dfu_target_get_commands (DfuTarget *target,
1769 GCancellable *cancellable,
1770 GError **error)
1771 {
1772 GBytes *data_in;
1773 GBytes *data_out;
1774 guint8 buf[1];
1775
1776 /* invalid */
1777 if (!dfu_device_has_dfuse_support (priv->device)) {
1778 g_set_error_literal (error,
1779 DFU_ERROR,
1780 DFU_ERROR_NOT_SUPPORTED,
1781 "only supported for DfuSe targets");
1782 return FALSE;
1783 }
1784
1785 /* format buffer */
1786 buf[0] = DFU_CMD_DFUSE_GET_COMMAND;
1787 data_in = g_bytes_new_static (buf, sizeof(buf));
1788 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
1789 g_prefix_error (error, "cannot get DfuSe commands: ");
1790 return FALSE;
1791 }
1792
1793 /* return results */
1794 data_out = dfu_target_upload_chunk (target, 0, cancellable, error);
1795 if (data_out == NULL)
1796 return FALSE;
1797
1798 // N bytes,
1799 // each byte is the command code
1800
1801 // FIXME: parse?
1802 return TRUE;
1803 }
1804 #endif
1805
1806 /**
1807 * dfu_target_get_alt_setting:
1808 * @target: a #DfuTarget
1809 *
1810 * Gets the alternate setting to use for this interface.
1811 *
1812 * Return value: the alternative setting, typically zero
1813 *
1814 * Since: 0.5.4
1815 **/
1816 guint8
1817 dfu_target_get_alt_setting (DfuTarget *target)
1818 {
1819 DfuTargetPrivate *priv = GET_PRIVATE (target);
1820 g_return_val_if_fail (DFU_IS_TARGET (target), 0xff);
1821 return priv->alt_setting;
1822 }
1823
1824 /**
1825 * dfu_target_get_alt_name:
1826 * @target: a #DfuTarget
1827 * @error: a #GError, or %NULL
1828 *
1829 * Gets the alternate setting name to use for this interface.
1830 *
1831 * Return value: the alternative setting name, typically %NULL
1832 *
1833 * Since: 0.5.4
1834 **/
1835 const gchar *
1836 dfu_target_get_alt_name (DfuTarget *target, GError **error)
1837 {
1838 DfuTargetPrivate *priv = GET_PRIVATE (target);
1839 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
1840
1841 /* ensure populated */
1842 if (!dfu_target_setup (target, error))
1843 return NULL;
1844
1845 /* nothing */
1846 if (priv->alt_name == NULL) {
1847 g_set_error_literal (error,
1848 DFU_ERROR,
1849 DFU_ERROR_NOT_FOUND,
1850 "no alt-name");
1851 return NULL;
1852 }
1853
1854 return priv->alt_name;
1855 }
1856
1857 /**
1858 * dfu_target_get_alt_name_for_display:
1859 * @target: a #DfuTarget
1860 * @error: a #GError, or %NULL
1861 *
1862 * Gets the alternate setting name to use for this interface that can be
1863 * shown on the display.
1864 *
1865 * Return value: the alternative setting name
1866 *
1867 * Since: 0.7.5
1868 **/
1869 const gchar *
1870 dfu_target_get_alt_name_for_display (DfuTarget *target, GError **error)
1871 {
1872 DfuTargetPrivate *priv = GET_PRIVATE (target);
1873 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
1874
1875 /* ensure populated */
1876 if (!dfu_target_setup (target, error))
1877 return NULL;
1878
1879 /* nothing */
1880 if (priv->alt_name_for_display == NULL) {
1881 g_set_error_literal (error,
1882 DFU_ERROR,
1883 DFU_ERROR_NOT_FOUND,
1884 "no alt-name");
1885 return NULL;
1886 }
1887
1888 return priv->alt_name_for_display;
1889 }
1890
1891 /**
1892 * dfu_target_get_cipher_kind:
1893 * @target: a #DfuTarget
1894 *
1895 * Gets the cipher used for data sent to this interface.
1896 *
1897 * Return value: the cipher, typically %DFU_CIPHER_KIND_NONE
1898 *
1899 * Since: 0.5.4
1900 **/
1901 DfuCipherKind
1902 dfu_target_get_cipher_kind (DfuTarget *target)
1903 {
1904 DfuTargetPrivate *priv = GET_PRIVATE (target);
1905 g_return_val_if_fail (DFU_IS_TARGET (target), 0);
1906 return priv->cipher_kind;
1907 }
+0
-103
libdfu/dfu-target.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_TARGET_H
22 #define __DFU_TARGET_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-common.h"
29 #include "dfu-image.h"
30
31 G_BEGIN_DECLS
32
33 #define DFU_TYPE_TARGET (dfu_target_get_type ())
34 G_DECLARE_DERIVABLE_TYPE (DfuTarget, dfu_target, DFU, TARGET, GUsbDevice)
35
36 struct _DfuTargetClass
37 {
38 GUsbDeviceClass parent_class;
39 void (*percentage_changed) (DfuTarget *target,
40 guint percentage);
41 void (*action_changed) (DfuTarget *target,
42 DfuAction action);
43 /*< private >*/
44 /* Padding for future expansion */
45 void (*_dfu_target_reserved1) (void);
46 void (*_dfu_target_reserved2) (void);
47 void (*_dfu_target_reserved3) (void);
48 void (*_dfu_target_reserved4) (void);
49 void (*_dfu_target_reserved5) (void);
50 void (*_dfu_target_reserved6) (void);
51 void (*_dfu_target_reserved7) (void);
52 void (*_dfu_target_reserved8) (void);
53 };
54
55 /**
56 * DfuTargetTransferFlags:
57 * @DFU_TARGET_TRANSFER_FLAG_NONE: No flags set
58 * @DFU_TARGET_TRANSFER_FLAG_VERIFY: Verify the download once complete
59 * @DFU_TARGET_TRANSFER_FLAG_DETACH: If required, detach from runtime mode
60 * @DFU_TARGET_TRANSFER_FLAG_ATTACH: Attach the device back to runtime after completion
61 * @DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME: Wait for runtime to load after completion
62 * @DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID: Allow downloading images with wildcard VIDs
63 * @DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID: Allow downloading images with wildcard PIDs
64 * @DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER: Allow any cipher kinds to be downloaded
65 * @DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC: Automatically detect the address to use
66 *
67 * The optional flags used for transfering firmware.
68 **/
69 typedef enum {
70 DFU_TARGET_TRANSFER_FLAG_NONE = 0,
71 DFU_TARGET_TRANSFER_FLAG_VERIFY = (1 << 0),
72 DFU_TARGET_TRANSFER_FLAG_DETACH = (1 << 1),
73 DFU_TARGET_TRANSFER_FLAG_ATTACH = (1 << 2),
74 DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME = (1 << 3),
75 DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID = (1 << 4),
76 DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID = (1 << 5),
77 DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER = (1 << 6),
78 DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC = (1 << 7),
79 /*< private >*/
80 DFU_TARGET_TRANSFER_FLAG_LAST
81 } DfuTargetTransferFlags;
82
83 GPtrArray *dfu_target_get_sectors (DfuTarget *target);
84 guint8 dfu_target_get_alt_setting (DfuTarget *target);
85 const gchar *dfu_target_get_alt_name (DfuTarget *target,
86 GError **error);
87 const gchar *dfu_target_get_alt_name_for_display (DfuTarget *target,
88 GError **error);
89 DfuImage *dfu_target_upload (DfuTarget *target,
90 DfuTargetTransferFlags flags,
91 GCancellable *cancellable,
92 GError **error);
93 gboolean dfu_target_download (DfuTarget *target,
94 DfuImage *image,
95 DfuTargetTransferFlags flags,
96 GCancellable *cancellable,
97 GError **error);
98 DfuCipherKind dfu_target_get_cipher_kind (DfuTarget *target);
99
100 G_END_DECLS
101
102 #endif /* __DFU_TARGET_H */
+0
-2442
libdfu/dfu-tool.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "config.h"
22
23 #include <dfu.h>
24 #include <libintl.h>
25 #include <locale.h>
26 #include <stdlib.h>
27 #include <glib/gi18n.h>
28 #include <glib-unix.h>
29 #include <appstream-glib.h>
30
31 #include "dfu-cipher-devo.h"
32 #include "dfu-cipher-xtea.h"
33 #include "dfu-device-private.h"
34 #include "dfu-progress-bar.h"
35
36 typedef struct {
37 GCancellable *cancellable;
38 GPtrArray *cmd_array;
39 gboolean force;
40 gchar *device_vid_pid;
41 guint16 transfer_size;
42 DfuProgressBar *progress_bar;
43 } DfuToolPrivate;
44
45 static void
46 dfu_tool_print_indent (const gchar *title, const gchar *message, guint indent)
47 {
48 gsize i;
49 for (i = 0; i < indent; i++)
50 g_print (" ");
51 g_print ("%s:", title);
52 for (i = strlen (title) + indent; i < 15; i++)
53 g_print (" ");
54 g_print ("%s\n", message);
55 }
56
57 static void
58 dfu_tool_private_free (DfuToolPrivate *priv)
59 {
60 if (priv == NULL)
61 return;
62 g_free (priv->device_vid_pid);
63 g_object_unref (priv->cancellable);
64 if (priv->cmd_array != NULL)
65 g_ptr_array_unref (priv->cmd_array);
66 g_free (priv);
67 }
68 G_DEFINE_AUTOPTR_CLEANUP_FUNC(DfuToolPrivate, dfu_tool_private_free)
69
70 typedef gboolean (*FuUtilPrivateCb) (DfuToolPrivate *util,
71 gchar **values,
72 GError **error);
73
74 typedef struct {
75 gchar *name;
76 gchar *arguments;
77 gchar *description;
78 FuUtilPrivateCb callback;
79 } FuUtilItem;
80
81 static void
82 dfu_tool_item_free (FuUtilItem *item)
83 {
84 g_free (item->name);
85 g_free (item->arguments);
86 g_free (item->description);
87 g_free (item);
88 }
89
90 static gint
91 dfu_tool_sort_command_name_cb (FuUtilItem **item1, FuUtilItem **item2)
92 {
93 return g_strcmp0 ((*item1)->name, (*item2)->name);
94 }
95
96 static void
97 dfu_tool_add (GPtrArray *array,
98 const gchar *name,
99 const gchar *arguments,
100 const gchar *description,
101 FuUtilPrivateCb callback)
102 {
103 guint i;
104 FuUtilItem *item;
105 g_auto(GStrv) names = NULL;
106
107 g_return_if_fail (name != NULL);
108 g_return_if_fail (description != NULL);
109 g_return_if_fail (callback != NULL);
110
111 /* add each one */
112 names = g_strsplit (name, ",", -1);
113 for (i = 0; names[i] != NULL; i++) {
114 item = g_new0 (FuUtilItem, 1);
115 item->name = g_strdup (names[i]);
116 if (i == 0) {
117 item->description = g_strdup (description);
118 } else {
119 /* TRANSLATORS: this is a command alias, e.g. 'get-devices' */
120 item->description = g_strdup_printf (_("Alias to %s"),
121 names[0]);
122 }
123 item->arguments = g_strdup (arguments);
124 item->callback = callback;
125 g_ptr_array_add (array, item);
126 }
127 }
128
129 static gchar *
130 dfu_tool_get_descriptions (GPtrArray *array)
131 {
132 guint i;
133 gsize j;
134 gsize len;
135 const gsize max_len = 31;
136 FuUtilItem *item;
137 GString *string;
138
139 /* print each command */
140 string = g_string_new ("");
141 for (i = 0; i < array->len; i++) {
142 item = g_ptr_array_index (array, i);
143 g_string_append (string, " ");
144 g_string_append (string, item->name);
145 len = strlen (item->name) + 2;
146 if (item->arguments != NULL) {
147 g_string_append (string, " ");
148 g_string_append (string, item->arguments);
149 len += strlen (item->arguments) + 1;
150 }
151 if (len < max_len) {
152 for (j = len; j < max_len + 1; j++)
153 g_string_append_c (string, ' ');
154 g_string_append (string, item->description);
155 g_string_append_c (string, '\n');
156 } else {
157 g_string_append_c (string, '\n');
158 for (j = 0; j < max_len + 1; j++)
159 g_string_append_c (string, ' ');
160 g_string_append (string, item->description);
161 g_string_append_c (string, '\n');
162 }
163 }
164
165 /* remove trailing newline */
166 if (string->len > 0)
167 g_string_set_size (string, string->len - 1);
168
169 return g_string_free (string, FALSE);
170 }
171
172 static gboolean
173 dfu_tool_run (DfuToolPrivate *priv,
174 const gchar *command,
175 gchar **values,
176 GError **error)
177 {
178 guint i;
179 FuUtilItem *item;
180
181 /* find command */
182 for (i = 0; i < priv->cmd_array->len; i++) {
183 item = g_ptr_array_index (priv->cmd_array, i);
184 if (g_strcmp0 (item->name, command) == 0)
185 return item->callback (priv, values, error);
186 }
187
188 /* not found */
189 g_set_error_literal (error,
190 DFU_ERROR,
191 DFU_ERROR_INTERNAL,
192 /* TRANSLATORS: error message */
193 _("Command not found"));
194 return FALSE;
195 }
196
197 static DfuDevice *
198 dfu_tool_get_defalt_device (DfuToolPrivate *priv, GError **error)
199 {
200 DfuDevice *device;
201 g_autoptr(DfuContext) dfu_context = NULL;
202
203 /* get all the DFU devices */
204 dfu_context = dfu_context_new ();
205 dfu_context_enumerate (dfu_context, NULL);
206
207 /* we specified it manually */
208 if (priv->device_vid_pid != NULL) {
209 gchar *tmp;
210 guint64 pid;
211 guint64 vid;
212
213 /* parse */
214 vid = g_ascii_strtoull (priv->device_vid_pid, &tmp, 16);
215 if (vid == 0 || vid > G_MAXUINT16) {
216 g_set_error_literal (error,
217 DFU_ERROR,
218 DFU_ERROR_INTERNAL,
219 "Invalid format of VID:PID");
220 return NULL;
221 }
222 if (tmp[0] != ':') {
223 g_set_error_literal (error,
224 DFU_ERROR,
225 DFU_ERROR_INTERNAL,
226 "Invalid format of VID:PID");
227 return NULL;
228 }
229 pid = g_ascii_strtoull (tmp + 1, NULL, 16);
230 if (pid == 0 || pid > G_MAXUINT16) {
231 g_set_error_literal (error,
232 DFU_ERROR,
233 DFU_ERROR_INTERNAL,
234 "Invalid format of VID:PID");
235 return NULL;
236 }
237
238 /* find device */
239 device = dfu_context_get_device_by_vid_pid (dfu_context,
240 (guint16) vid,
241 (guint16) pid,
242 error);
243 if (device == NULL)
244 return NULL;
245 } else {
246 /* auto-detect first device */
247 device = dfu_context_get_device_default (dfu_context, error);
248 if (device == NULL)
249 return NULL;
250 }
251
252 /* this has to be added to the device so we can deal with detach */
253 g_object_set_data_full (G_OBJECT (device), "DfuContext",
254 g_object_ref (dfu_context),
255 (GDestroyNotify) g_object_unref);
256 return device;
257 }
258
259 static gboolean
260 dfu_tool_set_vendor (DfuToolPrivate *priv, gchar **values, GError **error)
261 {
262 guint64 tmp;
263 g_autoptr(DfuFirmware) firmware = NULL;
264 g_autoptr(GFile) file = NULL;
265
266 /* check args */
267 if (g_strv_length (values) < 2) {
268 g_set_error_literal (error,
269 DFU_ERROR,
270 DFU_ERROR_INTERNAL,
271 "Invalid arguments, expected FILE VID"
272 " -- e.g. `firmware.dfu 273f");
273 return FALSE;
274 }
275
276 /* open */
277 file = g_file_new_for_path (values[0]);
278 firmware = dfu_firmware_new ();
279 if (!dfu_firmware_parse_file (firmware, file,
280 DFU_FIRMWARE_PARSE_FLAG_NONE,
281 priv->cancellable,
282 error)) {
283 return FALSE;
284 }
285
286 /* parse VID */
287 tmp = g_ascii_strtoull (values[1], NULL, 16);
288 if (tmp == 0 || tmp > G_MAXUINT16) {
289 g_set_error (error,
290 DFU_ERROR,
291 DFU_ERROR_INTERNAL,
292 "Failed to parse VID '%s'",
293 values[1]);
294 return FALSE;
295 }
296 dfu_firmware_set_vid (firmware, (guint16) tmp);
297
298 /* write out new file */
299 return dfu_firmware_write_file (firmware,
300 file,
301 priv->cancellable,
302 error);
303 }
304
305 static gboolean
306 dfu_tool_set_product (DfuToolPrivate *priv, gchar **values, GError **error)
307 {
308 guint64 tmp;
309 g_autoptr(DfuFirmware) firmware = NULL;
310 g_autoptr(GFile) file = NULL;
311
312 /* check args */
313 if (g_strv_length (values) < 2) {
314 g_set_error_literal (error,
315 DFU_ERROR,
316 DFU_ERROR_INTERNAL,
317 "Invalid arguments, expected FILE PID"
318 " -- e.g. `firmware.dfu 1004");
319 return FALSE;
320 }
321
322 /* open */
323 file = g_file_new_for_path (values[0]);
324 firmware = dfu_firmware_new ();
325 if (!dfu_firmware_parse_file (firmware, file,
326 DFU_FIRMWARE_PARSE_FLAG_NONE,
327 priv->cancellable,
328 error)) {
329 return FALSE;
330 }
331
332 /* parse VID */
333 tmp = g_ascii_strtoull (values[1], NULL, 16);
334 if (tmp == 0 || tmp > G_MAXUINT16) {
335 g_set_error (error,
336 DFU_ERROR,
337 DFU_ERROR_INTERNAL,
338 "Failed to parse PID '%s'", values[1]);
339 return FALSE;
340 }
341 dfu_firmware_set_pid (firmware, (guint16) tmp);
342
343 /* write out new file */
344 return dfu_firmware_write_file (firmware,
345 file,
346 priv->cancellable,
347 error);
348 }
349
350 static guint16
351 dfu_tool_parse_release_uint16 (const gchar *version, GError **error)
352 {
353 gchar *endptr = NULL;
354 guint64 tmp_lsb, tmp_msb;
355 g_auto(GStrv) split = g_strsplit (version, ".", -1);
356
357 /* check if valid */
358 if (g_strv_length (split) != 2) {
359 g_set_error_literal (error,
360 DFU_ERROR,
361 DFU_ERROR_INTERNAL,
362 "invalid format, expected 'major.minor'");
363 return 0xffff;
364 }
365
366 /* parse MSB & LSB */
367 tmp_msb = g_ascii_strtoull (split[0], &endptr, 10);
368 if (tmp_msb > 0xff || endptr[0] != '\0') {
369 g_set_error (error,
370 DFU_ERROR,
371 DFU_ERROR_INTERNAL,
372 "Failed to parse version '%s'",
373 version);
374 return 0xffff;
375 }
376 tmp_lsb = g_ascii_strtoull (split[1], &endptr, 10);
377 if (tmp_lsb > 0xff || endptr[0] != '\0') {
378 g_set_error (error,
379 DFU_ERROR,
380 DFU_ERROR_INTERNAL,
381 "Failed to parse version '%s'",
382 version);
383 return 0xffff;
384 }
385 return (tmp_msb << 8) + tmp_lsb;
386 }
387
388 static gboolean
389 dfu_tool_set_release (DfuToolPrivate *priv, gchar **values, GError **error)
390 {
391 gchar *endptr = NULL;
392 guint64 tmp;
393 g_autoptr(DfuFirmware) firmware = NULL;
394 g_autoptr(GFile) file = NULL;
395
396 /* check args */
397 if (g_strv_length (values) < 2) {
398 g_set_error_literal (error,
399 DFU_ERROR,
400 DFU_ERROR_INTERNAL,
401 "Invalid arguments, expected FILE RELEASE"
402 " -- e.g. `firmware.dfu ffff");
403 return FALSE;
404 }
405
406 /* open */
407 file = g_file_new_for_path (values[0]);
408 firmware = dfu_firmware_new ();
409 if (!dfu_firmware_parse_file (firmware, file,
410 DFU_FIRMWARE_PARSE_FLAG_NONE,
411 priv->cancellable,
412 error)) {
413 return FALSE;
414 }
415
416 /* parse release */
417 tmp = g_ascii_strtoull (values[1], &endptr, 16);
418 if (tmp > G_MAXUINT16 || endptr[0] != '\0') {
419 tmp = dfu_tool_parse_release_uint16 (values[1], error);
420 if (tmp == 0xffff)
421 return FALSE;
422 }
423 dfu_firmware_set_release (firmware, (guint16) tmp);
424
425 /* write out new file */
426 return dfu_firmware_write_file (firmware,
427 file,
428 priv->cancellable,
429 error);
430 }
431
432 static GBytes *
433 dfu_tool_parse_hex_string (const gchar *val, GError **error)
434 {
435 gsize result_size;
436 guint i;
437 g_autofree guint8 *result = NULL;
438
439 /* sanity check */
440 if (val == NULL) {
441 g_set_error_literal (error,
442 DFU_ERROR,
443 DFU_ERROR_INTERNAL,
444 "nothing to parse");
445 return NULL;
446 }
447
448 /* parse each hex byte */
449 result_size = strlen (val) / 2;
450 result = g_malloc (result_size);
451 for (i = 0; i < result_size; i++) {
452 gchar buf[3] = { "xx" };
453 gchar *endptr = NULL;
454 guint64 tmp;
455
456 /* copy two bytes and parse as hex */
457 memcpy (buf, val + (i * 2), 2);
458 tmp = g_ascii_strtoull (buf, &endptr, 16);
459 if (tmp > 0xff || endptr[0] != '\0') {
460 g_set_error (error,
461 DFU_ERROR,
462 DFU_ERROR_INTERNAL,
463 "failed to parse '%s'", val);
464 return NULL;
465 }
466 result[i] = tmp;
467 }
468 return g_bytes_new (result, result_size);
469 }
470
471 static guint
472 dfu_tool_bytes_replace (GBytes *data, GBytes *search, GBytes *replace)
473 {
474 gsize data_sz;
475 gsize i;
476 gsize replace_sz;
477 gsize search_sz;
478 guint8 *data_buf;
479 guint8 *replace_buf;
480 guint8 *search_buf;
481 guint cnt = 0;
482
483 data_buf = (gpointer) g_bytes_get_data (data, &data_sz);
484 search_buf = (gpointer) g_bytes_get_data (search, &search_sz);
485 replace_buf = (gpointer) g_bytes_get_data (replace, &replace_sz);
486
487 g_return_val_if_fail (search_sz == replace_sz, FALSE);
488
489 /* find and replace each one */
490 for (i = 0; i < data_sz - search_sz; i++) {
491 if (memcmp (data_buf + i, search_buf, search_sz) == 0) {
492 g_print ("Replacing %" G_GSIZE_FORMAT " bytes @0x%04x\n",
493 replace_sz, (guint) i);
494 memcpy (data_buf + i, replace_buf, replace_sz);
495 i += replace_sz;
496 cnt++;
497 }
498 }
499 return cnt;
500 }
501
502 static gboolean
503 dfu_tool_patch_dump (DfuToolPrivate *priv, gchar **values, GError **error)
504 {
505 gsize sz = 0;
506 g_autofree gchar *data = NULL;
507 g_autofree gchar *str = NULL;
508 g_autoptr(DfuPatch) patch = NULL;
509 g_autoptr(GBytes) blob = NULL;
510
511 if (g_strv_length (values) != 1) {
512 g_set_error_literal (error,
513 DFU_ERROR,
514 DFU_ERROR_INTERNAL,
515 "Invalid arguments, expected FILE.bdiff");
516 return FALSE;
517 }
518
519 /* load file */
520 if (!g_file_get_contents (values[0], &data, &sz, error))
521 return FALSE;
522 blob = g_bytes_new (data, sz);
523
524 /* dump the patch to disk */
525 patch = dfu_patch_new ();
526 if (!dfu_patch_import (patch, blob, error))
527 return FALSE;
528 str = dfu_patch_to_string (patch);
529 g_print ("%s\n", str);
530
531 /* success */
532 return TRUE;
533 }
534
535 static gboolean
536 dfu_tool_patch_apply (DfuToolPrivate *priv, gchar **values, GError **error)
537 {
538 DfuPatchApplyFlags flags = DFU_PATCH_APPLY_FLAG_NONE;
539 const gchar *data_new;
540 gsize sz_diff = 0;
541 gsize sz_new = 0;
542 gsize sz_old = 0;
543 g_autofree gchar *data_diff = NULL;
544 g_autofree gchar *data_old = NULL;
545 g_autoptr(DfuPatch) patch = NULL;
546 g_autoptr(GBytes) blob_diff = NULL;
547 g_autoptr(GBytes) blob_new = NULL;
548 g_autoptr(GBytes) blob_old = NULL;
549
550 if (g_strv_length (values) != 3) {
551 g_set_error_literal (error,
552 DFU_ERROR,
553 DFU_ERROR_INTERNAL,
554 "Invalid arguments, expected OLD.bin OUT.bdiff NEW.bin");
555 return FALSE;
556 }
557
558 /* allow the user to shoot themselves in the foot */
559 if (priv->force)
560 flags |= DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM;
561
562 if (!g_file_get_contents (values[0], &data_old, &sz_old, error))
563 return FALSE;
564 blob_old = g_bytes_new (data_old, sz_old);
565 if (!g_file_get_contents (values[1], &data_diff, &sz_diff, error))
566 return FALSE;
567 blob_diff = g_bytes_new (data_diff, sz_diff);
568 patch = dfu_patch_new ();
569 if (!dfu_patch_import (patch, blob_diff, error))
570 return FALSE;
571 blob_new = dfu_patch_apply (patch, blob_old, flags, error);
572 if (blob_new == NULL)
573 return FALSE;
574
575 /* save to disk */
576 data_new = g_bytes_get_data (blob_new, &sz_new);
577 return g_file_set_contents (values[2], data_new, sz_new, error);
578 }
579
580 static gboolean
581 dfu_tool_patch_create (DfuToolPrivate *priv, gchar **values, GError **error)
582 {
583 const gchar *data_diff;
584 gsize sz_diff = 0;
585 gsize sz_new = 0;
586 gsize sz_old = 0;
587 g_autofree gchar *data_new = NULL;
588 g_autofree gchar *data_old = NULL;
589 g_autoptr(DfuPatch) patch = NULL;
590 g_autoptr(GBytes) blob_diff = NULL;
591 g_autoptr(GBytes) blob_new = NULL;
592 g_autoptr(GBytes) blob_old = NULL;
593
594 if (g_strv_length (values) != 3) {
595 g_set_error_literal (error,
596 DFU_ERROR,
597 DFU_ERROR_INTERNAL,
598 "Invalid arguments, expected OLD.bin NEW.bin OUT.bdiff");
599 return FALSE;
600 }
601
602 /* read files */
603 if (!g_file_get_contents (values[0], &data_old, &sz_old, error))
604 return FALSE;
605 blob_old = g_bytes_new (data_old, sz_old);
606 if (!g_file_get_contents (values[1], &data_new, &sz_new, error))
607 return FALSE;
608 blob_new = g_bytes_new (data_new, sz_new);
609
610 /* create patch */
611 patch = dfu_patch_new ();
612 if (!dfu_patch_create (patch, blob_old, blob_new, error))
613 return FALSE;
614 blob_diff = dfu_patch_export (patch, error);
615 if (blob_diff == NULL)
616 return FALSE;
617
618 /* save to disk */
619 data_diff = g_bytes_get_data (blob_diff, &sz_diff);
620 return g_file_set_contents (values[2], data_diff, sz_diff, error);
621 }
622
623 static gboolean
624 dfu_tool_replace_data (DfuToolPrivate *priv, gchar **values, GError **error)
625 {
626 GPtrArray *images;
627 guint i;
628 guint j;
629 guint cnt = 0;
630 g_autoptr(DfuFirmware) firmware = NULL;
631 g_autoptr(GFile) file = NULL;
632 g_autoptr(GBytes) data_search = NULL;
633 g_autoptr(GBytes) data_replace = NULL;
634
635 /* check args */
636 if (g_strv_length (values) < 3) {
637 g_set_error_literal (error,
638 DFU_ERROR,
639 DFU_ERROR_INTERNAL,
640 "Invalid arguments, expected FILE SEARCH REPLACE"
641 " -- e.g. `firmware.dfu deadbeef beefdead");
642 return FALSE;
643 }
644
645 /* open */
646 file = g_file_new_for_path (values[0]);
647 firmware = dfu_firmware_new ();
648 if (!dfu_firmware_parse_file (firmware, file,
649 DFU_FIRMWARE_PARSE_FLAG_NONE,
650 priv->cancellable,
651 error)) {
652 return FALSE;
653 }
654
655 /* parse hex values */
656 data_search = dfu_tool_parse_hex_string (values[1], error);
657 if (data_search == NULL)
658 return FALSE;
659 data_replace = dfu_tool_parse_hex_string (values[2], error);
660 if (data_replace == NULL)
661 return FALSE;
662 if (g_bytes_get_size (data_search) != g_bytes_get_size (data_replace)) {
663 g_set_error_literal (error,
664 DFU_ERROR,
665 DFU_ERROR_INTERNAL,
666 "search and replace were different sizes");
667 return FALSE;
668 }
669
670 /* get each data segment */
671 images = dfu_firmware_get_images (firmware);
672 for (i = 0; i < images->len; i++) {
673 DfuImage *image = g_ptr_array_index (images, i);
674 GPtrArray *elements = dfu_image_get_elements (image);
675 for (j = 0; j < elements->len; j++) {
676 DfuElement *element = g_ptr_array_index (elements, j);
677 GBytes *contents = dfu_element_get_contents (element);
678 if (contents == NULL)
679 continue;
680 cnt += dfu_tool_bytes_replace (contents, data_search, data_replace);
681 }
682 }
683
684 /* nothing done */
685 if (cnt == 0) {
686 g_set_error_literal (error,
687 DFU_ERROR,
688 DFU_ERROR_INTERNAL,
689 "search string was not found");
690 return FALSE;
691 }
692
693 /* write out new file */
694 return dfu_firmware_write_file (firmware,
695 file,
696 priv->cancellable,
697 error);
698 }
699
700 static gboolean
701 dfu_tool_set_target_size (DfuToolPrivate *priv, gchar **values, GError **error)
702 {
703 DfuElement *element;
704 DfuImage *image;
705 gchar *endptr;
706 guint64 padding_char = 0x00;
707 guint64 target_size;
708 g_autoptr(DfuFirmware) firmware = NULL;
709 g_autoptr(GFile) file = NULL;
710
711 /* check args */
712 if (g_strv_length (values) < 2) {
713 g_set_error_literal (error,
714 DFU_ERROR,
715 DFU_ERROR_INTERNAL,
716 "Invalid arguments, expected FILE SIZE [VAL]"
717 " -- e.g. `firmware.dfu 8000 ff");
718 return FALSE;
719 }
720
721 /* open */
722 file = g_file_new_for_path (values[0]);
723 firmware = dfu_firmware_new ();
724 if (!dfu_firmware_parse_file (firmware, file,
725 DFU_FIRMWARE_PARSE_FLAG_NONE,
726 priv->cancellable,
727 error)) {
728 return FALSE;
729 }
730
731 /* doesn't make sense for DfuSe */
732 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) {
733 g_set_error (error,
734 DFU_ERROR,
735 DFU_ERROR_INTERNAL,
736 "Cannot pad DfuSe image, try DFU");
737 return FALSE;
738 }
739
740 /* parse target size */
741 target_size = g_ascii_strtoull (values[1], &endptr, 16);
742 if (target_size > 0xffff || endptr[0] != '\0') {
743 g_set_error (error,
744 DFU_ERROR,
745 DFU_ERROR_INTERNAL,
746 "Failed to parse target size '%s'",
747 values[1]);
748 return FALSE;
749 }
750
751 /* parse padding value */
752 if (g_strv_length (values) > 3) {
753 padding_char = g_ascii_strtoull (values[2], &endptr, 16);
754 if (padding_char > 0xff || endptr[0] != '\0') {
755 g_set_error (error,
756 DFU_ERROR,
757 DFU_ERROR_INTERNAL,
758 "Failed to parse padding value '%s'",
759 values[2]);
760 return FALSE;
761 }
762 }
763
764 /* this has to exist */
765 if (target_size > 0) {
766 image = dfu_firmware_get_image_default (firmware);
767 g_assert (image != NULL);
768 element = dfu_image_get_element (image, 0);
769 dfu_element_set_padding_value (element, (guint8) padding_char);
770 dfu_element_set_target_size (element, (guint32) target_size);
771 }
772
773 /* write out new file */
774 return dfu_firmware_write_file (firmware,
775 file,
776 priv->cancellable,
777 error);
778 }
779
780 static gboolean
781 dfu_tool_set_address (DfuToolPrivate *priv, gchar **values, GError **error)
782 {
783 DfuElement *element;
784 DfuFirmwareFormat firmware_format;
785 DfuImage *image;
786 gchar *endptr;
787 guint64 address;
788 g_autoptr(DfuFirmware) firmware = NULL;
789 g_autoptr(GFile) file = NULL;
790
791 /* check args */
792 if (g_strv_length (values) < 2) {
793 g_set_error_literal (error,
794 DFU_ERROR,
795 DFU_ERROR_INTERNAL,
796 "Invalid arguments, expected FILE ADDR"
797 " -- e.g. `firmware.dfu 8000");
798 return FALSE;
799 }
800
801 /* open */
802 file = g_file_new_for_path (values[0]);
803 firmware = dfu_firmware_new ();
804 if (!dfu_firmware_parse_file (firmware, file,
805 DFU_FIRMWARE_PARSE_FLAG_NONE,
806 priv->cancellable,
807 error)) {
808 return FALSE;
809 }
810
811 /* only makes sense for DfuSe */
812 firmware_format = dfu_firmware_get_format (firmware);
813 if (firmware_format != DFU_FIRMWARE_FORMAT_DFUSE) {
814 g_set_error (error,
815 DFU_ERROR,
816 DFU_ERROR_INTERNAL,
817 "Cannot set address of %s image, try DfuSe",
818 dfu_firmware_format_to_string (firmware_format));
819 return FALSE;
820 }
821
822 /* parse address */
823 address = g_ascii_strtoull (values[1], &endptr, 16);
824 if (address > G_MAXUINT32 || endptr[0] != '\0') {
825 g_set_error (error,
826 DFU_ERROR,
827 DFU_ERROR_INTERNAL,
828 "Failed to parse address '%s'",
829 values[1]);
830 return FALSE;
831 }
832
833 /* this has to exist */
834 if (address > 0) {
835 image = dfu_firmware_get_image_default (firmware);
836 g_assert (image != NULL);
837 element = dfu_image_get_element (image, 0);
838 dfu_element_set_address (element, (guint32) address);
839 }
840
841 /* write out new file */
842 return dfu_firmware_write_file (firmware,
843 file,
844 priv->cancellable,
845 error);
846 }
847
848 static gboolean
849 dfu_tool_set_metadata (DfuToolPrivate *priv, gchar **values, GError **error)
850 {
851 g_autoptr(DfuFirmware) firmware = NULL;
852 g_autoptr(GFile) file = NULL;
853
854 /* check args */
855 if (g_strv_length (values) < 3) {
856 g_set_error_literal (error,
857 DFU_ERROR,
858 DFU_ERROR_INTERNAL,
859 "Invalid arguments, expected FILE KEY VALUE"
860 " -- e.g. `firmware.dfu Licence GPL-2.0+");
861 return FALSE;
862 }
863
864 /* open */
865 file = g_file_new_for_path (values[0]);
866 firmware = dfu_firmware_new ();
867 if (!dfu_firmware_parse_file (firmware, file,
868 DFU_FIRMWARE_PARSE_FLAG_NONE,
869 priv->cancellable,
870 error)) {
871 return FALSE;
872 }
873
874 /* doesn't make sense for non-DFU */
875 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_RAW) {
876 g_set_error (error,
877 DFU_ERROR,
878 DFU_ERROR_INTERNAL,
879 "Only possible on DFU/DfuSe images, try convert");
880 return FALSE;
881 }
882
883 /* set metadata */
884 dfu_firmware_set_metadata (firmware, values[1], values[2]);
885
886 /* write out new file */
887 return dfu_firmware_write_file (firmware,
888 file,
889 priv->cancellable,
890 error);
891 }
892
893 static gboolean
894 dfu_tool_set_alt_setting (DfuToolPrivate *priv, gchar **values, GError **error)
895 {
896 DfuImage *image;
897 guint64 tmp;
898 g_autoptr(DfuFirmware) firmware = NULL;
899 g_autoptr(GFile) file = NULL;
900
901 /* check args */
902 if (g_strv_length (values) < 2) {
903 g_set_error_literal (error,
904 DFU_ERROR,
905 DFU_ERROR_INTERNAL,
906 "Invalid arguments, expected FILE ALT-ID"
907 " -- e.g. `firmware.dfu 1");
908 return FALSE;
909 }
910
911 /* open */
912 file = g_file_new_for_path (values[0]);
913 firmware = dfu_firmware_new ();
914 if (!dfu_firmware_parse_file (firmware, file,
915 DFU_FIRMWARE_PARSE_FLAG_NONE,
916 priv->cancellable,
917 error)) {
918 return FALSE;
919 }
920
921 /* doesn't make sense for non-DfuSe */
922 if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) {
923 g_set_error (error,
924 DFU_ERROR,
925 DFU_ERROR_INTERNAL,
926 "Only possible on DfuSe images, try convert");
927 return FALSE;
928 }
929
930 /* parse VID */
931 tmp = g_ascii_strtoull (values[1], NULL, 10);
932 if (tmp == 0 || tmp > G_MAXUINT8) {
933 g_set_error (error,
934 DFU_ERROR,
935 DFU_ERROR_INTERNAL,
936 "Failed to parse alternative setting '%s'",
937 values[1]);
938 return FALSE;
939 }
940 image = dfu_firmware_get_image_default (firmware);
941 if (image == NULL) {
942 g_set_error (error,
943 DFU_ERROR,
944 DFU_ERROR_INTERNAL,
945 "found no image '%s'", values[1]);
946 return FALSE;
947 }
948 dfu_image_set_alt_setting (image, (guint8) tmp);
949
950 /* write out new file */
951 return dfu_firmware_write_file (firmware,
952 file,
953 priv->cancellable,
954 error);
955 }
956
957 static gboolean
958 dfu_tool_set_alt_setting_name (DfuToolPrivate *priv, gchar **values, GError **error)
959 {
960 DfuImage *image;
961 g_autoptr(DfuFirmware) firmware = NULL;
962 g_autoptr(GFile) file = NULL;
963
964 /* check args */
965 if (g_strv_length (values) < 2) {
966 g_set_error_literal (error,
967 DFU_ERROR,
968 DFU_ERROR_INTERNAL,
969 "Invalid arguments, expected FILE ALT-NAME"
970 " -- e.g. `firmware.dfu ST");
971 return FALSE;
972 }
973
974 /* open */
975 file = g_file_new_for_path (values[0]);
976 firmware = dfu_firmware_new ();
977 if (!dfu_firmware_parse_file (firmware, file,
978 DFU_FIRMWARE_PARSE_FLAG_NONE,
979 priv->cancellable,
980 error)) {
981 return FALSE;
982 }
983
984 /* doesn't make sense for non-DfuSe */
985 if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) {
986 g_set_error (error,
987 DFU_ERROR,
988 DFU_ERROR_INTERNAL,
989 "Only possible on DfuSe images, try convert");
990 return FALSE;
991 }
992
993 /* parse VID */
994 image = dfu_firmware_get_image_default (firmware);
995 if (image == NULL) {
996 g_set_error (error,
997 DFU_ERROR,
998 DFU_ERROR_INTERNAL,
999 "found no image '%s'", values[1]);
1000 return FALSE;
1001 }
1002 dfu_image_set_name (image, values[1]);
1003
1004 /* write out new file */
1005 return dfu_firmware_write_file (firmware,
1006 file,
1007 priv->cancellable,
1008 error);
1009 }
1010
1011 static gboolean
1012 dfu_tool_merge (DfuToolPrivate *priv, gchar **values, GError **error)
1013 {
1014 guint16 pid = 0xffff;
1015 guint16 rel = 0xffff;
1016 guint16 vid = 0xffff;
1017 guint i;
1018 g_autofree gchar *str_debug = NULL;
1019 g_autoptr(DfuFirmware) firmware = NULL;
1020 g_autoptr(GFile) file = NULL;
1021
1022 /* check args */
1023 if (g_strv_length (values) < 3) {
1024 g_set_error_literal (error,
1025 DFU_ERROR,
1026 DFU_ERROR_INTERNAL,
1027 "Invalid arguments, expected "
1028 "FILE-OUT FILE1 FILE2 [FILE3...]"
1029 " -- e.g. `combined.dfu lib.dfu app.dfu`");
1030 return FALSE;
1031 }
1032
1033 /* parse source files */
1034 firmware = dfu_firmware_new ();
1035 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFUSE);
1036 for (i = 1; values[i] != NULL; i++) {
1037 GPtrArray *images;
1038 guint j;
1039 g_autoptr(GFile) file_tmp = NULL;
1040 g_autoptr(DfuFirmware) firmware_tmp = NULL;
1041
1042 /* open up source */
1043 file_tmp = g_file_new_for_path (values[i]);
1044 firmware_tmp = dfu_firmware_new ();
1045 if (!dfu_firmware_parse_file (firmware_tmp, file_tmp,
1046 DFU_FIRMWARE_PARSE_FLAG_NONE,
1047 priv->cancellable,
1048 error)) {
1049 return FALSE;
1050 }
1051
1052 /* check same vid:pid:rel */
1053 if (vid != 0xffff &&
1054 dfu_firmware_get_vid (firmware_tmp) != vid) {
1055 g_set_error (error,
1056 DFU_ERROR,
1057 DFU_ERROR_INVALID_FILE,
1058 "Vendor ID was already set as "
1059 "0x%04x, %s is 0x%04x",
1060 vid, values[i],
1061 dfu_firmware_get_vid (firmware_tmp));
1062 return FALSE;
1063 }
1064 if (pid != 0xffff &&
1065 dfu_firmware_get_pid (firmware_tmp) != pid) {
1066 g_set_error (error,
1067 DFU_ERROR,
1068 DFU_ERROR_INVALID_FILE,
1069 "Product ID was already set as "
1070 "0x%04x, %s is 0x%04x",
1071 pid, values[i],
1072 dfu_firmware_get_pid (firmware_tmp));
1073 return FALSE;
1074 }
1075 if (rel != 0xffff &&
1076 dfu_firmware_get_release (firmware_tmp) != rel) {
1077 g_set_error (error,
1078 DFU_ERROR,
1079 DFU_ERROR_INVALID_FILE,
1080 "Release was already set as "
1081 "0x%04x, %s is 0x%04x",
1082 rel, values[i],
1083 dfu_firmware_get_release (firmware_tmp));
1084 return FALSE;
1085 }
1086
1087 /* add all images to destination */
1088 images = dfu_firmware_get_images (firmware_tmp);
1089 for (j = 0; j < images->len; j++) {
1090 DfuImage *image;
1091 guint8 alt_id;
1092
1093 /* verify the alt-setting does not already exist */
1094 image = g_ptr_array_index (images, j);
1095 alt_id = dfu_image_get_alt_setting (image);
1096 g_print ("Adding alternative setting ID of 0x%02x\n",
1097 alt_id);
1098 if (dfu_firmware_get_image (firmware, alt_id) != NULL) {
1099 if (!priv->force) {
1100 g_set_error (error,
1101 DFU_ERROR,
1102 DFU_ERROR_INVALID_FILE,
1103 "The alternative setting ID "
1104 "of 0x%02x has already been added",
1105 alt_id);
1106 return FALSE;
1107 }
1108 g_print ("WARNING: The alternative setting "
1109 "ID of 0x%02x has already been added\n",
1110 alt_id);
1111 }
1112
1113 /* add to destination */
1114 dfu_firmware_add_image (firmware, image);
1115 }
1116
1117 /* save last IDs */
1118 vid = dfu_firmware_get_vid (firmware_tmp);
1119 pid = dfu_firmware_get_pid (firmware_tmp);
1120 rel = dfu_firmware_get_release (firmware_tmp);
1121 }
1122
1123 /* print the new object */
1124 str_debug = dfu_firmware_to_string (firmware);
1125 g_print ("New merged file:\n%s\n", str_debug);
1126
1127 /* write out new file */
1128 file = g_file_new_for_path (values[0]);
1129 return dfu_firmware_write_file (firmware,
1130 file,
1131 priv->cancellable,
1132 error);
1133 }
1134
1135 static gboolean
1136 dfu_tool_convert (DfuToolPrivate *priv, gchar **values, GError **error)
1137 {
1138 DfuFirmwareFormat format;
1139 guint argc = g_strv_length (values);
1140 g_autofree gchar *str_debug = NULL;
1141 g_autoptr(DfuFirmware) firmware = NULL;
1142 g_autoptr(GFile) file_in = NULL;
1143 g_autoptr(GFile) file_out = NULL;
1144
1145 /* check args */
1146 if (argc != 3) {
1147 g_set_error_literal (error,
1148 DFU_ERROR,
1149 DFU_ERROR_INTERNAL,
1150 "Invalid arguments, expected "
1151 "FORMAT FILE-IN FILE-OUT"
1152 " -- e.g. `dfu firmware.hex firmware.dfu`");
1153 return FALSE;
1154 }
1155
1156 /* parse file */
1157 file_in = g_file_new_for_path (values[1]);
1158 file_out = g_file_new_for_path (values[2]);
1159 firmware = dfu_firmware_new ();
1160 if (!dfu_firmware_parse_file (firmware, file_in,
1161 DFU_FIRMWARE_PARSE_FLAG_NONE,
1162 priv->cancellable,
1163 error)) {
1164 return FALSE;
1165 }
1166
1167 /* set output format */
1168 format = dfu_firmware_format_from_string (values[0]);
1169 dfu_firmware_set_format (firmware, format);
1170 if (format == DFU_FIRMWARE_FORMAT_UNKNOWN) {
1171 g_autoptr(GString) tmp = g_string_new (NULL);
1172 for (guint i = 1; i < DFU_FIRMWARE_FORMAT_LAST; i++) {
1173 if (tmp->len > 0)
1174 g_string_append (tmp, "|");
1175 g_string_append (tmp, dfu_firmware_format_to_string (i));
1176 }
1177 g_set_error (error,
1178 DFU_ERROR,
1179 DFU_ERROR_INTERNAL,
1180 "unknown format '%s', expected [%s]",
1181 values[0], tmp->str);
1182 return FALSE;
1183 }
1184
1185 /* print the new object */
1186 str_debug = dfu_firmware_to_string (firmware);
1187 g_debug ("DFU: %s", str_debug);
1188
1189 /* write out new file */
1190 return dfu_firmware_write_file (firmware,
1191 file_out,
1192 priv->cancellable,
1193 error);
1194 }
1195
1196 static gboolean
1197 dfu_tool_attach (DfuToolPrivate *priv, gchar **values, GError **error)
1198 {
1199 g_autoptr(DfuDevice) device = NULL;
1200
1201 device = dfu_tool_get_defalt_device (priv, error);
1202 if (device == NULL)
1203 return FALSE;
1204 if (!dfu_device_open (device,
1205 DFU_DEVICE_OPEN_FLAG_NONE,
1206 priv->cancellable,
1207 error))
1208 return FALSE;
1209 if (!dfu_device_attach (device, error))
1210 return FALSE;
1211 return TRUE;
1212 }
1213
1214 static void
1215 fu_tool_percentage_changed_cb (DfuDevice *device,
1216 guint percentage,
1217 DfuToolPrivate *priv)
1218 {
1219 dfu_progress_bar_set_percentage (priv->progress_bar, percentage);
1220 }
1221
1222 static void
1223 fu_tool_action_changed_cb (DfuDevice *device,
1224 DfuAction action,
1225 DfuToolPrivate *priv)
1226 {
1227 switch (action) {
1228 case DFU_ACTION_IDLE:
1229 dfu_progress_bar_set_percentage (priv->progress_bar, 100);
1230 dfu_progress_bar_end (priv->progress_bar);
1231 break;
1232 case DFU_ACTION_READ:
1233 dfu_progress_bar_start (priv->progress_bar,
1234 /* TRANSLATORS: read from device to host */
1235 _("Reading"));
1236 dfu_progress_bar_set_percentage (priv->progress_bar, 0);
1237 break;
1238 case DFU_ACTION_WRITE:
1239 dfu_progress_bar_start (priv->progress_bar,
1240 /* TRANSLATORS: write from host to device */
1241 _("Writing"));
1242 dfu_progress_bar_set_percentage (priv->progress_bar, 0);
1243 break;
1244 case DFU_ACTION_VERIFY:
1245 dfu_progress_bar_start (priv->progress_bar,
1246 /* TRANSLATORS: read from device to host */
1247 _("Verifying"));
1248 dfu_progress_bar_set_percentage (priv->progress_bar, 0);
1249 break;
1250 case DFU_ACTION_ERASE:
1251 dfu_progress_bar_start (priv->progress_bar,
1252 /* TRANSLATORS: read from device to host */
1253 _("Erasing"));
1254 dfu_progress_bar_set_percentage (priv->progress_bar, 0);
1255 break;
1256 case DFU_ACTION_DETACH:
1257 dfu_progress_bar_start (priv->progress_bar,
1258 /* TRANSLATORS: waiting for device */
1259 _("Detaching"));
1260 dfu_progress_bar_set_percentage (priv->progress_bar, -1);
1261 break;
1262 case DFU_ACTION_ATTACH:
1263 dfu_progress_bar_start (priv->progress_bar,
1264 /* TRANSLATORS: waiting for device */
1265 _("Attaching"));
1266 dfu_progress_bar_set_percentage (priv->progress_bar, -1);
1267 break;
1268 default:
1269 break;
1270 }
1271 }
1272
1273 static gboolean
1274 dfu_tool_read_alt (DfuToolPrivate *priv, gchar **values, GError **error)
1275 {
1276 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_NONE;
1277 g_autofree gchar *str_debug = NULL;
1278 g_autoptr(DfuDevice) device = NULL;
1279 g_autoptr(DfuFirmware) firmware = NULL;
1280 g_autoptr(DfuImage) image = NULL;
1281 g_autoptr(DfuTarget) target = NULL;
1282 g_autoptr(GFile) file = NULL;
1283
1284 /* check args */
1285 if (g_strv_length (values) < 2) {
1286 g_set_error_literal (error,
1287 DFU_ERROR,
1288 DFU_ERROR_INTERNAL,
1289 "Invalid arguments, expected "
1290 "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID");
1291 return FALSE;
1292 }
1293
1294 /* open correct device */
1295 device = dfu_tool_get_defalt_device (priv, error);
1296 if (device == NULL)
1297 return FALSE;
1298 if (priv->transfer_size > 0)
1299 dfu_device_set_transfer_size (device, priv->transfer_size);
1300 if (!dfu_device_open (device,
1301 DFU_DEVICE_OPEN_FLAG_NONE,
1302 priv->cancellable,
1303 error))
1304 return FALSE;
1305
1306 /* set up progress */
1307 g_signal_connect (device, "action-changed",
1308 G_CALLBACK (fu_tool_action_changed_cb), priv);
1309 g_signal_connect (device, "percentage-changed",
1310 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1311
1312 /* APP -> DFU */
1313 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1314 g_debug ("detaching");
1315 if (!dfu_device_detach (device, priv->cancellable, error))
1316 return FALSE;
1317 if (!dfu_device_wait_for_replug (device,
1318 DFU_DEVICE_REPLUG_TIMEOUT,
1319 priv->cancellable,
1320 error))
1321 return FALSE;
1322
1323 /* put back in same state */
1324 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1325 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1326 }
1327
1328 /* transfer */
1329 target = dfu_device_get_target_by_alt_name (device,
1330 values[1],
1331 NULL);
1332 if (target == NULL) {
1333 gchar *endptr;
1334 guint64 tmp = g_ascii_strtoull (values[1], &endptr, 10);
1335 if (tmp > 0xff || endptr[0] != '\0') {
1336 g_set_error (error,
1337 DFU_ERROR,
1338 DFU_ERROR_INTERNAL,
1339 "Failed to parse alt-setting '%s'",
1340 values[1]);
1341 return FALSE;
1342 }
1343 target = dfu_device_get_target_by_alt_setting (device,
1344 (guint8) tmp,
1345 error);
1346 if (target == NULL)
1347 return FALSE;
1348 }
1349
1350 /* do transfer */
1351 image = dfu_target_upload (target, flags, priv->cancellable, error);
1352 if (image == NULL)
1353 return FALSE;
1354
1355 /* create new firmware object */
1356 firmware = dfu_firmware_new ();
1357 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU);
1358 dfu_firmware_set_vid (firmware, dfu_device_get_runtime_vid (device));
1359 dfu_firmware_set_pid (firmware, dfu_device_get_runtime_pid (device));
1360 dfu_firmware_add_image (firmware, image);
1361
1362 /* save file */
1363 file = g_file_new_for_path (values[0]);
1364 if (!dfu_firmware_write_file (firmware,
1365 file,
1366 priv->cancellable,
1367 error))
1368 return FALSE;
1369
1370 /* print the new object */
1371 str_debug = dfu_firmware_to_string (firmware);
1372 g_debug ("DFU: %s", str_debug);
1373
1374 /* success */
1375 g_print ("%u bytes successfully uploaded from device\n",
1376 dfu_image_get_size (image));
1377 return TRUE;
1378 }
1379
1380 static gboolean
1381 dfu_tool_read (DfuToolPrivate *priv, gchar **values, GError **error)
1382 {
1383 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_NONE;
1384 g_autofree gchar *str_debug = NULL;
1385 g_autoptr(DfuDevice) device = NULL;
1386 g_autoptr(DfuFirmware) firmware = NULL;
1387 g_autoptr(GFile) file = NULL;
1388
1389 /* check args */
1390 if (g_strv_length (values) < 1) {
1391 g_set_error_literal (error,
1392 DFU_ERROR,
1393 DFU_ERROR_INTERNAL,
1394 "Invalid arguments, expected FILENAME");
1395 return FALSE;
1396 }
1397
1398 /* open correct device */
1399 device = dfu_tool_get_defalt_device (priv, error);
1400 if (device == NULL)
1401 return FALSE;
1402 if (!dfu_device_open (device,
1403 DFU_DEVICE_OPEN_FLAG_NONE,
1404 priv->cancellable,
1405 error))
1406 return FALSE;
1407
1408 /* optional reset */
1409 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1410 flags |= DFU_TARGET_TRANSFER_FLAG_DETACH;
1411 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1412 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1413 }
1414
1415 /* transfer */
1416 g_signal_connect (device, "action-changed",
1417 G_CALLBACK (fu_tool_action_changed_cb), priv);
1418 g_signal_connect (device, "percentage-changed",
1419 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1420 firmware = dfu_device_upload (device,
1421 flags,
1422 priv->cancellable,
1423 error);
1424 if (firmware == NULL)
1425 return FALSE;
1426
1427 /* save file */
1428 file = g_file_new_for_path (values[0]);
1429 if (!dfu_firmware_write_file (firmware,
1430 file,
1431 priv->cancellable,
1432 error))
1433 return FALSE;
1434
1435 /* print the new object */
1436 str_debug = dfu_firmware_to_string (firmware);
1437 g_debug ("DFU: %s", str_debug);
1438
1439 /* success */
1440 g_print ("%u bytes successfully uploaded from device\n",
1441 dfu_firmware_get_size (firmware));
1442 return TRUE;
1443 }
1444
1445 static gchar *
1446 dfu_tool_get_device_string (DfuToolPrivate *priv, DfuDevice *device)
1447 {
1448 gchar *dstr;
1449 GUsbDevice *dev;
1450 g_autoptr(GError) error = NULL;
1451
1452 /* open, and get status */
1453 dev = dfu_device_get_usb_dev (device);
1454 if (dev == NULL) {
1455 return g_strdup_printf ("%04x:%04x [%s]",
1456 dfu_device_get_runtime_vid (device),
1457 dfu_device_get_runtime_pid (device),
1458 "removed");
1459 }
1460 if (!dfu_device_open (device,
1461 DFU_DEVICE_OPEN_FLAG_NONE,
1462 priv->cancellable,
1463 &error)) {
1464 return g_strdup_printf ("%04x:%04x [%s]",
1465 g_usb_device_get_vid (dev),
1466 g_usb_device_get_pid (dev),
1467 error->message);
1468 }
1469 dstr = g_strdup_printf ("%04x:%04x [%s:%s]",
1470 g_usb_device_get_vid (dev),
1471 g_usb_device_get_pid (dev),
1472 dfu_state_to_string (dfu_device_get_state (device)),
1473 dfu_status_to_string (dfu_device_get_status (device)));
1474 dfu_device_close (device, NULL);
1475 return dstr;
1476 }
1477
1478 static void
1479 dfu_tool_device_added_cb (DfuContext *context,
1480 DfuDevice *device,
1481 gpointer user_data)
1482 {
1483 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
1484 g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device);
1485 /* TRANSLATORS: this is when a device is hotplugged */
1486 dfu_tool_print_indent (_("Added"), tmp, 0);
1487 }
1488
1489 static void
1490 dfu_tool_device_removed_cb (DfuContext *context,
1491 DfuDevice *device,
1492 gpointer user_data)
1493 {
1494 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
1495 g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device);
1496 /* TRANSLATORS: this is when a device is hotplugged */
1497 dfu_tool_print_indent (_("Removed"), tmp, 0);
1498 }
1499
1500 static void
1501 dfu_tool_device_changed_cb (DfuContext *context, DfuDevice *device, gpointer user_data)
1502 {
1503 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
1504 g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device);
1505 /* TRANSLATORS: this is when a device is hotplugged */
1506 dfu_tool_print_indent (_("Changed"), tmp, 0);
1507 }
1508
1509 static void
1510 dfu_tool_watch_cancelled_cb (GCancellable *cancellable, gpointer user_data)
1511 {
1512 GMainLoop *loop = (GMainLoop *) user_data;
1513 /* TRANSLATORS: this is when a device ctrl+c's a watch */
1514 g_print ("%s\n", _("Cancelled"));
1515 g_main_loop_quit (loop);
1516 }
1517
1518 static guint8 *
1519 dfu_tool_get_firmware_contents_default (DfuFirmware *firmware,
1520 gsize *length,
1521 GError **error)
1522 {
1523 DfuElement *element;
1524 DfuImage *image;
1525 GBytes *contents;
1526
1527 image = dfu_firmware_get_image_default (firmware);
1528 if (image == NULL) {
1529 g_set_error_literal (error,
1530 DFU_ERROR,
1531 DFU_ERROR_INTERNAL,
1532 "No default image");
1533 return NULL;
1534 }
1535 element = dfu_image_get_element (image, 0);
1536 if (element == NULL) {
1537 g_set_error_literal (error,
1538 DFU_ERROR,
1539 DFU_ERROR_INTERNAL,
1540 "No default element");
1541 return NULL;
1542 }
1543 contents = dfu_element_get_contents (element);
1544 if (contents == NULL) {
1545 g_set_error_literal (error,
1546 DFU_ERROR,
1547 DFU_ERROR_INTERNAL,
1548 "No image contents");
1549 return NULL;
1550 }
1551 return (guint8 *) g_bytes_get_data (contents, length);
1552 }
1553
1554 static gboolean
1555 dfu_tool_encrypt (DfuToolPrivate *priv, gchar **values, GError **error)
1556 {
1557 gsize len;
1558 guint8 *data;
1559 g_autoptr(DfuFirmware) firmware = NULL;
1560 g_autoptr(GFile) file_in = NULL;
1561 g_autoptr(GFile) file_out = NULL;
1562
1563 /* check args */
1564 if (g_strv_length (values) < 4) {
1565 g_set_error_literal (error,
1566 DFU_ERROR,
1567 DFU_ERROR_INTERNAL,
1568 "Invalid arguments, expected "
1569 "FILENAME-IN FILENAME-OUT TYPE KEY"
1570 " -- e.g. firmware.dfu firmware.xdfu xtea deadbeef");
1571 return FALSE;
1572 }
1573
1574 /* check extensions */
1575 if (!priv->force) {
1576 if (!g_str_has_suffix (values[0], ".dfu")) {
1577 g_set_error_literal (error,
1578 DFU_ERROR,
1579 DFU_ERROR_NOT_SUPPORTED,
1580 "Invalid filename, expected *.dfu");
1581 return FALSE;
1582 }
1583 if (!g_str_has_suffix (values[1], ".xdfu")) {
1584 g_set_error_literal (error,
1585 DFU_ERROR,
1586 DFU_ERROR_NOT_SUPPORTED,
1587 "Invalid filename, expected *.xdfu");
1588 return FALSE;
1589 }
1590 }
1591
1592 /* open */
1593 file_in = g_file_new_for_path (values[0]);
1594 firmware = dfu_firmware_new ();
1595 if (!dfu_firmware_parse_file (firmware, file_in,
1596 DFU_FIRMWARE_PARSE_FLAG_NONE,
1597 priv->cancellable,
1598 error)) {
1599 return FALSE;
1600 }
1601
1602 /* get data */
1603 data = dfu_tool_get_firmware_contents_default (firmware, &len, error);
1604 if (data == NULL)
1605 return FALSE;
1606
1607 /* check type */
1608 if (g_strcmp0 (values[2], "xtea") == 0) {
1609 if (!dfu_cipher_encrypt_xtea (values[3], data, (guint32) len, error))
1610 return FALSE;
1611 dfu_firmware_set_metadata (firmware,
1612 DFU_METADATA_KEY_CIPHER_KIND,
1613 "XTEA");
1614 } else if (g_strcmp0 (values[2], "devo") == 0) {
1615 if (!dfu_cipher_encrypt_devo (values[3], data, (guint32) len, error))
1616 return FALSE;
1617 dfu_firmware_set_metadata (firmware,
1618 DFU_METADATA_KEY_CIPHER_KIND,
1619 "DEVO");
1620 } else {
1621 g_set_error (error,
1622 DFU_ERROR,
1623 DFU_ERROR_INTERNAL,
1624 "unknown type '%s', expected [xtea|devo]",
1625 values[2]);
1626 return FALSE;
1627 }
1628
1629 /* write out new file */
1630 file_out = g_file_new_for_path (values[1]);
1631 g_debug ("wrote %s", values[1]);
1632 return dfu_firmware_write_file (firmware,
1633 file_out,
1634 priv->cancellable,
1635 error);
1636 }
1637
1638 static gboolean
1639 dfu_tool_decrypt (DfuToolPrivate *priv, gchar **values, GError **error)
1640 {
1641 gsize len;
1642 guint8 *data;
1643 g_autoptr(DfuFirmware) firmware = NULL;
1644 g_autoptr(GFile) file_in = NULL;
1645 g_autoptr(GFile) file_out = NULL;
1646
1647 /* check args */
1648 if (g_strv_length (values) < 4) {
1649 g_set_error_literal (error,
1650 DFU_ERROR,
1651 DFU_ERROR_INTERNAL,
1652 "Invalid arguments, expected "
1653 "FILENAME-IN FILENAME-OUT TYPE KEY"
1654 " -- e.g. firmware.xdfu firmware.dfu xtea deadbeef");
1655 return FALSE;
1656 }
1657
1658 /* check extensions */
1659 if (!priv->force) {
1660 if (!g_str_has_suffix (values[0], ".xdfu")) {
1661 g_set_error_literal (error,
1662 DFU_ERROR,
1663 DFU_ERROR_NOT_SUPPORTED,
1664 "Invalid filename, expected *.xdfu");
1665 return FALSE;
1666 }
1667 if (!g_str_has_suffix (values[1], ".dfu")) {
1668 g_set_error_literal (error,
1669 DFU_ERROR,
1670 DFU_ERROR_NOT_SUPPORTED,
1671 "Invalid filename, expected *.dfu");
1672 return FALSE;
1673 }
1674 }
1675
1676 /* open */
1677 file_in = g_file_new_for_path (values[0]);
1678 firmware = dfu_firmware_new ();
1679 if (!dfu_firmware_parse_file (firmware, file_in,
1680 DFU_FIRMWARE_PARSE_FLAG_NONE,
1681 priv->cancellable,
1682 error)) {
1683 return FALSE;
1684 }
1685
1686 /* get data */
1687 data = dfu_tool_get_firmware_contents_default (firmware, &len, error);
1688 if (data == NULL)
1689 return FALSE;
1690
1691 /* check type */
1692 if (g_strcmp0 (values[2], "xtea") == 0) {
1693 if (!dfu_cipher_decrypt_xtea (values[3], data, (guint32) len, error))
1694 return FALSE;
1695 dfu_firmware_remove_metadata (firmware,
1696 DFU_METADATA_KEY_CIPHER_KIND);
1697 } else if (g_strcmp0 (values[2], "devo") == 0) {
1698 if (!dfu_cipher_decrypt_devo (values[3], data, (guint32) len, error))
1699 return FALSE;
1700 dfu_firmware_remove_metadata (firmware,
1701 DFU_METADATA_KEY_CIPHER_KIND);
1702 } else {
1703 g_set_error (error,
1704 DFU_ERROR,
1705 DFU_ERROR_INTERNAL,
1706 "unknown type '%s', expected [xtea:devo]",
1707 values[2]);
1708 return FALSE;
1709 }
1710
1711 /* write out new file */
1712 file_out = g_file_new_for_path (values[1]);
1713 g_debug ("wrote %s", values[1]);
1714 return dfu_firmware_write_file (firmware,
1715 file_out,
1716 priv->cancellable,
1717 error);
1718 }
1719
1720 static gboolean
1721 dfu_tool_watch (DfuToolPrivate *priv, gchar **values, GError **error)
1722 {
1723 guint i;
1724 DfuDevice *device;
1725 g_autoptr(DfuContext) dfu_context = NULL;
1726 g_autoptr(GMainLoop) loop = NULL;
1727 g_autoptr(GPtrArray) devices = NULL;
1728
1729 /* get all the DFU devices */
1730 dfu_context = dfu_context_new ();
1731 dfu_context_enumerate (dfu_context, NULL);
1732
1733 /* print what's already attached */
1734 devices = dfu_context_get_devices (dfu_context);
1735 for (i = 0; i < devices->len; i++) {
1736 device = g_ptr_array_index (devices, i);
1737 dfu_tool_device_added_cb (dfu_context, device, priv);
1738 }
1739
1740 /* watch for any hotplugged device */
1741 loop = g_main_loop_new (NULL, FALSE);
1742 g_signal_connect (dfu_context, "device-added",
1743 G_CALLBACK (dfu_tool_device_added_cb), priv);
1744 g_signal_connect (dfu_context, "device-removed",
1745 G_CALLBACK (dfu_tool_device_removed_cb), priv);
1746 g_signal_connect (dfu_context, "device-changed",
1747 G_CALLBACK (dfu_tool_device_changed_cb), priv);
1748 g_signal_connect (priv->cancellable, "cancelled",
1749 G_CALLBACK (dfu_tool_watch_cancelled_cb), loop);
1750 g_main_loop_run (loop);
1751 return TRUE;
1752 }
1753
1754 static gboolean
1755 dfu_tool_dump (DfuToolPrivate *priv, gchar **values, GError **error)
1756 {
1757 DfuFirmwareParseFlags flags = DFU_FIRMWARE_PARSE_FLAG_NONE;
1758 guint i;
1759
1760 /* check args */
1761 if (g_strv_length (values) < 1) {
1762 g_set_error_literal (error,
1763 DFU_ERROR,
1764 DFU_ERROR_INTERNAL,
1765 "Invalid arguments, expected FILENAME");
1766 return FALSE;
1767 }
1768
1769 /* dump corrupt files */
1770 if (priv->force) {
1771 flags |= DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST;
1772 flags |= DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST;
1773 }
1774
1775 /* open files */
1776 for (i = 0; values[i] != NULL; i++) {
1777 g_autoptr(DfuFirmware) firmware = NULL;
1778 g_autoptr(GFile) file = NULL;
1779 g_autoptr(GError) error_local = NULL;
1780
1781 /* dump to screen */
1782 g_print ("Loading %s:\n", values[i]);
1783 firmware = dfu_firmware_new ();
1784 file = g_file_new_for_path (values[i]);
1785 if (!dfu_firmware_parse_file (firmware, file, flags,
1786 priv->cancellable,
1787 &error_local)) {
1788 g_print ("Failed to load firmware: %s\n",
1789 error_local->message);
1790 continue;
1791 }
1792 g_print ("%s\n", dfu_firmware_to_string (firmware));
1793 }
1794 return TRUE;
1795 }
1796
1797 static gboolean
1798 dfu_tool_write_alt (DfuToolPrivate *priv, gchar **values, GError **error)
1799 {
1800 DfuImage *image;
1801 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_VERIFY;
1802 g_autofree gchar *str_debug = NULL;
1803 g_autoptr(DfuDevice) device = NULL;
1804 g_autoptr(DfuFirmware) firmware = NULL;
1805 g_autoptr(DfuTarget) target = NULL;
1806 g_autoptr(GFile) file = NULL;
1807
1808 /* check args */
1809 if (g_strv_length (values) < 2) {
1810 g_set_error_literal (error,
1811 DFU_ERROR,
1812 DFU_ERROR_INTERNAL,
1813 "Invalid arguments, expected "
1814 "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID "
1815 "[IMAGE-ALT-NAME|IMAGE-ALT-ID]");
1816 return FALSE;
1817 }
1818
1819 /* open file */
1820 firmware = dfu_firmware_new ();
1821 file = g_file_new_for_path (values[0]);
1822 if (!dfu_firmware_parse_file (firmware, file,
1823 DFU_FIRMWARE_PARSE_FLAG_NONE,
1824 priv->cancellable, error))
1825 return FALSE;
1826
1827 /* open correct device */
1828 device = dfu_tool_get_defalt_device (priv, error);
1829 if (device == NULL)
1830 return FALSE;
1831 if (priv->transfer_size > 0)
1832 dfu_device_set_transfer_size (device, priv->transfer_size);
1833 if (!dfu_device_open (device,
1834 DFU_DEVICE_OPEN_FLAG_NONE,
1835 priv->cancellable,
1836 error))
1837 return FALSE;
1838
1839 /* set up progress */
1840 g_signal_connect (device, "action-changed",
1841 G_CALLBACK (fu_tool_action_changed_cb), priv);
1842 g_signal_connect (device, "percentage-changed",
1843 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1844
1845 /* APP -> DFU */
1846 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1847 g_debug ("detaching");
1848 if (!dfu_device_detach (device, priv->cancellable, error))
1849 return FALSE;
1850 if (!dfu_device_wait_for_replug (device, 5000, priv->cancellable, error))
1851 return FALSE;
1852
1853 /* put back in same state */
1854 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1855 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1856 }
1857
1858 /* print the new object */
1859 str_debug = dfu_firmware_to_string (firmware);
1860 g_debug ("DFU: %s", str_debug);
1861
1862 /* get correct target on device */
1863 target = dfu_device_get_target_by_alt_name (device,
1864 values[1],
1865 NULL);
1866 if (target == NULL) {
1867 gchar *endptr;
1868 guint64 tmp = g_ascii_strtoull (values[1], &endptr, 10);
1869 if (tmp > 0xff || endptr[0] != '\0') {
1870 g_set_error (error,
1871 DFU_ERROR,
1872 DFU_ERROR_INTERNAL,
1873 "Failed to parse alt-setting '%s'",
1874 values[1]);
1875 return FALSE;
1876 }
1877 target = dfu_device_get_target_by_alt_setting (device,
1878 (guint8) tmp,
1879 error);
1880 if (target == NULL)
1881 return FALSE;
1882 }
1883
1884 /* allow overriding the firmware alt-setting */
1885 if (g_strv_length (values) > 2) {
1886 image = dfu_firmware_get_image_by_name (firmware, values[2]);
1887 if (image == NULL) {
1888 gchar *endptr;
1889 guint64 tmp = g_ascii_strtoull (values[2], &endptr, 10);
1890 if (tmp > 0xff || endptr[0] != '\0') {
1891 g_set_error (error,
1892 DFU_ERROR,
1893 DFU_ERROR_INTERNAL,
1894 "Failed to parse image alt-setting '%s'",
1895 values[2]);
1896 return FALSE;
1897 }
1898 image = dfu_firmware_get_image (firmware, (guint8) tmp);
1899 if (image == NULL) {
1900 g_set_error (error,
1901 DFU_ERROR,
1902 DFU_ERROR_INVALID_FILE,
1903 "could not locate image in firmware for %02x",
1904 (guint) tmp);
1905 return FALSE;
1906 }
1907 }
1908 } else {
1909 g_print ("WARNING: Using default firmware image\n");
1910 image = dfu_firmware_get_image_default (firmware);
1911 if (image == NULL) {
1912 g_set_error_literal (error,
1913 DFU_ERROR,
1914 DFU_ERROR_INVALID_FILE,
1915 "no default image");
1916 return FALSE;
1917 }
1918 }
1919
1920 /* allow forcing firmware kinds */
1921 if (priv->force) {
1922 flags |= DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER;
1923 }
1924
1925 /* transfer */
1926 if (!dfu_target_download (target,
1927 image,
1928 flags,
1929 priv->cancellable,
1930 error))
1931 return FALSE;
1932
1933 /* success */
1934 g_print ("%u bytes successfully downloaded to device\n",
1935 dfu_image_get_size (image));
1936 return TRUE;
1937 }
1938
1939 static gboolean
1940 dfu_tool_write (DfuToolPrivate *priv, gchar **values, GError **error)
1941 {
1942 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_VERIFY;
1943 g_autofree gchar *str_debug = NULL;
1944 g_autoptr(DfuDevice) device = NULL;
1945 g_autoptr(DfuFirmware) firmware = NULL;
1946 g_autoptr(GFile) file = NULL;
1947
1948 /* check args */
1949 if (g_strv_length (values) < 1) {
1950 g_set_error_literal (error,
1951 DFU_ERROR,
1952 DFU_ERROR_INTERNAL,
1953 "Invalid arguments, expected FILENAME");
1954 return FALSE;
1955 }
1956
1957 /* open file */
1958 firmware = dfu_firmware_new ();
1959 file = g_file_new_for_path (values[0]);
1960 if (!dfu_firmware_parse_file (firmware, file,
1961 DFU_FIRMWARE_PARSE_FLAG_NONE,
1962 priv->cancellable, error))
1963 return FALSE;
1964
1965 /* open correct device */
1966 device = dfu_tool_get_defalt_device (priv, error);
1967 if (device == NULL)
1968 return FALSE;
1969 if (!dfu_device_open (device,
1970 DFU_DEVICE_OPEN_FLAG_NONE,
1971 priv->cancellable,
1972 error))
1973 return FALSE;
1974
1975 /* print the new object */
1976 str_debug = dfu_firmware_to_string (firmware);
1977 g_debug ("DFU: %s", str_debug);
1978
1979 /* put in correct mode */
1980 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1981 flags |= DFU_TARGET_TRANSFER_FLAG_DETACH;
1982 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1983 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1984 }
1985
1986 /* allow wildcards */
1987 if (priv->force) {
1988 flags |= DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID;
1989 flags |= DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID;
1990 flags |= DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER;
1991 }
1992
1993 /* transfer */
1994 g_signal_connect (device, "action-changed",
1995 G_CALLBACK (fu_tool_action_changed_cb), priv);
1996 g_signal_connect (device, "percentage-changed",
1997 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1998 if (!dfu_device_download (device,
1999 firmware,
2000 flags,
2001 priv->cancellable,
2002 error))
2003 return FALSE;
2004
2005 /* success */
2006 g_print ("%u bytes successfully downloaded to device\n",
2007 dfu_firmware_get_size (firmware));
2008 return TRUE;
2009 }
2010
2011 static void
2012 dfu_tool_list_target (DfuTarget *target)
2013 {
2014 DfuCipherKind cipher_kind;
2015 GPtrArray *sectors;
2016 const gchar *tmp;
2017 guint i;
2018 g_autofree gchar *alt_id = NULL;
2019 g_autoptr(GError) error_local = NULL;
2020
2021 /* TRANSLATORS: the identifier name please */
2022 alt_id = g_strdup_printf ("%i", dfu_target_get_alt_setting (target));
2023 dfu_tool_print_indent (_("ID"), alt_id, 1);
2024
2025 /* this is optional */
2026 tmp = dfu_target_get_alt_name_for_display (target, &error_local);
2027 if (tmp != NULL) {
2028 /* TRANSLATORS: interface name, e.g. "Flash" */
2029 dfu_tool_print_indent (_("Name"), tmp, 2);
2030 } else if (!g_error_matches (error_local,
2031 DFU_ERROR,
2032 DFU_ERROR_NOT_FOUND)) {
2033 g_autofree gchar *str = NULL;
2034 str = g_strdup_printf ("Error: %s", error_local->message);
2035 dfu_tool_print_indent (_("Name"), str, 2);
2036 }
2037
2038 /* this is optional */
2039 cipher_kind = dfu_target_get_cipher_kind (target);
2040 if (cipher_kind != DFU_CIPHER_KIND_NONE) {
2041 /* TRANSLATORS: this is the encryption method used when writing */
2042 dfu_tool_print_indent (_("Cipher"),
2043 dfu_cipher_kind_to_string (cipher_kind),
2044 2);
2045 }
2046
2047 /* print sector information */
2048 sectors = dfu_target_get_sectors (target);
2049 for (i = 0; i < sectors->len; i++) {
2050 DfuSector *sector;
2051 g_autofree gchar *msg = NULL;
2052 g_autofree gchar *title = NULL;
2053 sector = g_ptr_array_index (sectors, i);
2054 msg = dfu_sector_to_string (sector);
2055 /* TRANSLATORS: these are areas of memory on the chip */
2056 title = g_strdup_printf ("%s 0x%02x", _("Region"), i);
2057 dfu_tool_print_indent (title, msg, 2);
2058 }
2059 }
2060
2061 static gboolean
2062 dfu_tool_list (DfuToolPrivate *priv, gchar **values, GError **error)
2063 {
2064 guint i;
2065 g_autoptr(DfuContext) dfu_context = NULL;
2066 g_autoptr(GPtrArray) devices = NULL;
2067
2068 /* get all the connected USB devices */
2069 dfu_context = dfu_context_new ();
2070 dfu_context_enumerate (dfu_context, NULL);
2071 devices = dfu_context_get_devices (dfu_context);
2072 for (i = 0; i < devices->len; i++) {
2073 DfuDevice *device = NULL;
2074 DfuTarget *target;
2075 GUsbDevice *dev;
2076 GPtrArray *dfu_targets;
2077 const gchar *tmp;
2078 guint j;
2079 guint16 transfer_size;
2080 g_autofree gchar *quirks = NULL;
2081 g_autofree gchar *version = NULL;
2082 g_autoptr(GError) error_local = NULL;
2083
2084 /* device specific */
2085 device = g_ptr_array_index (devices, i);
2086 dev = dfu_device_get_usb_dev (device);
2087 version = as_utils_version_from_uint16 (g_usb_device_get_release (dev),
2088 AS_VERSION_PARSE_FLAG_NONE);
2089 g_print ("%s %04x:%04x [v%s]:\n",
2090 /* TRANSLATORS: detected a DFU device */
2091 _("Found"),
2092 g_usb_device_get_vid (dev),
2093 g_usb_device_get_pid (dev),
2094 version);
2095
2096 tmp = dfu_version_to_string (dfu_device_get_version (device));
2097 if (tmp != NULL) {
2098 /* TRANSLATORS: DFU protocol version, e.g. 1.1 */
2099 dfu_tool_print_indent (_("Protocol"), tmp, 1);
2100 }
2101
2102 /* open */
2103 if (!dfu_device_open (device,
2104 DFU_DEVICE_OPEN_FLAG_NONE,
2105 priv->cancellable,
2106 &error_local)) {
2107 if (g_error_matches (error_local,
2108 DFU_ERROR,
2109 DFU_ERROR_PERMISSION_DENIED)) {
2110 /* TRANSLATORS: probably not run as root... */
2111 dfu_tool_print_indent (_("Status"), _("Unknown: permission denied"), 2);
2112 } else {
2113 /* TRANSLATORS: device has failed to report status */
2114 dfu_tool_print_indent (_("Status"), error_local->message, 2);
2115 }
2116 continue;
2117 }
2118
2119 tmp = dfu_device_get_display_name (device);
2120 if (tmp != NULL) {
2121 /* TRANSLATORS: device name, e.g. 'ColorHug2' */
2122 dfu_tool_print_indent (_("Name"), tmp, 1);
2123 }
2124
2125 tmp = dfu_device_get_serial_number (device);
2126 if (tmp != NULL) {
2127 /* TRANSLATORS: serial number, e.g. '00012345' */
2128 dfu_tool_print_indent (_("Serial"), tmp, 1);
2129 }
2130
2131 tmp = dfu_mode_to_string (dfu_device_get_mode (device));
2132 /* TRANSLATORS: device mode, e.g. runtime or DFU */
2133 dfu_tool_print_indent (_("Mode"), tmp, 1);
2134
2135 tmp = dfu_status_to_string (dfu_device_get_status (device));
2136 /* TRANSLATORS: device status, e.g. "OK" */
2137 dfu_tool_print_indent (_("Status"), tmp, 1);
2138
2139 tmp = dfu_state_to_string (dfu_device_get_state (device));
2140 /* TRANSLATORS: device state, i.e. appIDLE */
2141 dfu_tool_print_indent (_("State"), tmp, 1);
2142
2143 transfer_size = dfu_device_get_transfer_size (device);
2144 if (transfer_size > 0) {
2145 g_autofree gchar *str = NULL;
2146 str = g_format_size_full (transfer_size,
2147 G_FORMAT_SIZE_LONG_FORMAT);
2148 /* TRANSLATORS: transfer size in bytes */
2149 dfu_tool_print_indent (_("Transfer Size"), str, 1);
2150 }
2151
2152 /* quirks are NULL if none are set */
2153 quirks = dfu_device_get_quirks_as_string (device);
2154 if (quirks != NULL) {
2155 /* TRANSLATORS: device quirks, i.e. things that
2156 * it does that we have to work around */
2157 dfu_tool_print_indent (_("Quirks"), quirks, 1);
2158 }
2159
2160 /* list targets */
2161 dfu_targets = dfu_device_get_targets (device);
2162 for (j = 0; j < dfu_targets->len; j++) {
2163 target = g_ptr_array_index (dfu_targets, j);
2164 dfu_tool_list_target (target);
2165 }
2166 }
2167 return TRUE;
2168 }
2169
2170 static gboolean
2171 dfu_tool_detach (DfuToolPrivate *priv, gchar **values, GError **error)
2172 {
2173 g_autoptr(DfuDevice) device = NULL;
2174
2175 /* open correct device */
2176 device = dfu_tool_get_defalt_device (priv, error);
2177 if (device == NULL)
2178 return FALSE;
2179 if (priv->transfer_size > 0)
2180 dfu_device_set_transfer_size (device, priv->transfer_size);
2181
2182 /* detatch */
2183 if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE,
2184 priv->cancellable, error))
2185 return FALSE;
2186 if (!dfu_device_detach (device, priv->cancellable, error))
2187 return FALSE;
2188 return TRUE;
2189 }
2190
2191 static gboolean
2192 dfu_tool_sigint_cb (gpointer user_data)
2193 {
2194 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
2195 g_debug ("Handling SIGINT");
2196 g_cancellable_cancel (priv->cancellable);
2197 return FALSE;
2198 }
2199
2200 int
2201 main (int argc, char *argv[])
2202 {
2203 gboolean ret;
2204 gboolean verbose = FALSE;
2205 gboolean version = FALSE;
2206 g_autofree gchar *cmd_descriptions = NULL;
2207 g_autoptr(DfuToolPrivate) priv = g_new0 (DfuToolPrivate, 1);
2208 g_autoptr(GError) error = NULL;
2209 g_autoptr(GOptionContext) context = NULL;
2210 const GOptionEntry options[] = {
2211 { "version", '\0', 0, G_OPTION_ARG_NONE, &version,
2212 "Print the version number", NULL },
2213 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
2214 "Print verbose debug statements", NULL },
2215 { "device", 'd', 0, G_OPTION_ARG_STRING, &priv->device_vid_pid,
2216 "Specify Vendor/Product ID(s) of DFU device", "VID:PID" },
2217 { "transfer-size", 't', 0, G_OPTION_ARG_STRING, &priv->transfer_size,
2218 "Specify the number of bytes per USB transfer", "BYTES" },
2219 { "force", '\0', 0, G_OPTION_ARG_NONE, &priv->force,
2220 "Force the action ignoring all warnings", NULL },
2221 { NULL}
2222 };
2223
2224 setlocale (LC_ALL, "");
2225
2226 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
2227 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2228 textdomain (GETTEXT_PACKAGE);
2229
2230 /* add commands */
2231 priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_tool_item_free);
2232 dfu_tool_add (priv->cmd_array,
2233 "convert",
2234 NULL,
2235 /* TRANSLATORS: command description */
2236 _("Convert firmware to DFU format"),
2237 dfu_tool_convert);
2238 dfu_tool_add (priv->cmd_array,
2239 "merge",
2240 NULL,
2241 /* TRANSLATORS: command description */
2242 _("Merge multiple firmware files into one"),
2243 dfu_tool_merge);
2244 dfu_tool_add (priv->cmd_array,
2245 "set-vendor",
2246 NULL,
2247 /* TRANSLATORS: command description */
2248 _("Set vendor ID on firmware file"),
2249 dfu_tool_set_vendor);
2250 dfu_tool_add (priv->cmd_array,
2251 "set-product",
2252 NULL,
2253 /* TRANSLATORS: command description */
2254 _("Set product ID on firmware file"),
2255 dfu_tool_set_product);
2256 dfu_tool_add (priv->cmd_array,
2257 "set-address",
2258 NULL,
2259 /* TRANSLATORS: command description */
2260 _("Set element address on firmware file"),
2261 dfu_tool_set_address);
2262 dfu_tool_add (priv->cmd_array,
2263 "set-target-size",
2264 NULL,
2265 /* TRANSLATORS: command description */
2266 _("Set the firmware size for the target"),
2267 dfu_tool_set_target_size);
2268 dfu_tool_add (priv->cmd_array,
2269 "set-release",
2270 NULL,
2271 /* TRANSLATORS: command description */
2272 _("Set release version on firmware file"),
2273 dfu_tool_set_release);
2274 dfu_tool_add (priv->cmd_array,
2275 "set-alt-setting",
2276 NULL,
2277 /* TRANSLATORS: command description */
2278 _("Set alternative number on firmware file"),
2279 dfu_tool_set_alt_setting);
2280 dfu_tool_add (priv->cmd_array,
2281 "set-alt-setting-name",
2282 NULL,
2283 /* TRANSLATORS: command description */
2284 _("Set alternative name on firmware file"),
2285 dfu_tool_set_alt_setting_name);
2286 dfu_tool_add (priv->cmd_array,
2287 "attach",
2288 NULL,
2289 /* TRANSLATORS: command description */
2290 _("Attach DFU capable device back to runtime"),
2291 dfu_tool_attach);
2292 dfu_tool_add (priv->cmd_array,
2293 "read",
2294 NULL,
2295 /* TRANSLATORS: command description */
2296 _("Read firmware from device into a file"),
2297 dfu_tool_read);
2298 dfu_tool_add (priv->cmd_array,
2299 "read-alt",
2300 NULL,
2301 /* TRANSLATORS: command description */
2302 _("Read firmware from one partition into a file"),
2303 dfu_tool_read_alt);
2304 dfu_tool_add (priv->cmd_array,
2305 "write",
2306 NULL,
2307 /* TRANSLATORS: command description */
2308 _("Write firmware from file into device"),
2309 dfu_tool_write);
2310 dfu_tool_add (priv->cmd_array,
2311 "write-alt",
2312 NULL,
2313 /* TRANSLATORS: command description */
2314 _("Write firmware from file into one partition"),
2315 dfu_tool_write_alt);
2316 dfu_tool_add (priv->cmd_array,
2317 "list",
2318 NULL,
2319 /* TRANSLATORS: command description */
2320 _("List currently attached DFU capable devices"),
2321 dfu_tool_list);
2322 dfu_tool_add (priv->cmd_array,
2323 "detach",
2324 NULL,
2325 /* TRANSLATORS: command description */
2326 _("Detach currently attached DFU capable device"),
2327 dfu_tool_detach);
2328 dfu_tool_add (priv->cmd_array,
2329 "dump",
2330 NULL,
2331 /* TRANSLATORS: command description */
2332 _("Dump details about a firmware file"),
2333 dfu_tool_dump);
2334 dfu_tool_add (priv->cmd_array,
2335 "watch",
2336 NULL,
2337 /* TRANSLATORS: command description */
2338 _("Watch DFU devices being hotplugged"),
2339 dfu_tool_watch);
2340 dfu_tool_add (priv->cmd_array,
2341 "encrypt",
2342 NULL,
2343 /* TRANSLATORS: command description */
2344 _("Encrypt firmware data"),
2345 dfu_tool_encrypt);
2346 dfu_tool_add (priv->cmd_array,
2347 "decrypt",
2348 NULL,
2349 /* TRANSLATORS: command description */
2350 _("Decrypt firmware data"),
2351 dfu_tool_decrypt);
2352 dfu_tool_add (priv->cmd_array,
2353 "set-metadata",
2354 NULL,
2355 /* TRANSLATORS: command description */
2356 _("Sets metadata on a firmware file"),
2357 dfu_tool_set_metadata);
2358 dfu_tool_add (priv->cmd_array,
2359 "replace-data",
2360 NULL,
2361 /* TRANSLATORS: command description */
2362 _("Replace data in an existing firmware file"),
2363 dfu_tool_replace_data);
2364 dfu_tool_add (priv->cmd_array,
2365 "patch-create",
2366 NULL,
2367 /* TRANSLATORS: command description */
2368 _("Create a binary patch using two files"),
2369 dfu_tool_patch_create);
2370 dfu_tool_add (priv->cmd_array,
2371 "patch-apply",
2372 NULL,
2373 /* TRANSLATORS: command description */
2374 _("Apply a binary patch"),
2375 dfu_tool_patch_apply);
2376 dfu_tool_add (priv->cmd_array,
2377 "patch-dump",
2378 NULL,
2379 /* TRANSLATORS: command description */
2380 _("Dump information about a binary patch to the screen"),
2381 dfu_tool_patch_dump);
2382
2383 /* use animated progress bar */
2384 priv->progress_bar = dfu_progress_bar_new ();
2385 dfu_progress_bar_set_size (priv->progress_bar, 50);
2386 dfu_progress_bar_set_padding (priv->progress_bar, 20);
2387
2388 /* do stuff on ctrl+c */
2389 priv->cancellable = g_cancellable_new ();
2390 g_unix_signal_add_full (G_PRIORITY_DEFAULT,
2391 SIGINT,
2392 dfu_tool_sigint_cb,
2393 priv,
2394 NULL);
2395
2396 /* sort by command name */
2397 g_ptr_array_sort (priv->cmd_array,
2398 (GCompareFunc) dfu_tool_sort_command_name_cb);
2399
2400 /* get a list of the commands */
2401 context = g_option_context_new (NULL);
2402 cmd_descriptions = dfu_tool_get_descriptions (priv->cmd_array);
2403 g_option_context_set_summary (context, cmd_descriptions);
2404
2405 /* TRANSLATORS: DFU stands for device firmware update */
2406 g_set_application_name (_("DFU Utility"));
2407 g_option_context_add_main_entries (context, options, NULL);
2408 ret = g_option_context_parse (context, &argc, &argv, &error);
2409 if (!ret) {
2410 /* TRANSLATORS: the user didn't read the man page */
2411 g_print ("%s: %s\n", _("Failed to parse arguments"), error->message);
2412 return EXIT_FAILURE;
2413 }
2414
2415 /* set verbose? */
2416 if (verbose)
2417 g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
2418
2419 /* version */
2420 if (version) {
2421 g_print ("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
2422 return EXIT_SUCCESS;
2423 }
2424
2425 /* run the specified command */
2426 ret = dfu_tool_run (priv, argv[1], (gchar**) &argv[2], &error);
2427 if (!ret) {
2428 if (g_error_matches (error, DFU_ERROR, DFU_ERROR_INTERNAL)) {
2429 g_autofree gchar *tmp = NULL;
2430 tmp = g_option_context_get_help (context, TRUE, NULL);
2431 g_print ("%s\n\n%s", error->message, tmp);
2432 } else {
2433 g_print ("%s\n", error->message);
2434 }
2435 return EXIT_FAILURE;
2436 }
2437
2438 /* success/ */
2439 g_object_unref (priv->progress_bar);
2440 return EXIT_SUCCESS;
2441 }
+0
-46
libdfu/dfu.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu
23 * @short_description: Helper objects for interacting with DFU devices.
24 */
25
26 #ifndef __DFU_H__
27 #define __DFU_H__
28
29 #define __DFU_H_INSIDE__
30
31 #include <libdfu/dfu-common.h>
32 #include <libdfu/dfu-context.h>
33 #include <libdfu/dfu-device.h>
34 #include <libdfu/dfu-element.h>
35 #include <libdfu/dfu-error.h>
36 #include <libdfu/dfu-firmware.h>
37 #include <libdfu/dfu-image.h>
38 #include <libdfu/dfu-patch.h>
39 #include <libdfu/dfu-sector.h>
40 #include <libdfu/dfu-target.h>
41
42 #undef __DFU_H_INSIDE__
43
44 #endif /* __DFU_H__ */
45
+0
-6
libdfu/dfu.map less more
0 {
1 global:
2 dfu_*;
3 local:
4 *;
5 };
+0
-24
libdfu/examples/upload.py less more
0 #!/usr/bin/python
1
2 # Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 # Licensed under the GNU General Public License Version 2
4
5 import gi
6 gi.require_version('Dfu', '1.0')
7
8 from gi.repository import Dfu
9 from gi.repository import Gio
10
11 cancellable = Gio.Cancellable.new()
12 ctx = Dfu.Context.new()
13 ctx.enumerate()
14
15 for dev in ctx.get_devices():
16
17 # print details about the device
18 dev.open(Dfu.DeviceOpenFlags.NONE, cancellable)
19 print "getting firmware from %s:%s" % (dev.get_state(), dev.get_status())
20
21 # transfer firmware from device to host and show summary
22 fw = dev.upload(Dfu.TargetTransferFlags.DETACH, cancellable)
23 print fw.to_string()
libdfu/fuzzing/example.dfu less more
Binary diff not shown
libdfu/fuzzing/example.dfuse less more
Binary diff not shown
libdfu/fuzzing/firmware.elf less more
Binary diff not shown
+0
-10
libdfu/fuzzing/firmware.hex less more
0 :044000003DEF20F080
1 :10400800FACF01F0FBCF02F0E9CF03F0EACF04F0DA
2 :10401800E1CF05F0E2CF06F0D9CF07F0DACF08F00C
3 :10402800F3CF09F0F4CF0AF0F6CF0BF0F7CF0CF08E
4 :10403800F8CF0DF0F5CF0EF00EC0F5FF0DC0F8FF6C
5 :104048000CC0F7FF0BC0F6FF0AC0F4FF09C0F3FF6E
6 :1040580008C0DAFF07C0D9FF06C0E2FF05C0E1FFCC
7 :1040680004C0EAFF03C0E9FF02C0FBFF01C0FAFF7A
8 :1040780011003FEF20F0000142EF20F03DEF20F06B
9 :00000001FF
libdfu/fuzzing/metadata-multiple.dfu less more
Binary diff not shown
libdfu/fuzzing/metadata.dfu less more
Binary diff not shown
+0
-19
libdfu/fuzzing.md less more
0 Fuzzing
1 =======
2
3 CC=afl-gcc meson --default-library=static ../
4 AFL_HARDEN=1 ninja
5 afl-fuzz -m 300 -i fuzzing -o findings ./libdfu/dfu-tool --force dump @@
6 afl-fuzz -m 300 -i fuzzing-patch-dump -o findings ./libdfu/dfu-tool --force patch-dump @@
7
8 Generating
9 ----------
10
11 mkdir -p fuzzing-patch-dump
12 echo -n hello > complete-replace.old
13 echo -n XXXXX > complete-replace.new
14 ./libdfu/dfu-tool patch-create complete-replace.old complete-replace.new fuzzing-patch-dump/complete-replace.bdiff
15
16 echo -n helloworldhelloworldhelloworldhelloworld > grow-two-chunks.old
17 echo -n XelloXorldhelloworldhelloworldhelloworlXXX > grow-two-chunks.new
18 ./libdfu/dfu-tool patch-create grow-two-chunks.old grow-two-chunks.new fuzzing-patch-dump/grow-two-chunks.bdiff
+0
-155
libdfu/meson.build less more
0 cargs = [
1 '-DG_LOG_DOMAIN="Dfu"',
2 ]
3
4 install_headers('dfu.h')
5 install_headers([
6 'dfu-common.h',
7 'dfu-context.h',
8 'dfu-device.h',
9 'dfu-element.h',
10 'dfu-error.h',
11 'dfu-firmware.h',
12 'dfu-image.h',
13 'dfu-patch.h',
14 'dfu-sector.h',
15 'dfu-target.h',
16 ],
17 subdir : 'libdfu'
18 )
19
20 deps = [
21 appstream_glib,
22 giounix,
23 libm,
24 gusb,
25 ]
26
27 if get_option('enable-libelf')
28 deps += libelf
29 endif
30
31 mapfile = 'dfu.map'
32 vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
33 dfu = shared_library(
34 'dfu',
35 sources : [
36 'dfu-cipher-devo.c',
37 'dfu-cipher-xtea.c',
38 'dfu-common.c',
39 'dfu-context.c',
40 'dfu-device.c',
41 'dfu-element.c',
42 'dfu-error.c',
43 'dfu-firmware.c',
44 'dfu-format-dfu.c',
45 'dfu-format-dfuse.c',
46 'dfu-format-elf.c',
47 'dfu-format-ihex.c',
48 'dfu-format-metadata.c',
49 'dfu-format-raw.c',
50 'dfu-image.c',
51 'dfu-patch.c',
52 'dfu-sector.c',
53 'dfu-target.c',
54 ],
55 soversion : lt_current,
56 version : lt_version,
57 dependencies : deps,
58 c_args : cargs,
59 include_directories : include_directories('..'),
60 link_args : vflag,
61 link_depends : mapfile,
62 install : true
63 )
64
65 pkgg = import('pkgconfig')
66 pkgg.generate(
67 libraries : dfu,
68 requires : [ 'gio-2.0', 'gusb' ],
69 requires_private : [ 'libelf', 'appstream-glib' ],
70 subdirs : 'libdfu',
71 version : meson.project_version(),
72 name : 'dfu',
73 filebase : 'dfu',
74 description : 'libdfu is a library for reading and writing USB device firmware',
75 )
76
77 executable(
78 'dfu-tool',
79 sources : [
80 'dfu-progress-bar.c',
81 'dfu-tool.c',
82 ],
83 include_directories : [
84 include_directories('..'),
85 ],
86 dependencies : deps,
87 link_with : dfu,
88 c_args : cargs,
89 install : true,
90 install_dir : get_option('bindir')
91 )
92
93 if get_option('enable-introspection')
94 gnome.generate_gir(dfu,
95 sources : [
96 'dfu-common.c',
97 'dfu-common.h',
98 'dfu-context.c',
99 'dfu-context.h',
100 'dfu-device.c',
101 'dfu-device.h',
102 'dfu-element.c',
103 'dfu-element.h',
104 'dfu-error.c',
105 'dfu-error.h',
106 'dfu-firmware.c',
107 'dfu-firmware.h',
108 'dfu-image.c',
109 'dfu-image.h',
110 'dfu-patch.c',
111 'dfu-patch.h',
112 'dfu-sector.c',
113 'dfu-sector.h',
114 'dfu-target.c',
115 'dfu-target.h',
116 ],
117 nsversion : '1.0',
118 namespace : 'Dfu',
119 symbol_prefix : 'dfu',
120 identifier_prefix : 'Dfu',
121 export_packages : 'dfu',
122 dependencies : deps,
123 includes : [
124 'AppStreamGlib-1.0',
125 'Gio-2.0',
126 'GObject-2.0',
127 'GUsb-1.0',
128 ],
129 install : true
130 )
131 endif
132
133 if get_option('enable-tests')
134 testdatadir = join_paths(meson.current_source_dir(), 'tests')
135 cargs += '-DTESTDATADIR="' + testdatadir + '"'
136 e = executable(
137 'dfu-self-test',
138 sources : [
139 'dfu-self-test.c'
140 ],
141 include_directories : [
142 include_directories('..'),
143 ],
144 dependencies : [
145 appstream_glib,
146 gio,
147 gusb,
148 libm,
149 ],
150 link_with : dfu,
151 c_args : cargs
152 )
153 test('dfu-self-test', e)
154 endif
libdfu/tests/dev_VRBRAIN.dfu less more
Binary diff not shown
+0
-1
libdfu/tests/example.bin less more
0 hello world
libdfu/tests/example.dfu less more
Binary diff not shown
libdfu/tests/example.elf less more
Binary diff not shown
libdfu/tests/example.xdfu less more
Binary diff not shown
libdfu/tests/firmware.bin less more
Binary diff not shown
+0
-10
libdfu/tests/firmware.hex less more
0 :044000003DEF20F080
1 :10400800FACF01F0FBCF02F0E9CF03F0EACF04F0DA
2 :10401800E1CF05F0E2CF06F0D9CF07F0DACF08F00C
3 :10402800F3CF09F0F4CF0AF0F6CF0BF0F7CF0CF08E
4 :10403800F8CF0DF0F5CF0EF00EC0F5FF0DC0F8FF6C
5 :104048000CC0F7FF0BC0F6FF0AC0F4FF09C0F3FF6E
6 :1040580008C0DAFF07C0D9FF06C0E2FF05C0E1FFCC
7 :1040680004C0EAFF03C0E9FF02C0FBFF01C0FAFF7A
8 :1040780011003FEF20F0000142EF20F03DEF20F06B
9 :00000001FF
libdfu/tests/firmware.shex less more
Binary diff not shown
+0
-1
libdfu/tests/firmware.sig less more
0 deadbeef
libdfu/tests/kiibohd.dfu.bin less more
Binary diff not shown
libdfu/tests/metadata.dfu less more
Binary diff not shown
0 Planned API Changes
1 ===================
0 Migration from Version 0.9.x
1 ============================
22
3 When we next bump soname the following changes are planned:
4
5 * {sa{sv}} -> {a{sv}} -- we don't always want to send the device ID
63 * Rename FU_DEVICE_FLAG -> FWUPD_DEVICE_FLAG
7 * Remove all deprecated API
8 * Remove FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND
9 * Rename GetDetailsLocal() -> GetDetails()
10 * Rename UpdateMetadataWithId() -> UpdateMetadata()
11 * Make DeviceAdded emit a FwupdDevice, not a FwupdResult
12 * Unexport fwupd_result_to_data() and fwupd_result_new_from_data()
4 * Rename FWUPD_DEVICE_FLAG_ALLOW_ONLINE -> FWUPD_DEVICE_FLAG_UPDATABLE
5 * Rename FWUPD_DEVICE_FLAG_ALLOW_OFFLINE -> FWUPD_DEVICE_FLAG_ONLY_OFFLINE
6 * Rename fwupd_client_get_devices_simple -> fwupd_client_get_devices
7 * Rename fwupd_client_get_details_local -> fwupd_client_get_details
8 * Rename fwupd_client_update_metadata_with_id -> fwupd_client_update_metadata
9 * Rename fwupd_remote_get_uri -> fwupd_remote_get_metadata_uri
10 * Rename fwupd_remote_get_uri_asc -> fwupd_remote_get_metadata_uri_sig
11 * Rename fwupd_remote_build_uri -> fwupd_remote_build_firmware_uri
12 * Switch FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND to fwupd_checksum_guess_kind()
13 * Rename fwupd_result_update_*() to fwupd_release_*()
14 * Rename fwupd_result_*() to fwupd_device_*()
15 * Convert FwupdResult to FwupdDevice in all callbacks
16 * Rename fwupd_device_*_provider -> fwupd_device_*_plugin
17 * Convert hash types sa{sv} -> a{sv}
18 * Convert fwupd_client_get_updates() -> fwupd_client_get_upgrades()
3131
3232 #include "fwupd-client.h"
3333 #include "fwupd-common.h"
34 #include "fwupd-deprecated.h"
3435 #include "fwupd-enums.h"
3536 #include "fwupd-error.h"
3637 #include "fwupd-device-private.h"
3738 #include "fwupd-release-private.h"
3839 #include "fwupd-remote-private.h"
39 #include "fwupd-result.h"
40
41 /**
42 * SECTION:fwupd-client
43 * @short_description: a way of interfacing with the daemon
44 *
45 * An object that allows client code to call the daemon methods synchronously.
46 *
47 * See also: #FwupdDevice
48 */
4049
4150 static void fwupd_client_finalize (GObject *object);
4251
156165 GVariant *parameters,
157166 FwupdClient *client)
158167 {
159 g_autoptr(FwupdResult) res = NULL;
168 g_autoptr(FwupdDevice) dev = NULL;
160169 if (g_strcmp0 (signal_name, "Changed") == 0) {
161170 g_debug ("Emitting ::changed()");
162171 g_signal_emit (client, signals[SIGNAL_CHANGED], 0);
163172 return;
164173 }
165174 if (g_strcmp0 (signal_name, "DeviceAdded") == 0) {
166 res = fwupd_result_new_from_data (parameters);
175 dev = fwupd_device_from_variant (parameters);
167176 g_debug ("Emitting ::device-added(%s)",
168 fwupd_device_get_id (fwupd_result_get_device (res)));
169 g_signal_emit (client, signals[SIGNAL_DEVICE_ADDED], 0, res);
177 fwupd_device_get_id (dev));
178 g_signal_emit (client, signals[SIGNAL_DEVICE_ADDED], 0, dev);
170179 return;
171180 }
172181 if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) {
173 res = fwupd_result_new_from_data (parameters);
174 g_signal_emit (client, signals[SIGNAL_DEVICE_REMOVED], 0, res);
182 dev = fwupd_device_from_variant (parameters);
183 g_signal_emit (client, signals[SIGNAL_DEVICE_REMOVED], 0, dev);
175184 g_debug ("Emitting ::device-removed(%s)",
176 fwupd_device_get_id (fwupd_result_get_device (res)));
185 fwupd_device_get_id (dev));
177186 return;
178187 }
179188 if (g_strcmp0 (signal_name, "DeviceChanged") == 0) {
180 res = fwupd_result_new_from_data (parameters);
181 g_signal_emit (client, signals[SIGNAL_DEVICE_CHANGED], 0, res);
189 dev = fwupd_device_from_variant (parameters);
190 g_signal_emit (client, signals[SIGNAL_DEVICE_CHANGED], 0, dev);
182191 g_debug ("Emitting ::device-changed(%s)",
183 fwupd_device_get_id (fwupd_result_get_device (res)));
192 fwupd_device_get_id (dev));
184193 return;
185194 }
186195 g_debug ("Unknown signal name '%s' from %s", signal_name, sender_name);
241250 }
242251
243252 static GPtrArray *
244 fwupd_client_parse_results_from_data (GVariant *devices)
245 {
246 FwupdResult *res;
247 GPtrArray *results = NULL;
248 gsize sz;
249 guint i;
250 g_autoptr(GVariant) untuple = NULL;
251
252 results = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
253 untuple = g_variant_get_child_value (devices, 0);
254 sz = g_variant_n_children (untuple);
255 for (i = 0; i < sz; i++) {
256 g_autoptr(GVariant) data = NULL;
257 data = g_variant_get_child_value (untuple, i);
258 res = fwupd_result_new_from_data (data);
259 g_ptr_array_add (results, res);
260 }
261
262 return results;
263 }
264
265 static GPtrArray *
266253 fwupd_client_parse_releases_from_variant (GVariant *val)
267254 {
268255 GPtrArray *array = NULL;
276263 FwupdRelease *rel;
277264 g_autoptr(GVariant) data = NULL;
278265 data = g_variant_get_child_value (untuple, i);
279 rel = fwupd_release_new_from_data (data);
266 rel = fwupd_release_from_variant (data);
280267 if (rel == NULL)
281268 continue;
282269 g_ptr_array_add (array, rel);
298285 FwupdDevice *dev;
299286 g_autoptr(GVariant) data = NULL;
300287 data = g_variant_get_child_value (untuple, i);
301 dev = fwupd_device_new_from_data (data);
288 dev = fwupd_device_from_variant (data);
302289 if (dev == NULL)
303290 continue;
304291 g_ptr_array_add (array, dev);
317304 untuple = g_variant_get_child_value (devices, 0);
318305 sz = g_variant_n_children (untuple);
319306 for (guint i = 0; i < sz; i++) {
320 FwupdRemote *remote;
321307 g_autoptr(GVariant) data = g_variant_get_child_value (untuple, i);
322 remote = fwupd_remote_new_from_data (data);
308 FwupdRemote *remote = fwupd_remote_from_variant (data);
323309 g_ptr_array_add (remotes, remote);
324310 }
325311
362348 *
363349 * Gets all the devices registered with the daemon.
364350 *
365 * Returns: (element-type FwupdResult) (transfer container): results
366 *
367 * Since: 0.7.0
351 * Returns: (element-type FwupdDevice) (transfer container): results
352 *
353 * Since: 0.9.2
368354 **/
369355 GPtrArray *
370356 fwupd_client_get_devices (FwupdClient *client, GCancellable *cancellable, GError **error)
393379 fwupd_client_fixup_dbus_error (*error);
394380 return NULL;
395381 }
396 return fwupd_client_parse_results_from_data (val);
397 }
398
399 /**
400 * fwupd_client_get_devices_simple:
401 * @client: A #FwupdClient
402 * @cancellable: the #GCancellable, or %NULL
403 * @error: the #GError, or %NULL
404 *
405 * Gets all the devices registered with the daemon.
406 *
407 * Returns: (element-type FwupdDevice) (transfer container): results
408 *
409 * Since: 0.9.2
410 **/
411 GPtrArray *
412 fwupd_client_get_devices_simple (FwupdClient *client, GCancellable *cancellable, GError **error)
413 {
414 FwupdClientPrivate *priv = GET_PRIVATE (client);
415 g_autoptr(GVariant) val = NULL;
382 return fwupd_client_parse_devices_from_variant (val);
383 }
384
385 /**
386 * fwupd_client_get_device_by_id:
387 * @client: A #FwupdClient
388 * @device_id: the device ID, e.g. `usb:00:01:03:03`
389 * @cancellable: the #GCancellable, or %NULL
390 * @error: the #GError, or %NULL
391 *
392 * Gets a device by it's device ID.
393 *
394 * Returns: (transfer full): a #FwupdDevice or %NULL
395 *
396 * Since: 0.9.3
397 **/
398 FwupdDevice *
399 fwupd_client_get_device_by_id (FwupdClient *client,
400 const gchar *device_id,
401 GCancellable *cancellable,
402 GError **error)
403 {
404 g_autoptr(GPtrArray) devices = NULL;
416405
417406 g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
407 g_return_val_if_fail (device_id != NULL, NULL);
418408 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
419409 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
420410
411 /* get all the devices */
412 devices = fwupd_client_get_devices (client, cancellable, error);
413 if (devices == NULL)
414 return NULL;
415
416 /* find the device by ID (client side) */
417 for (guint i = 0; i < devices->len; i++) {
418 FwupdDevice *dev = g_ptr_array_index (devices, i);
419 if (g_strcmp0 (fwupd_device_get_id (dev), device_id) == 0)
420 return g_object_ref (dev);
421 }
422 g_set_error (error,
423 FWUPD_ERROR,
424 FWUPD_ERROR_NOT_FOUND,
425 "failed to find %s", device_id);
426 return NULL;
427 }
428
429 /**
430 * fwupd_client_get_releases:
431 * @client: A #FwupdClient
432 * @device_id: the device ID
433 * @cancellable: the #GCancellable, or %NULL
434 * @error: the #GError, or %NULL
435 *
436 * Gets all the releases for a specific device
437 *
438 * Returns: (element-type FwupdRelease) (transfer container): results
439 *
440 * Since: 0.9.3
441 **/
442 GPtrArray *
443 fwupd_client_get_releases (FwupdClient *client, const gchar *device_id,
444 GCancellable *cancellable, GError **error)
445 {
446 FwupdClientPrivate *priv = GET_PRIVATE (client);
447 g_autoptr(GVariant) val = NULL;
448
449 g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
450 g_return_val_if_fail (device_id != NULL, NULL);
451 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
452 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
453
421454 /* connect */
422455 if (!fwupd_client_connect (client, cancellable, error))
423456 return NULL;
424457
425458 /* call into daemon */
426459 val = g_dbus_proxy_call_sync (priv->proxy,
427 "GetDevices",
428 NULL,
460 "GetReleases",
461 g_variant_new ("(s)", device_id),
429462 G_DBUS_CALL_FLAGS_NONE,
430463 -1,
431464 cancellable,
435468 fwupd_client_fixup_dbus_error (*error);
436469 return NULL;
437470 }
438 return fwupd_client_parse_devices_from_variant (val);
439 }
440
441 /**
442 * fwupd_client_get_device_by_id:
443 * @client: A #FwupdClient
444 * @device_id: the device ID, e.g. "usb:00:01:03:03"
445 * @cancellable: the #GCancellable, or %NULL
446 * @error: the #GError, or %NULL
447 *
448 * Gets a device by it's device ID.
449 *
450 * Returns: (transfer full): a #FwupdDevice or %NULL
451 *
452 * Since: 0.9.3
453 **/
454 FwupdDevice *
455 fwupd_client_get_device_by_id (FwupdClient *client,
456 const gchar *device_id,
457 GCancellable *cancellable,
458 GError **error)
459 {
460 g_autoptr(GPtrArray) devices = NULL;
471 return fwupd_client_parse_releases_from_variant (val);
472 }
473
474 /**
475 * fwupd_client_get_downgrades:
476 * @client: A #FwupdClient
477 * @device_id: the device ID
478 * @cancellable: the #GCancellable, or %NULL
479 * @error: the #GError, or %NULL
480 *
481 * Gets all the downgrades for a specific device.
482 *
483 * Returns: (element-type FwupdRelease) (transfer container): results
484 *
485 * Since: 0.9.8
486 **/
487 GPtrArray *
488 fwupd_client_get_downgrades (FwupdClient *client, const gchar *device_id,
489 GCancellable *cancellable, GError **error)
490 {
491 FwupdClientPrivate *priv = GET_PRIVATE (client);
492 g_autoptr(GVariant) val = NULL;
461493
462494 g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
463495 g_return_val_if_fail (device_id != NULL, NULL);
464496 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
465497 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
466498
467 /* get all the devices */
468 devices = fwupd_client_get_devices_simple (client, cancellable, error);
469 if (devices == NULL)
470 return NULL;
471
472 /* find the device by ID (client side) */
473 for (guint i = 0; i < devices->len; i++) {
474 FwupdDevice *dev = g_ptr_array_index (devices, i);
475 if (g_strcmp0 (fwupd_device_get_id (dev), device_id) == 0)
476 return g_object_ref (dev);
477 }
478 g_set_error (error,
479 FWUPD_ERROR,
480 FWUPD_ERROR_NOT_FOUND,
481 "failed to find %s", device_id);
482 return NULL;
483 }
484
485 /**
486 * fwupd_client_get_updates:
487 * @client: A #FwupdClient
488 * @cancellable: the #GCancellable, or %NULL
489 * @error: the #GError, or %NULL
490 *
491 * Gets all the devices with known updates.
492 *
493 * Returns: (element-type FwupdResult) (transfer container): results
494 *
495 * Since: 0.7.0
496 **/
497 GPtrArray *
498 fwupd_client_get_updates (FwupdClient *client, GCancellable *cancellable, GError **error)
499 {
500 FwupdClientPrivate *priv = GET_PRIVATE (client);
501 g_autoptr(GVariant) val = NULL;
502
503 g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
504 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
505 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
506
507499 /* connect */
508500 if (!fwupd_client_connect (client, cancellable, error))
509501 return NULL;
510502
511503 /* call into daemon */
512504 val = g_dbus_proxy_call_sync (priv->proxy,
513 "GetUpdates",
514 NULL,
505 "GetDowngrades",
506 g_variant_new ("(s)", device_id),
515507 G_DBUS_CALL_FLAGS_NONE,
516508 -1,
517509 cancellable,
521513 fwupd_client_fixup_dbus_error (*error);
522514 return NULL;
523515 }
524 return fwupd_client_parse_results_from_data (val);
525 }
526
527 /**
528 * fwupd_client_get_releases:
516 return fwupd_client_parse_releases_from_variant (val);
517 }
518
519 /**
520 * fwupd_client_get_upgrades:
529521 * @client: A #FwupdClient
530522 * @device_id: the device ID
531523 * @cancellable: the #GCancellable, or %NULL
532524 * @error: the #GError, or %NULL
533525 *
534 * Gets all the releases for a specific device
526 * Gets all the upgrades for a specific device.
535527 *
536528 * Returns: (element-type FwupdRelease) (transfer container): results
537529 *
538 * Since: 0.9.3
530 * Since: 0.9.8
539531 **/
540532 GPtrArray *
541 fwupd_client_get_releases (FwupdClient *client, const gchar *device_id,
533 fwupd_client_get_upgrades (FwupdClient *client, const gchar *device_id,
542534 GCancellable *cancellable, GError **error)
543535 {
544536 FwupdClientPrivate *priv = GET_PRIVATE (client);
555547
556548 /* call into daemon */
557549 val = g_dbus_proxy_call_sync (priv->proxy,
558 "GetReleases",
550 "GetUpgrades",
559551 g_variant_new ("(s)", device_id),
560552 G_DBUS_CALL_FLAGS_NONE,
561553 -1,
783775 *
784776 * Gets the results of a previous firmware update for a specific device.
785777 *
786 * Returns: (transfer full): a #FwupdResult, or %NULL for failure
778 * Returns: (transfer full): a #FwupdDevice, or %NULL for failure
787779 *
788780 * Since: 0.7.0
789781 **/
790 FwupdResult *
782 FwupdDevice *
791783 fwupd_client_get_results (FwupdClient *client, const gchar *device_id,
792784 GCancellable *cancellable, GError **error)
793785 {
819811 helper->error = NULL;
820812 return NULL;
821813 }
822 return fwupd_result_new_from_data (helper->val);
814 return fwupd_device_from_variant (helper->val);
823815 }
824816
825817 static void
954946 /**
955947 * fwupd_client_get_details:
956948 * @client: A #FwupdClient
957 * @filename: the firmware filename, e.g. "firmware.cab"
949 * @filename: the firmware filename, e.g. `firmware.cab`
958950 * @cancellable: the #GCancellable, or %NULL
959951 * @error: the #GError, or %NULL
960952 *
961953 * Gets details about a specific firmware file.
962954 *
963 * Returns: (transfer full): a #FwupdResult, or %NULL for failure
964 *
965 * Since: 0.7.0
966 **/
967 FwupdResult *
955 * Returns: (transfer container) (element-type FwupdDevice): an array of results
956 *
957 * Since: 1.0.0
958 **/
959 GPtrArray *
968960 fwupd_client_get_details (FwupdClient *client, const gchar *filename,
969961 GCancellable *cancellable, GError **error)
970 {
971 g_autoptr(GPtrArray) results = NULL;
972 results = fwupd_client_get_details_local (client, filename, cancellable, error);
973 if (results == NULL)
974 return NULL;
975 if (results->len == 0) {
976 g_set_error (error,
977 FWUPD_ERROR,
978 FWUPD_ERROR_INVALID_FILE,
979 "failed to open %s",
980 filename);
981 return NULL;
982 }
983 return g_object_ref (g_ptr_array_index (results, 0));
984 }
985
986 /**
987 * fwupd_client_get_details_local:
988 * @client: A #FwupdClient
989 * @filename: the firmware filename, e.g. "firmware.cab"
990 * @cancellable: the #GCancellable, or %NULL
991 * @error: the #GError, or %NULL
992 *
993 * Gets details about a specific firmware file.
994 *
995 * Returns: (transfer container) (element-type FwupdResult): an array of results
996 *
997 * Since: 0.7.2
998 **/
999 GPtrArray *
1000 fwupd_client_get_details_local (FwupdClient *client, const gchar *filename,
1001 GCancellable *cancellable, GError **error)
1002962 {
1003963 FwupdClientPrivate *priv = GET_PRIVATE (client);
1004964 GVariant *body;
1035995 request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
1036996 FWUPD_DBUS_PATH,
1037997 FWUPD_DBUS_INTERFACE,
1038 "GetDetailsLocal");
998 "GetDetails");
1039999 g_dbus_message_set_unix_fd_list (request, fd_list);
10401000
10411001 /* g_unix_fd_list_append did a dup() already */
10621022 }
10631023
10641024 /* return results */
1065 return fwupd_client_parse_results_from_data (helper->val);
1025 return fwupd_client_parse_devices_from_variant (helper->val);
10661026 }
10671027
10681028 /**
11221082 /**
11231083 * fwupd_client_update_metadata:
11241084 * @client: A #FwupdClient
1085 * @remote_id: the remote ID, e.g. `lvfs-testing`
11251086 * @metadata_fn: the XML metadata filename
11261087 * @signature_fn: the GPG signature file
11271088 * @cancellable: the #GCancellable, or %NULL
11311092 * and metadata signing file to be passed into the daemon to be checked and
11321093 * parsed.
11331094 *
1095 * The @remote_id allows the firmware to be tagged so that the remote can be
1096 * matched when the firmware is downloaded.
1097 *
11341098 * Returns: %TRUE for success
11351099 *
1136 * Since: 0.7.0
1100 * Since: 1.0.0
11371101 **/
11381102 gboolean
11391103 fwupd_client_update_metadata (FwupdClient *client,
1104 const gchar *remote_id,
11401105 const gchar *metadata_fn,
11411106 const gchar *signature_fn,
11421107 GCancellable *cancellable,
11431108 GError **error)
1144 {
1145 return fwupd_client_update_metadata_with_id (client,
1146 "lvfs", /* remote_id */
1147 metadata_fn,
1148 signature_fn,
1149 cancellable,
1150 error);
1151 }
1152
1153 /**
1154 * fwupd_client_update_metadata_with_id:
1155 * @client: A #FwupdClient
1156 * @remote_id: the remote ID, e.g. "lvfs-testing"
1157 * @metadata_fn: the XML metadata filename
1158 * @signature_fn: the GPG signature file
1159 * @cancellable: the #GCancellable, or %NULL
1160 * @error: the #GError, or %NULL
1161 *
1162 * Updates the metadata. This allows a session process to download the metadata
1163 * and metadata signing file to be passed into the daemon to be checked and
1164 * parsed.
1165 *
1166 * The @remote_id allows the firmware to be tagged so that the remote can be
1167 * matched when the firmware is downloaded.
1168 *
1169 * Returns: %TRUE for success
1170 *
1171 * Since: 0.9.3
1172 **/
1173 gboolean
1174 fwupd_client_update_metadata_with_id (FwupdClient *client,
1175 const gchar *remote_id,
1176 const gchar *metadata_fn,
1177 const gchar *signature_fn,
1178 GCancellable *cancellable,
1179 GError **error)
11801109 {
11811110 FwupdClientPrivate *priv = GET_PRIVATE (client);
11821111 GVariant *body;
12251154 request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
12261155 FWUPD_DBUS_PATH,
12271156 FWUPD_DBUS_INTERFACE,
1228 "UpdateMetadataWithId");
1157 "UpdateMetadata");
12291158 g_dbus_message_set_unix_fd_list (request, fd_list);
12301159
12311160 /* g_unix_fd_list_append did a dup() already */
12951224 return fwupd_client_parse_remotes_from_data (val);
12961225 }
12971226
1227 /**
1228 * fwupd_client_modify_remote:
1229 * @client: A #FwupdClient
1230 * @remote_id: the remote ID, e.g. `lvfs-testing`
1231 * @key: the key, e.g. `Enabled`
1232 * @value: the key, e.g. `true`
1233 * @cancellable: the #GCancellable, or %NULL
1234 * @error: the #GError, or %NULL
1235 *
1236 * Modifies a system remote in a specific way.
1237 *
1238 * NOTE: User authentication may be required to complete this action.
1239 *
1240 * Returns: %TRUE for success
1241 *
1242 * Since: 0.9.8
1243 **/
1244 gboolean
1245 fwupd_client_modify_remote (FwupdClient *client,
1246 const gchar *remote_id,
1247 const gchar *key,
1248 const gchar *value,
1249 GCancellable *cancellable,
1250 GError **error)
1251 {
1252 FwupdClientPrivate *priv = GET_PRIVATE (client);
1253 g_autoptr(GVariant) val = NULL;
1254
1255 g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE);
1256 g_return_val_if_fail (remote_id != NULL, FALSE);
1257 g_return_val_if_fail (key != NULL, FALSE);
1258 g_return_val_if_fail (value != NULL, FALSE);
1259 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
1260 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1261
1262 /* connect */
1263 if (!fwupd_client_connect (client, cancellable, error))
1264 return FALSE;
1265
1266 /* call into daemon */
1267 val = g_dbus_proxy_call_sync (priv->proxy,
1268 "ModifyRemote",
1269 g_variant_new ("(sss)", remote_id, key, value),
1270 G_DBUS_CALL_FLAGS_NONE,
1271 -1,
1272 cancellable,
1273 error);
1274 if (val == NULL) {
1275 if (error != NULL)
1276 fwupd_client_fixup_dbus_error (*error);
1277 return FALSE;
1278 }
1279 return TRUE;
1280 }
1281
12981282 static FwupdRemote *
12991283 fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
13001284 {
13091293 /**
13101294 * fwupd_client_get_remote_by_id:
13111295 * @client: A #FwupdClient
1312 * @remote_id: the remote ID, e.g. "lvfs-testing"
1296 * @remote_id: the remote ID, e.g. `lvfs-testing`
13131297 * @cancellable: the #GCancellable, or %NULL
13141298 * @error: the #GError, or %NULL
13151299 *
14391423 /**
14401424 * FwupdClient::device-added:
14411425 * @client: the #FwupdClient instance that emitted the signal
1442 * @result: the #FwupdResult
1426 * @result: the #FwupdDevice
14431427 *
14441428 * The ::device-added signal is emitted when a device has been
14451429 * added.
14511435 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
14521436 G_STRUCT_OFFSET (FwupdClientClass, device_added),
14531437 NULL, NULL, g_cclosure_marshal_generic,
1454 G_TYPE_NONE, 1, FWUPD_TYPE_RESULT);
1438 G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE);
14551439
14561440 /**
14571441 * FwupdClient::device-removed:
14581442 * @client: the #FwupdClient instance that emitted the signal
1459 * @result: the #FwupdResult
1443 * @result: the #FwupdDevice
14601444 *
14611445 * The ::device-removed signal is emitted when a device has been
14621446 * removed.
14681452 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
14691453 G_STRUCT_OFFSET (FwupdClientClass, device_removed),
14701454 NULL, NULL, g_cclosure_marshal_generic,
1471 G_TYPE_NONE, 1, FWUPD_TYPE_RESULT);
1455 G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE);
14721456
14731457 /**
14741458 * FwupdClient::device-changed:
14751459 * @client: the #FwupdClient instance that emitted the signal
1476 * @result: the #FwupdResult
1460 * @result: the #FwupdDevice
14771461 *
14781462 * The ::device-changed signal is emitted when a device has been
14791463 * changed in some way, e.g. the version number is updated.
14851469 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
14861470 G_STRUCT_OFFSET (FwupdClientClass, device_changed),
14871471 NULL, NULL, g_cclosure_marshal_generic,
1488 G_TYPE_NONE, 1, FWUPD_TYPE_RESULT);
1472 G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE);
14891473
14901474 /**
14911475 * FwupdClient:status:
2525 #include <gio/gio.h>
2626
2727 #include "fwupd-enums.h"
28 #include "fwupd-device.h"
2829 #include "fwupd-remote.h"
29 #include "fwupd-result.h"
3030
3131 G_BEGIN_DECLS
3232
4040 void (*status_changed) (FwupdClient *client,
4141 FwupdStatus status);
4242 void (*device_added) (FwupdClient *client,
43 FwupdResult *result);
43 FwupdDevice *result);
4444 void (*device_removed) (FwupdClient *client,
45 FwupdResult *result);
45 FwupdDevice *result);
4646 void (*device_changed) (FwupdClient *client,
47 FwupdResult *result);
47 FwupdDevice *result);
4848 /*< private >*/
4949 void (*_fwupd_reserved1) (void);
5050 void (*_fwupd_reserved2) (void);
5151 void (*_fwupd_reserved3) (void);
5252 void (*_fwupd_reserved4) (void);
53 void (*_fwupd_reserved5) (void);
54 void (*_fwupd_reserved6) (void);
55 void (*_fwupd_reserved7) (void);
5356 };
5457
5558 FwupdClient *fwupd_client_new (void);
5659 gboolean fwupd_client_connect (FwupdClient *client,
5760 GCancellable *cancellable,
5861 GError **error);
59 G_DEPRECATED_FOR(fwupd_client_get_devices_simple)
6062 GPtrArray *fwupd_client_get_devices (FwupdClient *client,
61 GCancellable *cancellable,
62 GError **error);
63 GPtrArray *fwupd_client_get_devices_simple (FwupdClient *client,
64 GCancellable *cancellable,
65 GError **error);
66 GPtrArray *fwupd_client_get_updates (FwupdClient *client,
6763 GCancellable *cancellable,
6864 GError **error);
6965 GPtrArray *fwupd_client_get_releases (FwupdClient *client,
7066 const gchar *device_id,
7167 GCancellable *cancellable,
7268 GError **error);
73 GPtrArray *fwupd_client_get_details_local (FwupdClient *client,
69 GPtrArray *fwupd_client_get_downgrades (FwupdClient *client,
70 const gchar *device_id,
71 GCancellable *cancellable,
72 GError **error);
73 GPtrArray *fwupd_client_get_upgrades (FwupdClient *client,
74 const gchar *device_id,
75 GCancellable *cancellable,
76 GError **error);
77 GPtrArray *fwupd_client_get_details (FwupdClient *client,
7478 const gchar *filename,
7579 GCancellable *cancellable,
7680 GError **error);
9094 const gchar *device_id,
9195 GCancellable *cancellable,
9296 GError **error);
93 FwupdResult *fwupd_client_get_results (FwupdClient *client,
97 FwupdDevice *fwupd_client_get_results (FwupdClient *client,
9498 const gchar *device_id,
95 GCancellable *cancellable,
96 GError **error);
97 G_DEPRECATED_FOR(fwupd_client_get_details_local)
98 FwupdResult *fwupd_client_get_details (FwupdClient *client,
99 const gchar *filename,
10099 GCancellable *cancellable,
101100 GError **error);
102101 FwupdDevice *fwupd_client_get_device_by_id (FwupdClient *client,
109108 FwupdInstallFlags install_flags,
110109 GCancellable *cancellable,
111110 GError **error);
112 G_DEPRECATED_FOR(fwupd_client_update_metadata_with_id)
113111 gboolean fwupd_client_update_metadata (FwupdClient *client,
112 const gchar *remote_id,
114113 const gchar *metadata_fn,
115114 const gchar *signature_fn,
116115 GCancellable *cancellable,
117116 GError **error);
118 gboolean fwupd_client_update_metadata_with_id (FwupdClient *client,
117 gboolean fwupd_client_modify_remote (FwupdClient *client,
119118 const gchar *remote_id,
120 const gchar *metadata_fn,
121 const gchar *signature_fn,
119 const gchar *key,
120 const gchar *value,
122121 GCancellable *cancellable,
123122 GError **error);
124123 FwupdStatus fwupd_client_get_status (FwupdClient *client);
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __FWUPD_DEPRECATED_H
22 #define __FWUPD_DEPRECATED_H
23
24 /* indeed, nothing */
25
26 #endif /* __FWUPD_DEPRECATED_H */
2727
2828 G_BEGIN_DECLS
2929
30 FwupdDevice *fwupd_device_new_from_data (GVariant *data);
31 GVariant *fwupd_device_to_data (FwupdDevice *device,
32 const gchar *type_string);
33 void fwupd_device_to_variant_builder (FwupdDevice *device,
34 GVariantBuilder *builder);
35 void fwupd_device_from_key_value (FwupdDevice *device,
36 const gchar *key,
37 GVariant *value);
30 FwupdDevice *fwupd_device_from_variant (GVariant *data);
31 GVariant *fwupd_device_to_variant (FwupdDevice *device);
3832
3933 G_END_DECLS
4034
2828 #include "fwupd-enums-private.h"
2929 #include "fwupd-error.h"
3030 #include "fwupd-device-private.h"
31 #include "fwupd-release-private.h"
32
33 /**
34 * SECTION:fwupd-device
35 * @short_description: a hardware device
36 *
37 * An object that represents a physical device on the host.
38 *
39 * See also: #FwupdRelease
40 */
3141
3242 static void fwupd_device_finalize (GObject *object);
3343
3848 guint64 flags;
3949 gchar *appstream_id;
4050 GPtrArray *guids;
51 GPtrArray *icons;
4152 gchar *name;
4253 gchar *summary;
4354 gchar *description;
4455 gchar *vendor;
4556 gchar *vendor_id;
4657 gchar *homepage;
47 gchar *provider;
58 gchar *plugin;
4859 gchar *version;
4960 gchar *version_lowest;
5061 gchar *version_bootloader;
5162 GPtrArray *checksums;
5263 guint32 flashes_left;
64 FwupdUpdateState update_state;
65 gchar *update_error;
66 GPtrArray *releases;
5367 } FwupdDevicePrivate;
5468
5569 G_DEFINE_TYPE_WITH_PRIVATE (FwupdDevice, fwupd_device, G_TYPE_OBJECT)
153167 /**
154168 * fwupd_device_set_id:
155169 * @device: A #FwupdDevice
156 * @id: the device ID, e.g. "USB:foo"
170 * @id: the device ID, e.g. `USB:foo`
157171 *
158172 * Sets the ID.
159173 *
189203 /**
190204 * fwupd_device_has_guid:
191205 * @device: A #FwupdDevice
192 * @guid: the GUID, e.g. "2082b5e0-7a64-478a-b1b2-e3404fab6dad"
206 * @guid: the GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad`
193207 *
194208 * Finds out if the device has this specific GUID.
195209 *
201215 fwupd_device_has_guid (FwupdDevice *device, const gchar *guid)
202216 {
203217 FwupdDevicePrivate *priv = GET_PRIVATE (device);
204 guint i;
205218
206219 g_return_val_if_fail (FWUPD_IS_DEVICE (device), FALSE);
207220
208 for (i = 0; i < priv->guids->len; i++) {
221 for (guint i = 0; i < priv->guids->len; i++) {
209222 const gchar *guid_tmp = g_ptr_array_index (priv->guids, i);
210223 if (g_strcmp0 (guid, guid_tmp) == 0)
211224 return TRUE;
216229 /**
217230 * fwupd_device_add_guid:
218231 * @device: A #FwupdDevice
219 * @guid: the GUID, e.g. "2082b5e0-7a64-478a-b1b2-e3404fab6dad"
232 * @guid: the GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad`
220233 *
221234 * Adds the GUID if it does not already exist.
222235 *
253266 }
254267
255268 /**
269 * fwupd_device_get_icons:
270 * @device: A #FwupdDevice
271 *
272 * Gets the icon names to use for the device.
273 *
274 * NOTE: Icons specified without a full path are stock icons and should
275 * be loaded from the users icon theme.
276 *
277 * Returns: (element-type utf8) (transfer none): an array of icon names
278 *
279 * Since: 0.9.8
280 **/
281 GPtrArray *
282 fwupd_device_get_icons (FwupdDevice *device)
283 {
284 FwupdDevicePrivate *priv = GET_PRIVATE (device);
285 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
286 return priv->icons;
287 }
288
289 static gboolean
290 fwupd_device_has_icon (FwupdDevice *device, const gchar *icon)
291 {
292 FwupdDevicePrivate *priv = GET_PRIVATE (device);
293 for (guint i = 0; i < priv->icons->len; i++) {
294 const gchar *icon_tmp = g_ptr_array_index (priv->icons, i);
295 if (g_strcmp0 (icon, icon_tmp) == 0)
296 return TRUE;
297 }
298 return FALSE;
299 }
300
301 /**
302 * fwupd_device_add_icon:
303 * @device: A #FwupdDevice
304 * @icon: the name, e.g. `input-mouse` or `/usr/share/icons/foo.png`
305 *
306 * Adds the icon name if it does not already exist.
307 *
308 * Since: 0.9.8
309 **/
310 void
311 fwupd_device_add_icon (FwupdDevice *device, const gchar *icon)
312 {
313 FwupdDevicePrivate *priv = GET_PRIVATE (device);
314 g_return_if_fail (FWUPD_IS_DEVICE (device));
315 if (fwupd_device_has_icon (device, icon))
316 return;
317 g_ptr_array_add (priv->icons, g_strdup (icon));
318 }
319
320 /**
256321 * fwupd_device_get_name:
257322 * @device: A #FwupdDevice
258323 *
273338 /**
274339 * fwupd_device_set_name:
275340 * @device: A #FwupdDevice
276 * @name: the device name, e.g. "ColorHug2"
341 * @name: the device name, e.g. `ColorHug2`
277342 *
278343 * Sets the device name.
279344 *
417482 /**
418483 * fwupd_device_set_version:
419484 * @device: A #FwupdDevice
420 * @version: the device version, e.g. "1.2.3"
485 * @version: the device version, e.g. `1.2.3`
421486 *
422487 * Sets the device version.
423488 *
505570 }
506571
507572 /**
508 * fwupd_device_device_get_flashes_left:
573 * fwupd_device_get_flashes_left:
509574 * @device: A #FwupdDevice
510575 *
511576 * Gets the number of flash cycles left on the device
523588 }
524589
525590 /**
526 * fwupd_device_device_set_flashes_left:
591 * fwupd_device_set_flashes_left:
527592 * @device: A #FwupdDevice
528593 * @flashes_left: the description
529594 *
540605 }
541606
542607 /**
543 * fwupd_device_get_provider:
544 * @device: A #FwupdDevice
545 *
546 * Gets the device provider.
547 *
548 * Returns: the device provider, or %NULL if unset
549 *
550 * Since: 0.9.3
608 * fwupd_device_get_plugin:
609 * @device: A #FwupdDevice
610 *
611 * Gets the plugin that created the device.
612 *
613 * Returns: the plugin name, or %NULL if unset
614 *
615 * Since: 1.0.0
551616 **/
552617 const gchar *
553 fwupd_device_get_provider (FwupdDevice *device)
554 {
555 FwupdDevicePrivate *priv = GET_PRIVATE (device);
556 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
557 return priv->provider;
558 }
559
560 /**
561 * fwupd_device_set_provider:
562 * @device: A #FwupdDevice
563 * @provider: the provider name, e.g. "colorhug"
564 *
565 * Sets the device provider.
566 *
567 * Since: 0.9.3
568 **/
569 void
570 fwupd_device_set_provider (FwupdDevice *device, const gchar *provider)
571 {
572 FwupdDevicePrivate *priv = GET_PRIVATE (device);
573 g_return_if_fail (FWUPD_IS_DEVICE (device));
574 g_free (priv->provider);
575 priv->provider = g_strdup (provider);
618 fwupd_device_get_plugin (FwupdDevice *device)
619 {
620 FwupdDevicePrivate *priv = GET_PRIVATE (device);
621 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
622 return priv->plugin;
623 }
624
625 /**
626 * fwupd_device_set_plugin:
627 * @device: A #FwupdDevice
628 * @plugin: the plugin name, e.g. `colorhug`
629 *
630 * Sets the plugin that created the device.
631 *
632 * Since: 1.0.0
633 **/
634 void
635 fwupd_device_set_plugin (FwupdDevice *device, const gchar *plugin)
636 {
637 FwupdDevicePrivate *priv = GET_PRIVATE (device);
638 g_return_if_fail (FWUPD_IS_DEVICE (device));
639 g_free (priv->plugin);
640 priv->plugin = g_strdup (plugin);
576641 }
577642
578643 /**
734799 priv->modified = modified;
735800 }
736801
737 void
738 fwupd_device_to_variant_builder (FwupdDevice *device, GVariantBuilder *builder)
739 {
740 FwupdDevicePrivate *priv = GET_PRIVATE (device);
802 /**
803 * fwupd_device_to_variant:
804 * @device: A #FwupdDevice
805 *
806 * Creates a GVariant from the device data.
807 *
808 * Returns: the GVariant, or %NULL for error
809 *
810 * Since: 1.0.0
811 **/
812 GVariant *
813 fwupd_device_to_variant (FwupdDevice *device)
814 {
815 FwupdDevicePrivate *priv = GET_PRIVATE (device);
816 GVariantBuilder builder;
817
818 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
819
820 /* create an array with all the metadata in */
821 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
822 if (priv->id != NULL) {
823 g_variant_builder_add (&builder, "{sv}",
824 FWUPD_RESULT_KEY_DEVICE_ID,
825 g_variant_new_string (priv->id));
826 }
741827 if (priv->guids->len > 0) {
742 guint i;
743 g_autoptr(GString) str = g_string_new ("");
744 for (i = 0; i < priv->guids->len; i++) {
745 const gchar *guid = g_ptr_array_index (priv->guids, i);
746 g_string_append_printf (str, "%s,", guid);
747 }
748 if (str->len > 0)
749 g_string_truncate (str, str->len - 1);
750 g_variant_builder_add (builder, "{sv}",
828 const gchar * const *tmp = (const gchar * const *) priv->guids->pdata;
829 g_variant_builder_add (&builder, "{sv}",
751830 FWUPD_RESULT_KEY_GUID,
752 g_variant_new_string (str->str));
831 g_variant_new_strv (tmp, priv->guids->len));
832 }
833 if (priv->icons->len > 0) {
834 const gchar * const *tmp = (const gchar * const *) priv->icons->pdata;
835 g_variant_builder_add (&builder, "{sv}",
836 FWUPD_RESULT_KEY_ICON,
837 g_variant_new_strv (tmp, priv->icons->len));
753838 }
754839 if (priv->name != NULL) {
755 g_variant_builder_add (builder, "{sv}",
756 FWUPD_RESULT_KEY_DEVICE_NAME,
840 g_variant_builder_add (&builder, "{sv}",
841 FWUPD_RESULT_KEY_NAME,
757842 g_variant_new_string (priv->name));
758843 }
759844 if (priv->vendor != NULL) {
760 g_variant_builder_add (builder, "{sv}",
761 FWUPD_RESULT_KEY_DEVICE_VENDOR,
845 g_variant_builder_add (&builder, "{sv}",
846 FWUPD_RESULT_KEY_VENDOR,
762847 g_variant_new_string (priv->vendor));
763848 }
764849 if (priv->vendor_id != NULL) {
765 g_variant_builder_add (builder, "{sv}",
766 FWUPD_RESULT_KEY_DEVICE_VENDOR_ID,
850 g_variant_builder_add (&builder, "{sv}",
851 FWUPD_RESULT_KEY_VENDOR_ID,
767852 g_variant_new_string (priv->vendor_id));
768853 }
769854 if (priv->flags > 0) {
770 g_variant_builder_add (builder, "{sv}",
771 FWUPD_RESULT_KEY_DEVICE_FLAGS,
855 g_variant_builder_add (&builder, "{sv}",
856 FWUPD_RESULT_KEY_FLAGS,
772857 g_variant_new_uint64 (priv->flags));
773858 }
774859 if (priv->created > 0) {
775 g_variant_builder_add (builder, "{sv}",
776 FWUPD_RESULT_KEY_DEVICE_CREATED,
860 g_variant_builder_add (&builder, "{sv}",
861 FWUPD_RESULT_KEY_CREATED,
777862 g_variant_new_uint64 (priv->created));
778863 }
779864 if (priv->modified > 0) {
780 g_variant_builder_add (builder, "{sv}",
781 FWUPD_RESULT_KEY_DEVICE_MODIFIED,
865 g_variant_builder_add (&builder, "{sv}",
866 FWUPD_RESULT_KEY_MODIFIED,
782867 g_variant_new_uint64 (priv->modified));
783868 }
784869
785870 if (priv->description != NULL) {
786 g_variant_builder_add (builder, "{sv}",
787 FWUPD_RESULT_KEY_DEVICE_DESCRIPTION,
871 g_variant_builder_add (&builder, "{sv}",
872 FWUPD_RESULT_KEY_DESCRIPTION,
788873 g_variant_new_string (priv->description));
874 }
875 if (priv->summary != NULL) {
876 g_variant_builder_add (&builder, "{sv}",
877 FWUPD_RESULT_KEY_SUMMARY,
878 g_variant_new_string (priv->summary));
789879 }
790880 if (priv->checksums->len > 0) {
791881 g_autoptr(GString) str = g_string_new ("");
795885 }
796886 if (str->len > 0)
797887 g_string_truncate (str, str->len - 1);
798 g_variant_builder_add (builder, "{sv}",
799 FWUPD_RESULT_KEY_DEVICE_CHECKSUM,
888 g_variant_builder_add (&builder, "{sv}",
889 FWUPD_RESULT_KEY_CHECKSUM,
800890 g_variant_new_string (str->str));
801891 }
802 if (priv->provider != NULL) {
803 g_variant_builder_add (builder, "{sv}",
804 FWUPD_RESULT_KEY_DEVICE_PLUGIN,
805 g_variant_new_string (priv->provider));
892 if (priv->plugin != NULL) {
893 g_variant_builder_add (&builder, "{sv}",
894 FWUPD_RESULT_KEY_PLUGIN,
895 g_variant_new_string (priv->plugin));
806896 }
807897 if (priv->version != NULL) {
808 g_variant_builder_add (builder, "{sv}",
809 FWUPD_RESULT_KEY_DEVICE_VERSION,
898 g_variant_builder_add (&builder, "{sv}",
899 FWUPD_RESULT_KEY_VERSION,
810900 g_variant_new_string (priv->version));
811901 }
812902 if (priv->version_lowest != NULL) {
813 g_variant_builder_add (builder, "{sv}",
814 FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST,
903 g_variant_builder_add (&builder, "{sv}",
904 FWUPD_RESULT_KEY_VERSION_LOWEST,
815905 g_variant_new_string (priv->version_lowest));
816906 }
817907 if (priv->version_bootloader != NULL) {
818 g_variant_builder_add (builder, "{sv}",
819 FWUPD_RESULT_KEY_DEVICE_VERSION_BOOTLOADER,
908 g_variant_builder_add (&builder, "{sv}",
909 FWUPD_RESULT_KEY_VERSION_BOOTLOADER,
820910 g_variant_new_string (priv->version_bootloader));
821911 }
822912 if (priv->flashes_left > 0) {
823 g_variant_builder_add (builder, "{sv}",
824 FWUPD_RESULT_KEY_DEVICE_FLASHES_LEFT,
913 g_variant_builder_add (&builder, "{sv}",
914 FWUPD_RESULT_KEY_FLASHES_LEFT,
825915 g_variant_new_uint32 (priv->flashes_left));
826916 }
827 }
828
829 /**
830 * fwupd_device_to_data:
831 * @device: A #FwupdDevice
832 * @type_string: The Gvariant type string, e.g. "a{sv}" or "(a{sv})"
833 *
834 * Creates a GVariant from the device data.
835 *
836 * Returns: the GVariant, or %NULL for error
837 *
838 * Since: 0.9.3
839 **/
840 GVariant *
841 fwupd_device_to_data (FwupdDevice *device, const gchar *type_string)
842 {
843 GVariantBuilder builder;
844
845 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
846 g_return_val_if_fail (type_string != NULL, NULL);
917 if (priv->update_error != NULL) {
918 g_variant_builder_add (&builder, "{sv}",
919 FWUPD_RESULT_KEY_UPDATE_ERROR,
920 g_variant_new_string (priv->update_error));
921 }
922 if (priv->update_state != FWUPD_UPDATE_STATE_UNKNOWN) {
923 g_variant_builder_add (&builder, "{sv}",
924 FWUPD_RESULT_KEY_UPDATE_STATE,
925 g_variant_new_uint32 (priv->update_state));
926 }
847927
848928 /* create an array with all the metadata in */
849 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
850 fwupd_device_to_variant_builder (device, &builder);
851
852 /* supported types */
853 if (g_strcmp0 (type_string, "a{sv}") == 0)
854 return g_variant_new ("a{sv}", &builder);
855 if (g_strcmp0 (type_string, "(a{sv})") == 0)
856 return g_variant_new ("(a{sv})", &builder);
857 return NULL;
858 }
859
860 void
929 if (priv->releases->len > 0) {
930 g_autofree GVariant **children = NULL;
931 children = g_new0 (GVariant *, priv->releases->len);
932 for (guint i = 0; i < priv->releases->len; i++) {
933 FwupdRelease *release = g_ptr_array_index (priv->releases, i);
934 children[i] = fwupd_release_to_variant (release);
935 }
936 g_variant_builder_add (&builder, "{sv}",
937 FWUPD_RESULT_KEY_RELEASE,
938 g_variant_new_array (G_VARIANT_TYPE ("a{sv}"),
939 children,
940 priv->releases->len));
941 }
942 return g_variant_new ("a{sv}", &builder);
943 }
944
945 static void
861946 fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *value)
862947 {
863 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_FLAGS) == 0) {
948 if (g_strcmp0 (key, FWUPD_RESULT_KEY_RELEASE) == 0) {
949 GVariantIter iter;
950 GVariant *child;
951 g_variant_iter_init (&iter, value);
952 while ((child = g_variant_iter_next_value (&iter))) {
953 g_autoptr(FwupdRelease) release = fwupd_release_from_variant (child);
954 if (release != NULL)
955 fwupd_device_add_release (device, release);
956 g_variant_unref (child);
957 }
958 return;
959 }
960 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_ID) == 0) {
961 fwupd_device_set_id (device, g_variant_get_string (value, NULL));
962 return;
963 }
964 if (g_strcmp0 (key, FWUPD_RESULT_KEY_FLAGS) == 0) {
864965 fwupd_device_set_flags (device, g_variant_get_uint64 (value));
865966 return;
866967 }
867 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CREATED) == 0) {
968 if (g_strcmp0 (key, FWUPD_RESULT_KEY_CREATED) == 0) {
868969 fwupd_device_set_created (device, g_variant_get_uint64 (value));
869970 return;
870971 }
871 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_MODIFIED) == 0) {
972 if (g_strcmp0 (key, FWUPD_RESULT_KEY_MODIFIED) == 0) {
872973 fwupd_device_set_modified (device, g_variant_get_uint64 (value));
873974 return;
874975 }
875976 if (g_strcmp0 (key, FWUPD_RESULT_KEY_GUID) == 0) {
876 guint i;
877 const gchar *guids = g_variant_get_string (value, NULL);
878 g_auto(GStrv) split = g_strsplit (guids, ",", -1);
879 for (i = 0; split[i] != NULL; i++)
880 fwupd_device_add_guid (device, split[i]);
881 return;
882 }
883 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_NAME) == 0) {
977 g_autofree const gchar **guids = g_variant_get_strv (value, NULL);
978 for (guint i = 0; guids[i] != NULL; i++)
979 fwupd_device_add_guid (device, guids[i]);
980 return;
981 }
982 if (g_strcmp0 (key, FWUPD_RESULT_KEY_ICON) == 0) {
983 g_autofree const gchar **icons = g_variant_get_strv (value, NULL);
984 for (guint i = 0; icons[i] != NULL; i++)
985 fwupd_device_add_icon (device, icons[i]);
986 return;
987 }
988 if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME) == 0) {
884989 fwupd_device_set_name (device, g_variant_get_string (value, NULL));
885990 return;
886991 }
887 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_VENDOR) == 0) {
992 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR) == 0) {
888993 fwupd_device_set_vendor (device, g_variant_get_string (value, NULL));
889994 return;
890995 }
891 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_VENDOR_ID) == 0) {
996 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR_ID) == 0) {
892997 fwupd_device_set_vendor_id (device, g_variant_get_string (value, NULL));
893998 return;
894999 }
895 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_DESCRIPTION) == 0) {
1000 if (g_strcmp0 (key, FWUPD_RESULT_KEY_SUMMARY) == 0) {
1001 fwupd_device_set_summary (device, g_variant_get_string (value, NULL));
1002 return;
1003 }
1004 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) {
8961005 fwupd_device_set_description (device, g_variant_get_string (value, NULL));
8971006 return;
8981007 }
899 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_CHECKSUM) == 0) {
900 guint i;
1008 if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) {
9011009 const gchar *checksums = g_variant_get_string (value, NULL);
9021010 g_auto(GStrv) split = g_strsplit (checksums, ",", -1);
903 for (i = 0; split[i] != NULL; i++)
1011 for (guint i = 0; split[i] != NULL; i++)
9041012 fwupd_device_add_checksum (device, split[i]);
9051013 return;
9061014 }
907 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_PLUGIN) == 0) {
908 fwupd_device_set_provider (device, g_variant_get_string (value, NULL));
909 return;
910 }
911 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_VERSION) == 0) {
1015 if (g_strcmp0 (key, FWUPD_RESULT_KEY_PLUGIN) == 0) {
1016 fwupd_device_set_plugin (device, g_variant_get_string (value, NULL));
1017 return;
1018 }
1019 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION) == 0) {
9121020 fwupd_device_set_version (device, g_variant_get_string (value, NULL));
9131021 return;
9141022 }
915 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST) == 0) {
1023 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION_LOWEST) == 0) {
9161024 fwupd_device_set_version_lowest (device, g_variant_get_string (value, NULL));
9171025 return;
9181026 }
919 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_VERSION_BOOTLOADER) == 0) {
1027 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION_BOOTLOADER) == 0) {
9201028 fwupd_device_set_version_bootloader (device, g_variant_get_string (value, NULL));
9211029 return;
9221030 }
923 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_FLASHES_LEFT) == 0) {
1031 if (g_strcmp0 (key, FWUPD_RESULT_KEY_FLASHES_LEFT) == 0) {
9241032 fwupd_device_set_flashes_left (device, g_variant_get_uint32 (value));
1033 return;
1034 }
1035 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_ERROR) == 0) {
1036 fwupd_device_set_update_error (device, g_variant_get_string (value, NULL));
1037 return;
1038 }
1039 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_STATE) == 0) {
1040 fwupd_device_set_update_state (device, g_variant_get_uint32 (value));
9251041 return;
9261042 }
9271043 }
9561072 static void
9571073 fwupd_pad_kv_dfl (GString *str, const gchar *key, guint64 device_flags)
9581074 {
959 guint i;
960 g_autoptr(GString) tmp = NULL;
961
962 tmp = g_string_new ("");
963 for (i = 0; i < 64; i++) {
1075 g_autoptr(GString) tmp = g_string_new ("");
1076 for (guint i = 0; i < 64; i++) {
9641077 if ((device_flags & ((guint64) 1 << i)) == 0)
9651078 continue;
9661079 g_string_append_printf (tmp, "%s|",
9841097 return;
9851098 tmp = g_strdup_printf("%" G_GUINT32_FORMAT, value);
9861099 fwupd_pad_kv_str (str, key, tmp);
1100 }
1101
1102 /**
1103 * fwupd_device_get_update_state:
1104 * @device: A #FwupdDevice
1105 *
1106 * Gets the update state.
1107 *
1108 * Returns: the update state, or %FWUPD_UPDATE_STATE_UNKNOWN if unset
1109 *
1110 * Since: 0.9.8
1111 **/
1112 FwupdUpdateState
1113 fwupd_device_get_update_state (FwupdDevice *device)
1114 {
1115 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1116 g_return_val_if_fail (FWUPD_IS_DEVICE (device), FWUPD_UPDATE_STATE_UNKNOWN);
1117 return priv->update_state;
1118 }
1119
1120 /**
1121 * fwupd_device_set_update_state:
1122 * @device: A #FwupdDevice
1123 * @update_state: the state, e.g. %FWUPD_UPDATE_STATE_PENDING
1124 *
1125 * Sets the update state.
1126 *
1127 * Since: 0.9.8
1128 **/
1129 void
1130 fwupd_device_set_update_state (FwupdDevice *device, FwupdUpdateState update_state)
1131 {
1132 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1133 g_return_if_fail (FWUPD_IS_DEVICE (device));
1134 priv->update_state = update_state;
1135 }
1136
1137 /**
1138 * fwupd_device_get_update_error:
1139 * @device: A #FwupdDevice
1140 *
1141 * Gets the update error.
1142 *
1143 * Returns: the update error, or %NULL if unset
1144 *
1145 * Since: 0.9.8
1146 **/
1147 const gchar *
1148 fwupd_device_get_update_error (FwupdDevice *device)
1149 {
1150 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1151 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
1152 return priv->update_error;
1153 }
1154
1155 /**
1156 * fwupd_device_set_update_error:
1157 * @device: A #FwupdDevice
1158 * @update_error: the update error string
1159 *
1160 * Sets the update error.
1161 *
1162 * Since: 0.9.8
1163 **/
1164 void
1165 fwupd_device_set_update_error (FwupdDevice *device, const gchar *update_error)
1166 {
1167 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1168 g_return_if_fail (FWUPD_IS_DEVICE (device));
1169 g_free (priv->update_error);
1170 priv->update_error = g_strdup (update_error);
1171 }
1172
1173 /**
1174 * fwupd_device_get_release_default:
1175 * @device: A #FwupdDevice
1176 *
1177 * Gets the default release for this device.
1178 *
1179 * Returns: (transfer none): the #FwupdRelease, or %NULL if not set
1180 *
1181 * Since: 0.9.8
1182 **/
1183 FwupdRelease *
1184 fwupd_device_get_release_default (FwupdDevice *device)
1185 {
1186 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1187 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
1188 if (priv->releases->len == 0)
1189 return NULL;
1190 return FWUPD_RELEASE (g_ptr_array_index (priv->releases, 0));
1191 }
1192
1193 /**
1194 * fwupd_device_get_releases:
1195 * @device: A #FwupdDevice
1196 *
1197 * Gets all the releases for this device.
1198 *
1199 * Returns: (transfer none) (element-type FwupdRelease): array of releases
1200 *
1201 * Since: 0.9.8
1202 **/
1203 GPtrArray *
1204 fwupd_device_get_releases (FwupdDevice *device)
1205 {
1206 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1207 g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL);
1208 return priv->releases;
1209 }
1210
1211 /**
1212 * fwupd_device_add_release:
1213 * @device: A #FwupdDevice
1214 * @release: a #FwupdRelease
1215 *
1216 * Adds a release for this device.
1217 *
1218 * Since: 0.9.8
1219 **/
1220 void
1221 fwupd_device_add_release (FwupdDevice *device, FwupdRelease *release)
1222 {
1223 FwupdDevicePrivate *priv = GET_PRIVATE (device);
1224 g_return_if_fail (FWUPD_IS_DEVICE (device));
1225 g_ptr_array_add (priv->releases, g_object_ref (release));
1226 }
1227
1228 static void
1229 fwupd_pad_kv_ups (GString *str, const gchar *key, FwupdUpdateState value)
1230 {
1231 if (value == FWUPD_UPDATE_STATE_UNKNOWN)
1232 return;
1233 fwupd_pad_kv_str (str, key, fwupd_update_state_to_string (value));
9871234 }
9881235
9891236 /**
10141261 const gchar *guid = g_ptr_array_index (priv->guids, i);
10151262 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_GUID, guid);
10161263 }
1017 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_DESCRIPTION, priv->description);
1018 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_PLUGIN, priv->provider);
1019 fwupd_pad_kv_dfl (str, FWUPD_RESULT_KEY_DEVICE_FLAGS, priv->flags);
1264 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SUMMARY, priv->summary);
1265 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
1266 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PLUGIN, priv->plugin);
1267 fwupd_pad_kv_dfl (str, FWUPD_RESULT_KEY_FLAGS, priv->flags);
10201268 for (guint i = 0; i < priv->checksums->len; i++) {
10211269 const gchar *checksum = g_ptr_array_index (priv->checksums, i);
10221270 g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum);
1023 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_CHECKSUM, checksum_display);
1024 }
1025 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VENDOR, priv->vendor);
1026 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VENDOR_ID, priv->vendor_id);
1027 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VERSION, priv->version);
1028 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST, priv->version_lowest);
1029 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_VERSION_BOOTLOADER, priv->version_bootloader);
1271 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_CHECKSUM, checksum_display);
1272 }
1273 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR, priv->vendor);
1274 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR_ID, priv->vendor_id);
1275 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION, priv->version);
1276 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION_LOWEST, priv->version_lowest);
1277 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION_BOOTLOADER, priv->version_bootloader);
10301278 if (priv->flashes_left < 2)
1031 fwupd_pad_kv_int (str, FWUPD_RESULT_KEY_DEVICE_FLASHES_LEFT, priv->flashes_left);
1032 fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_DEVICE_CREATED, priv->created);
1033 fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_DEVICE_MODIFIED, priv->modified);
1279 fwupd_pad_kv_int (str, FWUPD_RESULT_KEY_FLASHES_LEFT, priv->flashes_left);
1280 if (priv->icons->len > 0) {
1281 g_autoptr(GString) tmp = g_string_new (NULL);
1282 for (guint i = 0; i < priv->icons->len; i++) {
1283 const gchar *icon = g_ptr_array_index (priv->icons, i);
1284 g_string_append_printf (tmp, "%s,", icon);
1285 }
1286 if (tmp->len > 1)
1287 g_string_truncate (tmp, tmp->len - 1);
1288 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_ICON, tmp->str);
1289 }
1290 fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_CREATED, priv->created);
1291 fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_MODIFIED, priv->modified);
1292 fwupd_pad_kv_ups (str, FWUPD_RESULT_KEY_UPDATE_STATE, priv->update_state);
1293 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_ERROR, priv->update_error);
1294 for (guint i = 0; i < priv->releases->len; i++) {
1295 FwupdRelease *release = g_ptr_array_index (priv->releases, i);
1296 g_autofree gchar *tmp = fwupd_release_to_string (release);
1297 g_string_append_printf (str, " \n [%s]\n%s",
1298 FWUPD_RESULT_KEY_RELEASE, tmp);
1299 }
10341300
10351301 return g_string_free (str, FALSE);
10361302 }
10471313 {
10481314 FwupdDevicePrivate *priv = GET_PRIVATE (device);
10491315 priv->guids = g_ptr_array_new_with_free_func (g_free);
1316 priv->icons = g_ptr_array_new_with_free_func (g_free);
10501317 priv->checksums = g_ptr_array_new_with_free_func (g_free);
1318 priv->releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
10511319 }
10521320
10531321 static void
10591327 g_free (priv->description);
10601328 g_free (priv->id);
10611329 g_free (priv->name);
1330 g_free (priv->summary);
10621331 g_free (priv->vendor);
10631332 g_free (priv->vendor_id);
1064 g_free (priv->provider);
1333 g_free (priv->plugin);
1334 g_free (priv->update_error);
10651335 g_free (priv->version);
10661336 g_free (priv->version_lowest);
10671337 g_free (priv->version_bootloader);
10681338 g_ptr_array_unref (priv->guids);
1339 g_ptr_array_unref (priv->icons);
10691340 g_ptr_array_unref (priv->checksums);
1341 g_ptr_array_unref (priv->releases);
10701342
10711343 G_OBJECT_CLASS (fwupd_device_parent_class)->finalize (object);
10721344 }
10831355 }
10841356
10851357 /**
1086 * fwupd_device_new_from_data:
1358 * fwupd_device_from_variant:
10871359 * @data: a #GVariant
10881360 *
10891361 * Creates a new device using packed data.
10901362 *
1091 * Returns: a new #FwupdDevice, or %NULL if @data was invalid
1092 *
1093 * Since: 0.9.3
1363 * Returns: (transfer full): a new #FwupdDevice, or %NULL if @data was invalid
1364 *
1365 * Since: 1.0.0
10941366 **/
10951367 FwupdDevice *
1096 fwupd_device_new_from_data (GVariant *data)
1368 fwupd_device_from_variant (GVariant *data)
10971369 {
10981370 FwupdDevice *dev = NULL;
10991371 const gchar *type_string;
11091381 dev = fwupd_device_new ();
11101382 g_variant_get (data, "a{sv}", &iter);
11111383 fwupd_device_set_from_variant_iter (dev, iter);
1112 } else if (g_strcmp0 (type_string, "{sa{sv}}") == 0) {
1113 const gchar *id;
1114 dev = fwupd_device_new ();
1115 g_variant_get (data, "{&sa{sv}}", &id, &iter);
1116 fwupd_device_set_id (dev, id);
1117 fwupd_device_set_from_variant_iter (dev, iter);
11181384 } else {
11191385 g_warning ("type %s not known", type_string);
11201386 }
2424 #include <glib-object.h>
2525
2626 #include "fwupd-enums.h"
27 #include "fwupd-release.h"
2728
2829 G_BEGIN_DECLS
2930
8889 GPtrArray *fwupd_device_get_checksums (FwupdDevice *device);
8990 void fwupd_device_add_checksum (FwupdDevice *device,
9091 const gchar *checksum);
91 const gchar *fwupd_device_get_provider (FwupdDevice *device);
92 void fwupd_device_set_provider (FwupdDevice *device,
93 const gchar *provider);
92 const gchar *fwupd_device_get_plugin (FwupdDevice *device);
93 void fwupd_device_set_plugin (FwupdDevice *device,
94 const gchar *plugin);
9495 const gchar *fwupd_device_get_vendor (FwupdDevice *device);
9596 void fwupd_device_set_vendor (FwupdDevice *device,
9697 const gchar *vendor);
103104 const gchar *guid);
104105 GPtrArray *fwupd_device_get_guids (FwupdDevice *device);
105106 const gchar *fwupd_device_get_guid_default (FwupdDevice *device);
107 void fwupd_device_add_icon (FwupdDevice *device,
108 const gchar *icon);
109 GPtrArray *fwupd_device_get_icons (FwupdDevice *device);
110
111 FwupdUpdateState fwupd_device_get_update_state (FwupdDevice *device);
112 void fwupd_device_set_update_state (FwupdDevice *device,
113 FwupdUpdateState update_state);
114 const gchar *fwupd_device_get_update_error (FwupdDevice *device);
115 void fwupd_device_set_update_error (FwupdDevice *device,
116 const gchar *update_error);
117 void fwupd_device_add_release (FwupdDevice *device,
118 FwupdRelease *release);
119 GPtrArray *fwupd_device_get_releases (FwupdDevice *device);
120 FwupdRelease *fwupd_device_get_release_default (FwupdDevice *device);
106121
107122 G_END_DECLS
108123
2121 #ifndef __FWUPD_ENUMS_PRIVATE_H
2222 #define __FWUPD_ENUMS_PRIVATE_H
2323
24 /* FIXME: change the keys to the new names when we bump major version */
25 #define FWUPD_RESULT_KEY_DEVICE_CREATED "Created" /* t */
26 #define FWUPD_RESULT_KEY_DEVICE_DESCRIPTION "Description" /* s */
27 #define FWUPD_RESULT_KEY_DEVICE_FLAGS "Flags" /* t */
28 #define FWUPD_RESULT_KEY_DEVICE_CHECKSUM "FirmwareHash" /* s */
29 #define FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND "DeviceChecksumKind" /* u */
30 #define FWUPD_RESULT_KEY_DEVICE_MODIFIED "Modified" /* t */
31 #define FWUPD_RESULT_KEY_DEVICE_NAME "DisplayName" /* s */
32 #define FWUPD_RESULT_KEY_DEVICE_ID "DeviceID" /* s */
33 #define FWUPD_RESULT_KEY_DEVICE_PLUGIN "Plugin" /* s */
34 #define FWUPD_RESULT_KEY_DEVICE_VERSION "Version" /* s */
35 #define FWUPD_RESULT_KEY_DEVICE_VERSION_LOWEST "VersionLowest" /* s */
36 #define FWUPD_RESULT_KEY_DEVICE_VERSION_BOOTLOADER "VersionBootloader" /* s */
37 #define FWUPD_RESULT_KEY_DEVICE_FLASHES_LEFT "FlashesLeft" /* u */
38 #define FWUPD_RESULT_KEY_DEVICE_VENDOR "DeviceVendor" /* s */
39 #define FWUPD_RESULT_KEY_DEVICE_VENDOR_ID "DeviceVendorId" /* s */
40 #define FWUPD_RESULT_KEY_GUID "Guid" /* s */
41 #define FWUPD_RESULT_KEY_UNIQUE_ID "UniqueID" /* s */
42 #define FWUPD_RESULT_KEY_UPDATE_REMOTE_ID "RemoteID" /* s */
43 #define FWUPD_RESULT_KEY_UPDATE_DESCRIPTION "UpdateDescription" /* s */
44 #define FWUPD_RESULT_KEY_UPDATE_ERROR "PendingError" /* s */
45 #define FWUPD_RESULT_KEY_UPDATE_FILENAME "FilenameCab" /* s */
46 #define FWUPD_RESULT_KEY_UPDATE_CHECKSUM "UpdateHash" /* s */
47 #define FWUPD_RESULT_KEY_UPDATE_CHECKSUM_KIND "UpdateChecksumKind" /* u */
48 #define FWUPD_RESULT_KEY_UPDATE_ID "AppstreamId" /* s */
49 #define FWUPD_RESULT_KEY_UPDATE_LICENSE "License" /* s */
50 #define FWUPD_RESULT_KEY_UPDATE_NAME "Name" /* s */
51 #define FWUPD_RESULT_KEY_UPDATE_SIZE "Size" /* t */
52 #define FWUPD_RESULT_KEY_UPDATE_STATE "PendingState" /* s */
53 #define FWUPD_RESULT_KEY_UPDATE_SUMMARY "Summary" /* s */
54 #define FWUPD_RESULT_KEY_UPDATE_TRUST_FLAGS "Trusted" /* t */
55 #define FWUPD_RESULT_KEY_UPDATE_URI "UpdateUri" /* s */
56 #define FWUPD_RESULT_KEY_UPDATE_HOMEPAGE "UrlHomepage" /* s */
57 #define FWUPD_RESULT_KEY_UPDATE_VENDOR "Vendor" /* s */
58 #define FWUPD_RESULT_KEY_UPDATE_VERSION "UpdateVersion" /* s */
24 #define FWUPD_RESULT_KEY_APPSTREAM_ID "AppstreamId" /* s */
25 #define FWUPD_RESULT_KEY_CHECKSUM "Checksum" /* as */
26 #define FWUPD_RESULT_KEY_CREATED "Created" /* t */
27 #define FWUPD_RESULT_KEY_DESCRIPTION "Description" /* s */
28 #define FWUPD_RESULT_KEY_DEVICE_ID "DeviceId" /* s */
29 #define FWUPD_RESULT_KEY_FILENAME "Filename" /* s */
30 #define FWUPD_RESULT_KEY_FLAGS "Flags" /* t */
31 #define FWUPD_RESULT_KEY_FLASHES_LEFT "FlashesLeft" /* u */
32 #define FWUPD_RESULT_KEY_GUID "Guid" /* as */
33 #define FWUPD_RESULT_KEY_HOMEPAGE "Homepage" /* s */
34 #define FWUPD_RESULT_KEY_ICON "Icon" /* as */
35 #define FWUPD_RESULT_KEY_LICENSE "License" /* s */
36 #define FWUPD_RESULT_KEY_MODIFIED "Modified" /* t */
37 #define FWUPD_RESULT_KEY_NAME "Name" /* s */
38 #define FWUPD_RESULT_KEY_PLUGIN "Plugin" /* s */
39 #define FWUPD_RESULT_KEY_RELEASE "Release" /* a{sv} */
40 #define FWUPD_RESULT_KEY_REMOTE_ID "RemoteId" /* s */
41 #define FWUPD_RESULT_KEY_SIZE "Size" /* t */
42 #define FWUPD_RESULT_KEY_SUMMARY "Summary" /* s */
43 #define FWUPD_RESULT_KEY_TRUST_FLAGS "TrustFlags" /* t */
44 #define FWUPD_RESULT_KEY_UPDATE_ERROR "UpdateError" /* s */
45 #define FWUPD_RESULT_KEY_UPDATE_STATE "UpdateState" /* u */
46 #define FWUPD_RESULT_KEY_URI "Uri" /* s */
47 #define FWUPD_RESULT_KEY_VENDOR_ID "VendorId" /* s */
48 #define FWUPD_RESULT_KEY_VENDOR "Vendor" /* s */
49 #define FWUPD_RESULT_KEY_VENDOR "Vendor" /* s */
50 #define FWUPD_RESULT_KEY_VERSION_BOOTLOADER "VersionBootloader" /* s */
51 #define FWUPD_RESULT_KEY_VERSION_LOWEST "VersionLowest" /* s */
52 #define FWUPD_RESULT_KEY_VERSION "Version" /* s */
5953
6054 #endif /* __FWUPD_ENUMS_PRIVATE_H */
2121 #include "config.h"
2222
2323 #include "fwupd-enums.h"
24
25 /**
26 * SECTION:fwupd-enums
27 * @short_description: enumerated values shared by the daemon and library
28 *
29 * This file also provides helper functions to map enums to strings and back
30 * again.
31 *
32 * See also: #fwupd-error
33 */
2434
2535 /**
2636 * fwupd_status_to_string:
4757 return "device-restart";
4858 if (status == FWUPD_STATUS_DEVICE_WRITE)
4959 return "device-write";
60 if (status == FWUPD_STATUS_DEVICE_READ)
61 return "device-read";
62 if (status == FWUPD_STATUS_DEVICE_ERASE)
63 return "device-erase";
5064 if (status == FWUPD_STATUS_DEVICE_VERIFY)
5165 return "device-verify";
5266 if (status == FWUPD_STATUS_SCHEDULING)
5367 return "scheduling";
5468 if (status == FWUPD_STATUS_DOWNLOADING)
5569 return "downloading";
70 if (status == FWUPD_STATUS_WAITING_FOR_AUTH)
71 return "waiting-for-auth";
5672 return NULL;
5773 }
5874
5975 /**
6076 * fwupd_status_from_string:
61 * @status: A string, e.g. "decompressing"
77 * @status: A string, e.g. `decompressing`
6278 *
6379 * Converts a string to a #FwupdStatus.
6480 *
87103 return FWUPD_STATUS_SCHEDULING;
88104 if (g_strcmp0 (status, "downloading") == 0)
89105 return FWUPD_STATUS_DOWNLOADING;
106 if (g_strcmp0 (status, "device-read") == 0)
107 return FWUPD_STATUS_DEVICE_READ;
108 if (g_strcmp0 (status, "device-erase") == 0)
109 return FWUPD_STATUS_DEVICE_ERASE;
110 if (g_strcmp0 (status, "waiting-for-auth") == 0)
111 return FWUPD_STATUS_WAITING_FOR_AUTH;
90112 return FWUPD_STATUS_LAST;
91113 }
92114
130152
131153 /**
132154 * fwupd_device_flag_from_string:
133 * @device_flag: A string, e.g. "require-ac"
155 * @device_flag: A string, e.g. `require-ac`
134156 *
135157 * Converts a string to a #FwupdDeviceFlags.
136158 *
192214
193215 /**
194216 * fwupd_update_state_from_string:
195 * @update_state: A string, e.g. "pending"
217 * @update_state: A string, e.g. `pending`
196218 *
197219 * Converts a string to a #FwupdUpdateState.
198220 *
238260
239261 /**
240262 * fwupd_trust_flag_from_string:
241 * @trust_flag: A string, e.g. "payload"
263 * @trust_flag: A string, e.g. `payload`
242264 *
243265 * Converts a string to a #FwupdTrustFlags.
244266 *
260282
261283 /**
262284 * fwupd_keyring_kind_from_string:
263 * @keyring_kind: a string, e.g. "gpg"
285 * @keyring_kind: a string, e.g. `gpg`
264286 *
265287 * Converts an printable string to an enumerated type.
266288 *
286308 *
287309 * Converts an enumerated type to a printable string.
288310 *
289 * Returns: a string, e.g. "gpg"
311 * Returns: a string, e.g. `gpg`
290312 *
291313 * Since: 0.9.7
292314 **/
3434 * @FWUPD_STATUS_DEVICE_VERIFY: Verifying (reading) a device
3535 * @FWUPD_STATUS_SCHEDULING: Scheduling an offline update
3636 * @FWUPD_STATUS_DOWNLOADING: A file is downloading
37 * @FWUPD_STATUS_DEVICE_READ: Reading from a device
38 * @FWUPD_STATUS_DEVICE_ERASE: Erasing a device
39 * @FWUPD_STATUS_WAITING_FOR_AUTH: Waiting for authentication
3740 *
3841 * The flags to show daemon status.
3942 **/
4750 FWUPD_STATUS_DEVICE_VERIFY, /* Since: 0.1.1 */
4851 FWUPD_STATUS_SCHEDULING, /* Since: 0.1.1 */
4952 FWUPD_STATUS_DOWNLOADING, /* Since: 0.9.4 */
53 FWUPD_STATUS_DEVICE_READ, /* Since: 1.0.0 */
54 FWUPD_STATUS_DEVICE_ERASE, /* Since: 1.0.0 */
55 FWUPD_STATUS_WAITING_FOR_AUTH, /* Since: 1.0.0 */
5056 /*< private >*/
5157 FWUPD_STATUS_LAST
5258 } FwupdStatus;
8086 * @FWUPD_DEVICE_FLAG_REGISTERED: Has been registered with other plugins
8187 * @FWUPD_DEVICE_FLAG_NEEDS_REBOOT: Requires a reboot to apply firmware or to reload hardware
8288 *
83 * FIXME: rename FU_DEVICE_ -> FWUPD_DEVICE_ when we break API
84 *
8589 * The device flags.
8690 **/
8791 #define FWUPD_DEVICE_FLAG_NONE (0u) /* Since: 0.1.3 */
97101 #define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
98102 typedef guint64 FwupdDeviceFlags;
99103
100 /* deprecated names */
101 #define FU_DEVICE_FLAG_NONE FWUPD_DEVICE_FLAG_NONE
102 #define FU_DEVICE_FLAG_INTERNAL FWUPD_DEVICE_FLAG_INTERNAL
103 #define FU_DEVICE_FLAG_ALLOW_ONLINE FWUPD_DEVICE_FLAG_UPDATABLE
104 #define FU_DEVICE_FLAG_ALLOW_OFFLINE FWUPD_DEVICE_FLAG_ONLY_OFFLINE
105 #define FU_DEVICE_FLAG_REQUIRE_AC FWUPD_DEVICE_FLAG_REQUIRE_AC
106 #define FU_DEVICE_FLAG_LOCKED FWUPD_DEVICE_FLAG_LOCKED
107 #define FU_DEVICE_FLAG_SUPPORTED FWUPD_DEVICE_FLAG_SUPPORTED
108 #define FU_DEVICE_FLAG_NEEDS_BOOTLOADER FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER
109 #define FU_DEVICE_FLAG_UNKNOWN FWUPD_DEVICE_FLAG_UNKNOWN
110 #define FWUPD_DEVICE_FLAG_ALLOW_ONLINE FWUPD_DEVICE_FLAG_UPDATABLE
111 #define FWUPD_DEVICE_FLAG_ALLOW_OFFLINE FWUPD_DEVICE_FLAG_ONLY_OFFLINE
112
113104 /**
114105 * FwupdInstallFlags:
115106 * @FWUPD_INSTALL_FLAG_NONE: No flags set
116107 * @FWUPD_INSTALL_FLAG_OFFLINE: Schedule this for next boot
117108 * @FWUPD_INSTALL_FLAG_ALLOW_REINSTALL: Allow reinstalling the same version
118109 * @FWUPD_INSTALL_FLAG_ALLOW_OLDER: Allow downgrading firmware
110 * @FWUPD_INSTALL_FLAG_FORCE: Force the update even if not a good idea
119111 *
120112 * Flags to set when performing the firwmare update or install.
121113 **/
2525 #include "fwupd-common.h"
2626 #include "fwupd-enums.h"
2727 #include "fwupd-error.h"
28
29 /**
30 * SECTION:fwupd-error
31 * @short_description: an error domain shared by the daemon and library
32 *
33 * This file also provides helper functions to map errors to strings and back
34 * again.
35 *
36 * See also: #fwupd-enums
37 */
2838
2939 /**
3040 * fwupd_error_to_string:
6575 return FWUPD_DBUS_INTERFACE ".SignatureInvalid";
6676 if (error == FWUPD_ERROR_AC_POWER_REQUIRED)
6777 return FWUPD_DBUS_INTERFACE ".AcPowerRequired";
78 if (error == FWUPD_ERROR_PERMISSION_DENIED)
79 return FWUPD_DBUS_INTERFACE ".PermissionDenied";
6880 return NULL;
6981 }
7082
7183 /**
7284 * fwupd_error_from_string:
73 * @error: A string, e.g. "org.freedesktop.fwupd.VersionNewer"
85 * @error: A string, e.g. `org.freedesktop.fwupd.VersionNewer`
7486 *
7587 * Converts a string to a #FwupdError.
7688 *
107119 return FWUPD_ERROR_SIGNATURE_INVALID;
108120 if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".AcPowerRequired") == 0)
109121 return FWUPD_ERROR_AC_POWER_REQUIRED;
122 if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".PermissionDenied") == 0)
123 return FWUPD_ERROR_PERMISSION_DENIED;
110124 return FWUPD_ERROR_LAST;
111125 }
112126
4040 * @FWUPD_ERROR_NOT_SUPPORTED: Action was not possible
4141 * @FWUPD_ERROR_SIGNATURE_INVALID: Signature was invalid
4242 * @FWUPD_ERROR_AC_POWER_REQUIRED: AC power was required
43 * @FWUPD_ERROR_PERMISSION_DENIED: Permission was denied
4344 *
4445 * The error code.
4546 **/
5758 FWUPD_ERROR_NOT_SUPPORTED, /* Since: 0.1.1 */
5859 FWUPD_ERROR_SIGNATURE_INVALID, /* Since: 0.1.2 */
5960 FWUPD_ERROR_AC_POWER_REQUIRED, /* Since: 0.8.0 */
61 FWUPD_ERROR_PERMISSION_DENIED, /* Since: 0.9.8 */
6062 /*< private >*/
6163 FWUPD_ERROR_LAST
6264 } FwupdError;
2727
2828 G_BEGIN_DECLS
2929
30 FwupdRelease *fwupd_release_new_from_data (GVariant *data);
31 GVariant *fwupd_release_to_data (FwupdRelease *release,
32 const gchar *type_string);
33 void fwupd_release_to_variant_builder (FwupdRelease *release,
34 GVariantBuilder *builder);
35 void fwupd_release_from_key_value (FwupdRelease *release,
36 const gchar *key,
37 GVariant *value);
30 FwupdRelease *fwupd_release_from_variant (GVariant *data);
31 GVariant *fwupd_release_to_variant (FwupdRelease *release);
3832
3933 G_END_DECLS
4034
2828 #include "fwupd-enums-private.h"
2929 #include "fwupd-error.h"
3030 #include "fwupd-release-private.h"
31
32 /**
33 * SECTION:fwupd-release
34 * @short_description: a firmware release
35 *
36 * An object that represents a firmware release with a specific version.
37 * Devices can have more than one release, and the releases are typically
38 * ordered by their version.
39 *
40 * See also: #FwupdDevice
41 */
3142
3243 static void fwupd_release_finalize (GObject *object);
3344
4556 gchar *version;
4657 gchar *remote_id;
4758 guint64 size;
59 FwupdTrustFlags trust_flags;
4860 } FwupdReleasePrivate;
4961
5062 G_DEFINE_TYPE_WITH_PRIVATE (FwupdRelease, fwupd_release, G_TYPE_OBJECT)
7183 /**
7284 * fwupd_release_set_remote_id:
7385 * @release: A #FwupdRelease
74 * @remote_id: the release ID, e.g. "USB:foo"
86 * @remote_id: the release ID, e.g. `USB:foo`
7587 *
7688 * Sets the remote ID that can be used for downloading.
7789 *
107119 /**
108120 * fwupd_release_set_version:
109121 * @release: A #FwupdRelease
110 * @version: the update version, e.g. "1.2.4"
122 * @version: the update version, e.g. `1.2.4`
111123 *
112124 * Sets the update version.
113125 *
328340 /**
329341 * fwupd_release_set_appstream_id:
330342 * @release: A #FwupdRelease
331 * @appstream_id: the AppStream component ID, e.g. "org.hughski.ColorHug2.firmware"
343 * @appstream_id: the AppStream component ID, e.g. `org.hughski.ColorHug2.firmware`
332344 *
333345 * Sets the AppStream ID.
334346 *
435447 /**
436448 * fwupd_release_set_vendor:
437449 * @release: A #FwupdRelease
438 * @vendor: the vendor name, e.g. "Hughski Limited"
450 * @vendor: the vendor name, e.g. `Hughski Limited`
439451 *
440452 * Sets the update vendor.
441453 *
522534 priv->name = g_strdup (name);
523535 }
524536
525 void
526 fwupd_release_to_variant_builder (FwupdRelease *release, GVariantBuilder *builder)
527 {
528 FwupdReleasePrivate *priv = GET_PRIVATE (release);
537 /**
538 * fwupd_release_get_trust_flags:
539 * @release: A #FwupdRelease
540 *
541 * Gets the trust level of the release.
542 *
543 * Returns: the trust bitfield, e.g. #FWUPD_TRUST_FLAG_PAYLOAD
544 *
545 * Since: 0.9.8
546 **/
547 FwupdTrustFlags
548 fwupd_release_get_trust_flags (FwupdRelease *release)
549 {
550 FwupdReleasePrivate *priv = GET_PRIVATE (release);
551 g_return_val_if_fail (FWUPD_IS_RELEASE (release), 0);
552 return priv->trust_flags;
553 }
554
555 /**
556 * fwupd_release_set_trust_flags:
557 * @release: A #FwupdRelease
558 * @trust_flags: the bitfield, e.g. #FWUPD_TRUST_FLAG_PAYLOAD
559 *
560 * Sets the trust level of the release.
561 *
562 * Since: 0.9.8
563 **/
564 void
565 fwupd_release_set_trust_flags (FwupdRelease *release, FwupdTrustFlags trust_flags)
566 {
567 FwupdReleasePrivate *priv = GET_PRIVATE (release);
568 g_return_if_fail (FWUPD_IS_RELEASE (release));
569 priv->trust_flags = trust_flags;
570 }
571
572 /**
573 * fwupd_release_to_variant:
574 * @release: A #FwupdRelease
575 *
576 * Creates a GVariant from the release data.
577 *
578 * Returns: the GVariant, or %NULL for error
579 *
580 * Since: 1.0.0
581 **/
582 GVariant *
583 fwupd_release_to_variant (FwupdRelease *release)
584 {
585 FwupdReleasePrivate *priv = GET_PRIVATE (release);
586 GVariantBuilder builder;
587
588 g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
589
590 /* create an array with all the metadata in */
591 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
529592 if (priv->remote_id != NULL) {
530 g_variant_builder_add (builder, "{sv}",
531 FWUPD_RESULT_KEY_UPDATE_REMOTE_ID,
593 g_variant_builder_add (&builder, "{sv}",
594 FWUPD_RESULT_KEY_REMOTE_ID,
532595 g_variant_new_string (priv->remote_id));
533596 }
534597 if (priv->appstream_id != NULL) {
535 g_variant_builder_add (builder, "{sv}",
536 FWUPD_RESULT_KEY_UPDATE_ID,
598 g_variant_builder_add (&builder, "{sv}",
599 FWUPD_RESULT_KEY_APPSTREAM_ID,
537600 g_variant_new_string (priv->appstream_id));
538601 }
539602 if (priv->filename != NULL) {
540 g_variant_builder_add (builder, "{sv}",
541 FWUPD_RESULT_KEY_UPDATE_FILENAME,
603 g_variant_builder_add (&builder, "{sv}",
604 FWUPD_RESULT_KEY_FILENAME,
542605 g_variant_new_string (priv->filename));
543606 }
544607 if (priv->license != NULL) {
545 g_variant_builder_add (builder, "{sv}",
546 FWUPD_RESULT_KEY_UPDATE_LICENSE,
608 g_variant_builder_add (&builder, "{sv}",
609 FWUPD_RESULT_KEY_LICENSE,
547610 g_variant_new_string (priv->license));
548611 }
549612 if (priv->name != NULL) {
550 g_variant_builder_add (builder, "{sv}",
551 FWUPD_RESULT_KEY_UPDATE_NAME,
613 g_variant_builder_add (&builder, "{sv}",
614 FWUPD_RESULT_KEY_NAME,
552615 g_variant_new_string (priv->name));
553616 }
554617 if (priv->size != 0) {
555 g_variant_builder_add (builder, "{sv}",
556 FWUPD_RESULT_KEY_UPDATE_SIZE,
618 g_variant_builder_add (&builder, "{sv}",
619 FWUPD_RESULT_KEY_SIZE,
557620 g_variant_new_uint64 (priv->size));
558621 }
559622 if (priv->summary != NULL) {
560 g_variant_builder_add (builder, "{sv}",
561 FWUPD_RESULT_KEY_UPDATE_SUMMARY,
623 g_variant_builder_add (&builder, "{sv}",
624 FWUPD_RESULT_KEY_SUMMARY,
562625 g_variant_new_string (priv->summary));
563626 }
564627 if (priv->description != NULL) {
565 g_variant_builder_add (builder, "{sv}",
566 FWUPD_RESULT_KEY_UPDATE_DESCRIPTION,
628 g_variant_builder_add (&builder, "{sv}",
629 FWUPD_RESULT_KEY_DESCRIPTION,
567630 g_variant_new_string (priv->description));
568631 }
569632 if (priv->checksums->len > 0) {
570 guint i;
571633 g_autoptr(GString) str = g_string_new ("");
572 for (i = 0; i < priv->checksums->len; i++) {
634 for (guint i = 0; i < priv->checksums->len; i++) {
573635 const gchar *checksum = g_ptr_array_index (priv->checksums, i);
574636 g_string_append_printf (str, "%s,", checksum);
575637 }
576638 if (str->len > 0)
577639 g_string_truncate (str, str->len - 1);
578 g_variant_builder_add (builder, "{sv}",
579 FWUPD_RESULT_KEY_UPDATE_CHECKSUM,
640 g_variant_builder_add (&builder, "{sv}",
641 FWUPD_RESULT_KEY_CHECKSUM,
580642 g_variant_new_string (str->str));
581643 }
582644 if (priv->uri != NULL) {
583 g_variant_builder_add (builder, "{sv}",
584 FWUPD_RESULT_KEY_UPDATE_URI,
645 g_variant_builder_add (&builder, "{sv}",
646 FWUPD_RESULT_KEY_URI,
585647 g_variant_new_string (priv->uri));
586648 }
587649 if (priv->homepage != NULL) {
588 g_variant_builder_add (builder, "{sv}",
589 FWUPD_RESULT_KEY_UPDATE_HOMEPAGE,
650 g_variant_builder_add (&builder, "{sv}",
651 FWUPD_RESULT_KEY_HOMEPAGE,
590652 g_variant_new_string (priv->homepage));
591653 }
592654 if (priv->version != NULL) {
593 g_variant_builder_add (builder, "{sv}",
594 FWUPD_RESULT_KEY_UPDATE_VERSION,
655 g_variant_builder_add (&builder, "{sv}",
656 FWUPD_RESULT_KEY_VERSION,
595657 g_variant_new_string (priv->version));
596658 }
597659 if (priv->vendor != NULL) {
598 g_variant_builder_add (builder, "{sv}",
599 FWUPD_RESULT_KEY_UPDATE_VENDOR,
660 g_variant_builder_add (&builder, "{sv}",
661 FWUPD_RESULT_KEY_VENDOR,
600662 g_variant_new_string (priv->vendor));
601663 }
602 }
603
604 /**
605 * fwupd_release_to_data:
606 * @release: A #FwupdRelease
607 * @type_string: The Gvariant type string, e.g. "a{sv}" or "(a{sv})"
608 *
609 * Creates a GVariant from the release data.
610 *
611 * Returns: the GVariant, or %NULL for error
612 *
613 * Since: 0.9.3
614 **/
615 GVariant *
616 fwupd_release_to_data (FwupdRelease *release, const gchar *type_string)
617 {
618 GVariantBuilder builder;
619
620 g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
621 g_return_val_if_fail (type_string != NULL, NULL);
622
623 /* create an array with all the metadata in */
624 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
625 fwupd_release_to_variant_builder (release, &builder);
626
627 /* supported types */
628 if (g_strcmp0 (type_string, "a{sv}") == 0)
629 return g_variant_new ("a{sv}", &builder);
630 if (g_strcmp0 (type_string, "(a{sv})") == 0)
631 return g_variant_new ("(a{sv})", &builder);
632 return NULL;
633 }
634
635 void
664 if (priv->trust_flags != 0) {
665 g_variant_builder_add (&builder, "{sv}",
666 FWUPD_RESULT_KEY_TRUST_FLAGS,
667 g_variant_new_uint64 (priv->trust_flags));
668 }
669 return g_variant_new ("a{sv}", &builder);
670 }
671
672 static void
636673 fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant *value)
637674 {
638 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_REMOTE_ID) == 0) {
675 if (g_strcmp0 (key, FWUPD_RESULT_KEY_REMOTE_ID) == 0) {
639676 fwupd_release_set_remote_id (release, g_variant_get_string (value, NULL));
640677 return;
641678 }
642 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_ID) == 0) {
679 if (g_strcmp0 (key, FWUPD_RESULT_KEY_APPSTREAM_ID) == 0) {
643680 fwupd_release_set_appstream_id (release, g_variant_get_string (value, NULL));
644681 return;
645682 }
646 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_FILENAME) == 0) {
683 if (g_strcmp0 (key, FWUPD_RESULT_KEY_FILENAME) == 0) {
647684 fwupd_release_set_filename (release, g_variant_get_string (value, NULL));
648685 return;
649686 }
650 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_LICENSE) == 0) {
687 if (g_strcmp0 (key, FWUPD_RESULT_KEY_LICENSE) == 0) {
651688 fwupd_release_set_license (release, g_variant_get_string (value, NULL));
652689 return;
653690 }
654 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_NAME) == 0) {
691 if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME) == 0) {
655692 fwupd_release_set_name (release, g_variant_get_string (value, NULL));
656693 return;
657694 }
658 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_SIZE) == 0) {
695 if (g_strcmp0 (key, FWUPD_RESULT_KEY_SIZE) == 0) {
659696 fwupd_release_set_size (release, g_variant_get_uint64 (value));
660697 return;
661698 }
662 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_SUMMARY) == 0) {
699 if (g_strcmp0 (key, FWUPD_RESULT_KEY_SUMMARY) == 0) {
663700 fwupd_release_set_summary (release, g_variant_get_string (value, NULL));
664701 return;
665702 }
666 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_DESCRIPTION) == 0) {
703 if (g_strcmp0 (key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) {
667704 fwupd_release_set_description (release, g_variant_get_string (value, NULL));
668705 return;
669706 }
670 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_CHECKSUM) == 0) {
707 if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) {
671708 const gchar *checksums = g_variant_get_string (value, NULL);
672709 g_auto(GStrv) split = g_strsplit (checksums, ",", -1);
673710 for (guint i = 0; split[i] != NULL; i++)
674711 fwupd_release_add_checksum (release, split[i]);
675712 return;
676713 }
677 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_URI) == 0) {
714 if (g_strcmp0 (key, FWUPD_RESULT_KEY_URI) == 0) {
678715 fwupd_release_set_uri (release, g_variant_get_string (value, NULL));
679716 return;
680717 }
681 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_HOMEPAGE) == 0) {
718 if (g_strcmp0 (key, FWUPD_RESULT_KEY_HOMEPAGE) == 0) {
682719 fwupd_release_set_homepage (release, g_variant_get_string (value, NULL));
683720 return;
684721 }
685 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_VERSION) == 0) {
722 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION) == 0) {
686723 fwupd_release_set_version (release, g_variant_get_string (value, NULL));
687724 return;
688725 }
689 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_VENDOR) == 0) {
726 if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR) == 0) {
690727 fwupd_release_set_vendor (release, g_variant_get_string (value, NULL));
728 return;
729 }
730 if (g_strcmp0 (key, FWUPD_RESULT_KEY_TRUST_FLAGS) == 0) {
731 fwupd_release_set_trust_flags (release, g_variant_get_uint64 (value));
691732 return;
692733 }
693734 }
716757 fwupd_pad_kv_str (str, key, tmp);
717758 }
718759
760 static void
761 fwupd_pad_kv_tfl (GString *str, const gchar *key, FwupdTrustFlags trust_flags)
762 {
763 g_autoptr(GString) tmp = g_string_new ("");
764 for (guint i = 1; i < FWUPD_TRUST_FLAG_LAST; i *= 2) {
765 if ((trust_flags & i) == 0)
766 continue;
767 g_string_append_printf (tmp, "%s|",
768 fwupd_trust_flag_to_string (i));
769 }
770 if (tmp->len == 0) {
771 g_string_append (tmp, fwupd_trust_flag_to_string (0));
772 } else {
773 g_string_truncate (tmp, tmp->len - 1);
774 }
775 fwupd_pad_kv_str (str, key, tmp->str);
776 }
777
719778 /**
720779 * fwupd_release_to_string:
721780 * @release: A #FwupdRelease
735794 g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL);
736795
737796 str = g_string_new ("");
738 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_ID, priv->appstream_id);
739 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_REMOTE_ID, priv->remote_id);
740 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_SUMMARY, priv->summary);
741 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_DESCRIPTION, priv->description);
742 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_VERSION, priv->version);
743 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_FILENAME, priv->filename);
797 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id);
798 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_REMOTE_ID, priv->remote_id);
799 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SUMMARY, priv->summary);
800 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description);
801 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION, priv->version);
802 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_FILENAME, priv->filename);
744803 for (guint i = 0; i < priv->checksums->len; i++) {
745804 const gchar *checksum = g_ptr_array_index (priv->checksums, i);
746805 g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum);
747 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_CHECKSUM, checksum_display);
748 }
749 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_LICENSE, priv->license);
750 fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_UPDATE_SIZE, priv->size);
751 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_URI, priv->uri);
752 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_HOMEPAGE, priv->homepage);
753 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_VENDOR, priv->vendor);
806 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_CHECKSUM, checksum_display);
807 }
808 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_LICENSE, priv->license);
809 fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_SIZE, priv->size);
810 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_URI, priv->uri);
811 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_HOMEPAGE, priv->homepage);
812 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR, priv->vendor);
813 fwupd_pad_kv_tfl (str, FWUPD_RESULT_KEY_TRUST_FLAGS, priv->trust_flags);
754814
755815 return g_string_free (str, FALSE);
756816 }
803863 }
804864
805865 /**
806 * fwupd_release_new_from_data:
866 * fwupd_release_from_variant:
807867 * @data: a #GVariant
808868 *
809869 * Creates a new release using packed data.
810870 *
811 * Returns: a new #FwupdRelease, or %NULL if @data was invalid
812 *
813 * Since: 0.9.3
871 * Returns: (transfer full): a new #FwupdRelease, or %NULL if @data was invalid
872 *
873 * Since: 1.0.0
814874 **/
815875 FwupdRelease *
816 fwupd_release_new_from_data (GVariant *data)
876 fwupd_release_from_variant (GVariant *data)
817877 {
818878 FwupdRelease *rel = NULL;
819879 const gchar *type_string;
8686 const gchar *fwupd_release_get_license (FwupdRelease *release);
8787 void fwupd_release_set_license (FwupdRelease *release,
8888 const gchar *license);
89 FwupdTrustFlags fwupd_release_get_trust_flags (FwupdRelease *release);
90 void fwupd_release_set_trust_flags (FwupdRelease *release,
91 FwupdTrustFlags trust_flags);
8992
9093 G_END_DECLS
9194
2525
2626 G_BEGIN_DECLS
2727
28 FwupdRemote *fwupd_remote_new_from_data (GVariant *data);
29 GVariant *fwupd_remote_to_data (FwupdRemote *self,
30 const gchar *type_string);
28 FwupdRemote *fwupd_remote_from_variant (GVariant *data);
29 GVariant *fwupd_remote_to_variant (FwupdRemote *self);
3130 gboolean fwupd_remote_load_from_filename (FwupdRemote *self,
3231 const gchar *filename,
3332 GCancellable *cancellable,
2020
2121 #include "config.h"
2222
23 #include <libsoup/soup.h>
24
25 #include "fwupd-deprecated.h"
26 #include "fwupd-enums-private.h"
2327 #include "fwupd-error.h"
2428 #include "fwupd-remote-private.h"
2529
30 /**
31 * SECTION:fwupd-remote
32 * @short_description: a source of firmware
33 *
34 * An object that represents a source of metadata that provides firmware.
35 *
36 * See also: #FwupdClient
37 */
38
2639 static void fwupd_remote_finalize (GObject *obj);
2740
28 struct _FwupdRemote
29 {
41 typedef struct {
3042 GObject parent_instance;
3143 FwupdRemoteKind kind;
3244 FwupdKeyringKind keyring_kind;
3648 gchar *metadata_uri_sig;
3749 gchar *username;
3850 gchar *password;
39 gchar *filename;
40 gchar *filename_asc;
51 gchar *title;
52 gchar *checksum;
4153 gchar *filename_cache;
4254 gchar *filename_cache_sig;
55 gchar *filename_source;
4356 gboolean enabled;
44 SoupURI *uri;
45 SoupURI *uri_asc;
4657 gint priority;
4758 guint64 mtime;
4859 gchar **order_after;
4960 gchar **order_before;
50 };
61 } FwupdRemotePrivate;
5162
5263 enum {
5364 PROP_0,
5667 PROP_LAST
5768 };
5869
59 G_DEFINE_TYPE (FwupdRemote, fwupd_remote, G_TYPE_OBJECT)
70 G_DEFINE_TYPE_WITH_PRIVATE (FwupdRemote, fwupd_remote, G_TYPE_OBJECT)
71 #define GET_PRIVATE(o) (fwupd_remote_get_instance_private (o))
6072
6173 static void
6274 fwupd_remote_set_username (FwupdRemote *self, const gchar *username)
6375 {
76 FwupdRemotePrivate *priv = GET_PRIVATE (self);
6477 if (username != NULL && username[0] == '\0')
6578 username = NULL;
66 self->username = g_strdup (username);
67 if (self->uri != NULL)
68 soup_uri_set_user (self->uri, username);
69 if (self->uri_asc != NULL)
70 soup_uri_set_user (self->uri_asc, username);
79 priv->username = g_strdup (username);
80 }
81
82 static void
83 fwupd_remote_set_title (FwupdRemote *self, const gchar *title)
84 {
85 FwupdRemotePrivate *priv = GET_PRIVATE (self);
86 g_free (priv->title);
87 priv->title = g_strdup (title);
88 }
89
90 static void
91 fwupd_remote_set_checksum (FwupdRemote *self, const gchar *checksum)
92 {
93 FwupdRemotePrivate *priv = GET_PRIVATE (self);
94 g_free (priv->checksum);
95 priv->checksum = g_strdup (checksum);
7196 }
7297
7398 static void
7499 fwupd_remote_set_password (FwupdRemote *self, const gchar *password)
75100 {
101 FwupdRemotePrivate *priv = GET_PRIVATE (self);
76102 if (password != NULL && password[0] == '\0')
77103 password = NULL;
78 self->password = g_strdup (password);
79 if (self->uri != NULL)
80 soup_uri_set_password (self->uri, password);
81 if (self->uri_asc != NULL)
82 soup_uri_set_password (self->uri_asc, password);
104 priv->password = g_strdup (password);
83105 }
84106
85107 static void
86108 fwupd_remote_set_kind (FwupdRemote *self, FwupdRemoteKind kind)
87109 {
88 self->kind = kind;
110 FwupdRemotePrivate *priv = GET_PRIVATE (self);
111 priv->kind = kind;
89112 }
90113
91114 static void
92115 fwupd_remote_set_keyring_kind (FwupdRemote *self, FwupdKeyringKind keyring_kind)
93116 {
94 self->keyring_kind = keyring_kind;
117 FwupdRemotePrivate *priv = GET_PRIVATE (self);
118 priv->keyring_kind = keyring_kind;
95119 }
96120
97121 /* note, this has to be set before url */
98122 static void
99123 fwupd_remote_set_id (FwupdRemote *self, const gchar *id)
100124 {
101 g_free (self->id);
102 self->id = g_strdup (id);
103 g_strdelimit (self->id, ".", '\0');
125 FwupdRemotePrivate *priv = GET_PRIVATE (self);
126 g_free (priv->id);
127 priv->id = g_strdup (id);
128 g_strdelimit (priv->id, ".", '\0');
129 }
130
131 static void
132 fwupd_remote_set_filename_source (FwupdRemote *self, const gchar *filename_source)
133 {
134 FwupdRemotePrivate *priv = GET_PRIVATE (self);
135 g_free (priv->filename_source);
136 priv->filename_source = g_strdup (filename_source);
104137 }
105138
106139 static const gchar *
113146 return NULL;
114147 }
115148
116 /* note, this has to be set before username and password */
117 static void
118 fwupd_remote_set_metadata_uri (FwupdRemote *self, const gchar *metadata_uri)
119 {
120 const gchar *suffix;
121 g_autofree gchar *basename = NULL;
122 g_autofree gchar *basename_asc = NULL;
123
124 /* save this so we can export the object as a GVariant */
125 self->metadata_uri = g_strdup (metadata_uri);
126
127 /* build the URI */
128 self->uri = soup_uri_new (metadata_uri);
129 if (self->uri == NULL)
130 return;
131
132 /* generate some plausible local filenames */
133 basename = g_path_get_basename (soup_uri_get_path (self->uri));
134 self->filename = g_strdup_printf ("%s-%s", self->id, basename);
135
136 /* generate the signature URI too */
137 suffix = fwupd_remote_get_suffix_for_keyring_kind (self->keyring_kind);
138 if (suffix != NULL) {
139 self->metadata_uri_sig = g_strconcat (metadata_uri, suffix, NULL);
140 self->uri_asc = fwupd_remote_build_uri (self, self->metadata_uri_sig, NULL);
141 basename_asc = g_path_get_basename (soup_uri_get_path (self->uri_asc));
142 self->filename_asc = g_strdup_printf ("%s-%s", self->id, basename_asc);
143 }
144 }
145
146 /* note, this has to be set after MetadataURI */
147 static void
148 fwupd_remote_set_firmware_base_uri (FwupdRemote *self, const gchar *firmware_base_uri)
149 {
150 self->firmware_base_uri = g_strdup (firmware_base_uri);
151 }
152
153 /**
154 * fwupd_remote_kind_from_string:
155 * @kind: a string, e.g. "download"
156 *
157 * Converts an printable string to an enumerated type.
158 *
159 * Returns: a #FwupdRemoteKind, e.g. %FWUPD_REMOTE_KIND_DOWNLOAD
160 *
161 * Since: 0.9.6
162 **/
163 FwupdRemoteKind
164 fwupd_remote_kind_from_string (const gchar *kind)
165 {
166 if (g_strcmp0 (kind, "download") == 0)
167 return FWUPD_REMOTE_KIND_DOWNLOAD;
168 if (g_strcmp0 (kind, "local") == 0)
169 return FWUPD_REMOTE_KIND_LOCAL;
170 return FWUPD_REMOTE_KIND_UNKNOWN;
171 }
172
173 /**
174 * fwupd_remote_kind_to_string:
175 * @kind: a #FwupdRemoteKind, e.g. %FWUPD_REMOTE_KIND_DOWNLOAD
176 *
177 * Converts an enumerated type to a printable string.
178 *
179 * Returns: a string, e.g. "download"
180 *
181 * Since: 0.9.6
182 **/
183 const gchar *
184 fwupd_remote_kind_to_string (FwupdRemoteKind kind)
185 {
186 if (kind == FWUPD_REMOTE_KIND_DOWNLOAD)
187 return "download";
188 if (kind == FWUPD_REMOTE_KIND_LOCAL)
189 return "local";
190 return NULL;
191 }
192
193 static void
194 fwupd_remote_set_filename_cache (FwupdRemote *self, const gchar *filename)
195 {
196 const gchar *suffix;
197
198 g_return_if_fail (FWUPD_IS_REMOTE (self));
199
200 g_free (self->filename_cache);
201 self->filename_cache = g_strdup (filename);
202
203 /* create for all remote types */
204 suffix = fwupd_remote_get_suffix_for_keyring_kind (self->keyring_kind);
205 if (suffix != NULL) {
206 g_free (self->filename_cache_sig);
207 self->filename_cache_sig = g_strconcat (filename, suffix, NULL);
208 }
209 }
210
211 /**
212 * fwupd_remote_load_from_filename:
213 * @self: A #FwupdRemote
214 * @filename: A filename
215 * @cancellable: the #GCancellable, or %NULL
216 * @error: the #GError, or %NULL
217 *
218 * Sets up the remote ready for use. Most other methods call this
219 * for you, and do you only need to call this if you are just watching
220 * the self.
221 *
222 * Returns: %TRUE for success
223 *
224 * Since: 0.9.3
225 **/
226 gboolean
227 fwupd_remote_load_from_filename (FwupdRemote *self,
228 const gchar *filename,
229 GCancellable *cancellable,
230 GError **error)
231 {
232 const gchar *group = "fwupd Remote";
233 g_autofree gchar *firmware_base_uri = NULL;
234 g_autofree gchar *id = NULL;
235 g_autofree gchar *keyring_kind = NULL;
236 g_autofree gchar *metadata_uri = NULL;
237 g_autofree gchar *order_after = NULL;
238 g_autofree gchar *order_before = NULL;
239 g_autoptr(GKeyFile) kf = NULL;
240
241 g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE);
242 g_return_val_if_fail (filename != NULL, FALSE);
243 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
244 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
245
246 /* set ID */
247 id = g_path_get_basename (filename);
248 fwupd_remote_set_id (self, id);
249
250 /* load file */
251 kf = g_key_file_new ();
252 if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_NONE, error))
253 return FALSE;
254
255 /* get verification type, falling back to GPG */
256 keyring_kind = g_key_file_get_string (kf, group, "Keyring", NULL);
257 if (keyring_kind == NULL) {
258 self->keyring_kind = FWUPD_KEYRING_KIND_GPG;
259 } else {
260 self->keyring_kind = fwupd_keyring_kind_from_string (keyring_kind);
261 if (self->keyring_kind == FWUPD_KEYRING_KIND_UNKNOWN) {
262 g_set_error (error,
263 FWUPD_ERROR,
264 FWUPD_ERROR_INVALID_FILE,
265 "Failed to parse type '%s'",
266 keyring_kind);
267 return FALSE;
268 }
269 }
270
271 /* all remotes need a URI, even if it's file:// to the cache */
272 metadata_uri = g_key_file_get_string (kf, group, "MetadataURI", error);
273 if (metadata_uri == NULL)
274 return FALSE;
275 if (g_str_has_prefix (metadata_uri, "file://")) {
276 self->kind = FWUPD_REMOTE_KIND_LOCAL;
277 } else if (g_str_has_prefix (metadata_uri, "http://") ||
278 g_str_has_prefix (metadata_uri, "https://")) {
279 self->kind = FWUPD_REMOTE_KIND_DOWNLOAD;
280 } else {
281 g_set_error (error,
282 FWUPD_ERROR,
283 FWUPD_ERROR_INVALID_FILE,
284 "Failed to parse MetadataURI type '%s'",
285 metadata_uri);
286 return FALSE;
287 }
288
289 /* extract data */
290 self->enabled = g_key_file_get_boolean (kf, group, "Enabled", NULL);
291
292 /* DOWNLOAD-type remotes */
293 if (self->kind == FWUPD_REMOTE_KIND_DOWNLOAD) {
294 g_autofree gchar *filename_cache = NULL;
295 g_autofree gchar *username = NULL;
296 g_autofree gchar *password = NULL;
297
298 /* the client has to download this and the signature */
299 fwupd_remote_set_metadata_uri (self, metadata_uri);
300
301 /* check the URI was valid */
302 if (self->uri == NULL) {
303 g_set_error (error,
304 FWUPD_ERROR,
305 FWUPD_ERROR_INVALID_FILE,
306 "Failed to parse URI '%s' in %s",
307 metadata_uri, filename);
308 return FALSE;
309 }
310
311 /* username and password are optional */
312 username = g_key_file_get_string (kf, group, "Username", NULL);
313 if (username != NULL)
314 fwupd_remote_set_username (self, username);
315 password = g_key_file_get_string (kf, group, "Password", NULL);
316 if (password != NULL)
317 fwupd_remote_set_password (self, password);
318
319 /* set cache to /var/lib... */
320 filename_cache = g_build_filename (LOCALSTATEDIR,
321 "lib",
322 "fwupd",
323 "remotes.d",
324 self->id,
325 "metadata.xml.gz",
326 NULL);
327 fwupd_remote_set_filename_cache (self, filename_cache);
328 }
329
330 /* all LOCAL remotes have to include a valid MetadataURI */
331 if (self->kind == FWUPD_REMOTE_KIND_LOCAL) {
332 const gchar *filename_cache = metadata_uri;
333 if (g_str_has_prefix (filename_cache, "file://"))
334 filename_cache += 7;
335 fwupd_remote_set_filename_cache (self, filename_cache);
336 }
337
338 /* the base URI is optional */
339 firmware_base_uri = g_key_file_get_string (kf, group, "FirmwareBaseURI", NULL);
340 if (firmware_base_uri != NULL)
341 fwupd_remote_set_firmware_base_uri (self, firmware_base_uri);
342
343 /* dep logic */
344 order_before = g_key_file_get_string (kf, group, "OrderBefore", NULL);
345 if (order_before != NULL)
346 self->order_before = g_strsplit_set (order_before, ",:;", -1);
347 order_after = g_key_file_get_string (kf, group, "OrderAfter", NULL);
348 if (order_after != NULL)
349 self->order_after = g_strsplit_set (order_after, ",:;", -1);
350
351 /* success */
352 return TRUE;
353 }
354
355 /* private */
356 gchar **
357 fwupd_remote_get_order_after (FwupdRemote *self)
358 {
359 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
360 return self->order_after;
361 }
362
363 /* private */
364 gchar **
365 fwupd_remote_get_order_before (FwupdRemote *self)
366 {
367 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
368 return self->order_before;
369 }
370
371 /**
372 * fwupd_remote_get_filename_cache:
373 * @self: A #FwupdRemote
374 *
375 * Gets the path and filename that the remote is using for a cache.
376 *
377 * Returns: a string, or %NULL for unset
378 *
379 * Since: 0.9.6
380 **/
381 const gchar *
382 fwupd_remote_get_filename_cache (FwupdRemote *self)
383 {
384 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
385 return self->filename_cache;
386 }
387
388 /**
389 * fwupd_remote_get_filename_cache_sig:
390 * @self: A #FwupdRemote
391 *
392 * Gets the path and filename that the remote is using for a signature cache.
393 *
394 * Returns: a string, or %NULL for unset
395 *
396 * Since: 0.9.7
397 **/
398 const gchar *
399 fwupd_remote_get_filename_cache_sig (FwupdRemote *self)
400 {
401 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
402 return self->filename_cache_sig;
403 }
404
405 /**
406 * fwupd_remote_get_priority:
407 * @self: A #FwupdRemote
408 *
409 * Gets the priority of the remote, where bigger numbers are better.
410 *
411 * Returns: a priority, or 0 for the default value
412 *
413 * Since: 0.9.5
414 **/
415 gint
416 fwupd_remote_get_priority (FwupdRemote *self)
417 {
418 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
419 return self->priority;
420 }
421
422 /**
423 * fwupd_remote_get_kind:
424 * @self: A #FwupdRemote
425 *
426 * Gets the kind of the remote.
427 *
428 * Returns: a #FwupdRemoteKind, e.g. #FWUPD_REMOTE_KIND_LOCAL
429 *
430 * Since: 0.9.6
431 **/
432 FwupdRemoteKind
433 fwupd_remote_get_kind (FwupdRemote *self)
434 {
435 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
436 return self->kind;
437 }
438
439 /**
440 * fwupd_remote_get_keyring_kind:
441 * @self: A #FwupdRemote
442 *
443 * Gets the keyring kind of the remote.
444 *
445 * Returns: a #FwupdKeyringKind, e.g. #FWUPD_KEYRING_KIND_GPG
446 *
447 * Since: 0.9.7
448 **/
449 FwupdKeyringKind
450 fwupd_remote_get_keyring_kind (FwupdRemote *self)
451 {
452 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
453 return self->keyring_kind;
454 }
455
456 /**
457 * fwupd_remote_get_age:
458 * @self: A #FwupdRemote
459 *
460 * Gets the age of the remote in seconds.
461 *
462 * Returns: a age, or %G_MAXUINT64 for unavailable
463 *
464 * Since: 0.9.5
465 **/
466 guint64
467 fwupd_remote_get_age (FwupdRemote *self)
468 {
469 guint64 now;
470 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
471 now = (guint64) g_get_real_time () / G_USEC_PER_SEC;
472 if (self->mtime > now)
473 return G_MAXUINT64;
474 return now - self->mtime;
475 }
476
477 /* private */
478 void
479 fwupd_remote_set_priority (FwupdRemote *self, gint priority)
480 {
481 g_return_if_fail (FWUPD_IS_REMOTE (self));
482 self->priority = priority;
483 }
484
485 /* private */
486 void
487 fwupd_remote_set_mtime (FwupdRemote *self, guint64 mtime)
488 {
489 g_return_if_fail (FWUPD_IS_REMOTE (self));
490 self->mtime = mtime;
491 }
492
493 const gchar *
494 fwupd_remote_get_filename (FwupdRemote *self)
495 {
496 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
497 return self->filename;
498 }
499
500 const gchar *
501 fwupd_remote_get_username (FwupdRemote *self)
502 {
503 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
504 return self->username;
505 }
506
507 const gchar *
508 fwupd_remote_get_password (FwupdRemote *self)
509 {
510 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
511 return self->password;
512 }
513
514 const gchar *
515 fwupd_remote_get_filename_asc (FwupdRemote *self)
516 {
517 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
518 return self->filename_asc;
519 }
520
521 /**
522 * fwupd_remote_build_uri:
523 * @self: A #FwupdRemote
524 * @url: the URL to use
525 * @error: the #GError, or %NULL
526 *
527 * Builds a URI for the URL using the username and password set for the remote,
528 * including any basename URI substitution.
529 *
530 * Returns: (transfer full): a #SoupURI, or %NULL for error
531 *
532 * Since: 0.9.3
533 **/
534 SoupURI *
149 static SoupURI *
535150 fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
536151 {
152 FwupdRemotePrivate *priv = GET_PRIVATE (self);
537153 SoupURI *uri;
538154
539155 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
541157 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
542158
543159 /* create URI, substituting if required */
544 if (self->firmware_base_uri != NULL) {
160 if (priv->firmware_base_uri != NULL) {
545161 g_autoptr(SoupURI) uri_tmp = NULL;
546162 g_autofree gchar *basename = NULL;
547163 g_autofree gchar *url2 = NULL;
554170 return NULL;
555171 }
556172 basename = g_path_get_basename (soup_uri_get_path (uri_tmp));
557 url2 = g_build_filename (self->firmware_base_uri, basename, NULL);
173 url2 = g_build_filename (priv->firmware_base_uri, basename, NULL);
558174 uri = soup_uri_new (url2);
559175 if (uri == NULL) {
560176 g_set_error (error,
574190 }
575191 }
576192
577 /* set the username and password from the metadata URI */
578 if (self->uri != NULL) {
579 soup_uri_set_user (uri, soup_uri_get_user (self->uri));
580 soup_uri_set_password (uri, soup_uri_get_password (self->uri));
581 }
193 /* set the username and password */
194 if (priv->username != NULL)
195 soup_uri_set_user (uri, priv->username);
196 if (priv->password != NULL)
197 soup_uri_set_password (uri, priv->password);
582198 return uri;
199 }
200
201 /* note, this has to be set before username and password */
202 static void
203 fwupd_remote_set_metadata_uri (FwupdRemote *self, const gchar *metadata_uri)
204 {
205 FwupdRemotePrivate *priv = GET_PRIVATE (self);
206 const gchar *suffix;
207 g_autoptr(SoupURI) uri = NULL;
208 g_autoptr(SoupURI) uri_asc = NULL;
209
210 /* build the URI */
211 uri = soup_uri_new (metadata_uri);
212 if (uri == NULL)
213 return;
214
215 /* save this so we can export the object as a GVariant */
216 priv->metadata_uri = g_strdup (metadata_uri);
217
218 /* generate the signature URI too */
219 suffix = fwupd_remote_get_suffix_for_keyring_kind (priv->keyring_kind);
220 if (suffix != NULL) {
221 priv->metadata_uri_sig = g_strconcat (metadata_uri, suffix, NULL);
222 uri_asc = fwupd_remote_build_uri (self, priv->metadata_uri_sig, NULL);
223 }
224 }
225
226 /* note, this has to be set after MetadataURI */
227 static void
228 fwupd_remote_set_firmware_base_uri (FwupdRemote *self, const gchar *firmware_base_uri)
229 {
230 FwupdRemotePrivate *priv = GET_PRIVATE (self);
231 priv->firmware_base_uri = g_strdup (firmware_base_uri);
232 }
233
234 /**
235 * fwupd_remote_kind_from_string:
236 * @kind: a string, e.g. `download`
237 *
238 * Converts an printable string to an enumerated type.
239 *
240 * Returns: a #FwupdRemoteKind, e.g. %FWUPD_REMOTE_KIND_DOWNLOAD
241 *
242 * Since: 0.9.6
243 **/
244 FwupdRemoteKind
245 fwupd_remote_kind_from_string (const gchar *kind)
246 {
247 if (g_strcmp0 (kind, "download") == 0)
248 return FWUPD_REMOTE_KIND_DOWNLOAD;
249 if (g_strcmp0 (kind, "local") == 0)
250 return FWUPD_REMOTE_KIND_LOCAL;
251 return FWUPD_REMOTE_KIND_UNKNOWN;
252 }
253
254 /**
255 * fwupd_remote_kind_to_string:
256 * @kind: a #FwupdRemoteKind, e.g. %FWUPD_REMOTE_KIND_DOWNLOAD
257 *
258 * Converts an enumerated type to a printable string.
259 *
260 * Returns: a string, e.g. `download`
261 *
262 * Since: 0.9.6
263 **/
264 const gchar *
265 fwupd_remote_kind_to_string (FwupdRemoteKind kind)
266 {
267 if (kind == FWUPD_REMOTE_KIND_DOWNLOAD)
268 return "download";
269 if (kind == FWUPD_REMOTE_KIND_LOCAL)
270 return "local";
271 return NULL;
272 }
273
274 static void
275 fwupd_remote_set_filename_cache (FwupdRemote *self, const gchar *filename)
276 {
277 FwupdRemotePrivate *priv = GET_PRIVATE (self);
278 const gchar *suffix;
279
280 g_return_if_fail (FWUPD_IS_REMOTE (self));
281
282 g_free (priv->filename_cache);
283 priv->filename_cache = g_strdup (filename);
284
285 /* create for all remote types */
286 suffix = fwupd_remote_get_suffix_for_keyring_kind (priv->keyring_kind);
287 if (suffix != NULL) {
288 g_free (priv->filename_cache_sig);
289 priv->filename_cache_sig = g_strconcat (filename, suffix, NULL);
290 }
291 }
292
293 /**
294 * fwupd_remote_load_from_filename:
295 * @self: A #FwupdRemote
296 * @filename: A filename
297 * @cancellable: the #GCancellable, or %NULL
298 * @error: the #GError, or %NULL
299 *
300 * Sets up the remote ready for use. Most other methods call this
301 * for you, and do you only need to call this if you are just watching
302 * the self.
303 *
304 * Returns: %TRUE for success
305 *
306 * Since: 0.9.3
307 **/
308 gboolean
309 fwupd_remote_load_from_filename (FwupdRemote *self,
310 const gchar *filename,
311 GCancellable *cancellable,
312 GError **error)
313 {
314 FwupdRemotePrivate *priv = GET_PRIVATE (self);
315 const gchar *group = "fwupd Remote";
316 g_autofree gchar *firmware_base_uri = NULL;
317 g_autofree gchar *id = NULL;
318 g_autofree gchar *keyring_kind = NULL;
319 g_autofree gchar *metadata_uri = NULL;
320 g_autofree gchar *order_after = NULL;
321 g_autofree gchar *order_before = NULL;
322 g_autoptr(GKeyFile) kf = NULL;
323
324 g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE);
325 g_return_val_if_fail (filename != NULL, FALSE);
326 g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
327 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
328
329 /* set ID */
330 id = g_path_get_basename (filename);
331 fwupd_remote_set_id (self, id);
332
333 /* load file */
334 kf = g_key_file_new ();
335 if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_NONE, error))
336 return FALSE;
337
338 /* get verification type, falling back to GPG */
339 keyring_kind = g_key_file_get_string (kf, group, "Keyring", NULL);
340 if (keyring_kind == NULL) {
341 priv->keyring_kind = FWUPD_KEYRING_KIND_GPG;
342 } else {
343 priv->keyring_kind = fwupd_keyring_kind_from_string (keyring_kind);
344 if (priv->keyring_kind == FWUPD_KEYRING_KIND_UNKNOWN) {
345 g_set_error (error,
346 FWUPD_ERROR,
347 FWUPD_ERROR_INVALID_FILE,
348 "Failed to parse type '%s'",
349 keyring_kind);
350 return FALSE;
351 }
352 }
353
354 /* all remotes need a URI, even if it's file:// to the cache */
355 metadata_uri = g_key_file_get_string (kf, group, "MetadataURI", error);
356 if (metadata_uri == NULL)
357 return FALSE;
358 if (g_str_has_prefix (metadata_uri, "file://")) {
359 priv->kind = FWUPD_REMOTE_KIND_LOCAL;
360 } else if (g_str_has_prefix (metadata_uri, "http://") ||
361 g_str_has_prefix (metadata_uri, "https://")) {
362 priv->kind = FWUPD_REMOTE_KIND_DOWNLOAD;
363 } else {
364 g_set_error (error,
365 FWUPD_ERROR,
366 FWUPD_ERROR_INVALID_FILE,
367 "Failed to parse MetadataURI type '%s'",
368 metadata_uri);
369 return FALSE;
370 }
371
372 /* extract data */
373 priv->enabled = g_key_file_get_boolean (kf, group, "Enabled", NULL);
374 priv->title = g_key_file_get_string (kf, group, "Title", NULL);
375
376 /* DOWNLOAD-type remotes */
377 if (priv->kind == FWUPD_REMOTE_KIND_DOWNLOAD) {
378 g_autofree gchar *filename_cache = NULL;
379 g_autofree gchar *username = NULL;
380 g_autofree gchar *password = NULL;
381
382 /* the client has to download this and the signature */
383 fwupd_remote_set_metadata_uri (self, metadata_uri);
384
385 /* check the URI was valid */
386 if (priv->metadata_uri == NULL) {
387 g_set_error (error,
388 FWUPD_ERROR,
389 FWUPD_ERROR_INVALID_FILE,
390 "Failed to parse URI '%s' in %s",
391 metadata_uri, filename);
392 return FALSE;
393 }
394
395 /* username and password are optional */
396 username = g_key_file_get_string (kf, group, "Username", NULL);
397 if (username != NULL)
398 fwupd_remote_set_username (self, username);
399 password = g_key_file_get_string (kf, group, "Password", NULL);
400 if (password != NULL)
401 fwupd_remote_set_password (self, password);
402
403 /* set cache to /var/lib... */
404 filename_cache = g_build_filename (LOCALSTATEDIR,
405 "lib",
406 "fwupd",
407 "remotes.d",
408 priv->id,
409 "metadata.xml.gz",
410 NULL);
411 fwupd_remote_set_filename_cache (self, filename_cache);
412 }
413
414 /* all LOCAL remotes have to include a valid MetadataURI */
415 if (priv->kind == FWUPD_REMOTE_KIND_LOCAL) {
416 const gchar *filename_cache = metadata_uri;
417 if (g_str_has_prefix (filename_cache, "file://"))
418 filename_cache += 7;
419 fwupd_remote_set_filename_cache (self, filename_cache);
420 }
421
422 /* load the checksum */
423 if (priv->filename_cache_sig != NULL &&
424 g_file_test (priv->filename_cache_sig, G_FILE_TEST_EXISTS)) {
425 gsize sz = 0;
426 g_autofree gchar *buf = NULL;
427 g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
428 if (!g_file_get_contents (priv->filename_cache_sig, &buf, &sz, error)) {
429 g_prefix_error (error, "failed to get checksum: ");
430 return FALSE;
431 }
432 g_checksum_update (checksum, (guchar *) buf, (gssize) sz);
433 fwupd_remote_set_checksum (self, g_checksum_get_string (checksum));
434 } else {
435 fwupd_remote_set_checksum (self, NULL);
436 }
437
438 /* the base URI is optional */
439 firmware_base_uri = g_key_file_get_string (kf, group, "FirmwareBaseURI", NULL);
440 if (firmware_base_uri != NULL)
441 fwupd_remote_set_firmware_base_uri (self, firmware_base_uri);
442
443 /* dep logic */
444 order_before = g_key_file_get_string (kf, group, "OrderBefore", NULL);
445 if (order_before != NULL)
446 priv->order_before = g_strsplit_set (order_before, ",:;", -1);
447 order_after = g_key_file_get_string (kf, group, "OrderAfter", NULL);
448 if (order_after != NULL)
449 priv->order_after = g_strsplit_set (order_after, ",:;", -1);
450
451 /* success */
452 fwupd_remote_set_filename_source (self, filename);
453 return TRUE;
454 }
455
456 /**
457 * fwupd_remote_get_order_after:
458 * @self: A #FwupdRemote
459 *
460 * Gets the list of remotes this plugin should be ordered after.
461 *
462 * Returns: (transfer none): an array
463 *
464 * Since: 0.9.5
465 **/
466 gchar **
467 fwupd_remote_get_order_after (FwupdRemote *self)
468 {
469 FwupdRemotePrivate *priv = GET_PRIVATE (self);
470 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
471 return priv->order_after;
472 }
473
474 /**
475 * fwupd_remote_get_order_before:
476 * @self: A #FwupdRemote
477 *
478 * Gets the list of remotes this plugin should be ordered before.
479 *
480 * Returns: (transfer none): an array
481 *
482 * Since: 0.9.5
483 **/
484 gchar **
485 fwupd_remote_get_order_before (FwupdRemote *self)
486 {
487 FwupdRemotePrivate *priv = GET_PRIVATE (self);
488 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
489 return priv->order_before;
490 }
491
492 /**
493 * fwupd_remote_get_filename_cache:
494 * @self: A #FwupdRemote
495 *
496 * Gets the path and filename that the remote is using for a cache.
497 *
498 * Returns: a string, or %NULL for unset
499 *
500 * Since: 0.9.6
501 **/
502 const gchar *
503 fwupd_remote_get_filename_cache (FwupdRemote *self)
504 {
505 FwupdRemotePrivate *priv = GET_PRIVATE (self);
506 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
507 return priv->filename_cache;
508 }
509
510 /**
511 * fwupd_remote_get_filename_cache_sig:
512 * @self: A #FwupdRemote
513 *
514 * Gets the path and filename that the remote is using for a signature cache.
515 *
516 * Returns: a string, or %NULL for unset
517 *
518 * Since: 0.9.7
519 **/
520 const gchar *
521 fwupd_remote_get_filename_cache_sig (FwupdRemote *self)
522 {
523 FwupdRemotePrivate *priv = GET_PRIVATE (self);
524 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
525 return priv->filename_cache_sig;
526 }
527
528 /**
529 * fwupd_remote_get_filename_source:
530 * @self: A #FwupdRemote
531 *
532 * Gets the path and filename of the remote itself, typically a `.conf` file.
533 *
534 * Returns: a string, or %NULL for unset
535 *
536 * Since: 0.9.8
537 **/
538 const gchar *
539 fwupd_remote_get_filename_source (FwupdRemote *self)
540 {
541 FwupdRemotePrivate *priv = GET_PRIVATE (self);
542 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
543 return priv->filename_source;
544 }
545
546 /**
547 * fwupd_remote_get_priority:
548 * @self: A #FwupdRemote
549 *
550 * Gets the priority of the remote, where bigger numbers are better.
551 *
552 * Returns: a priority, or 0 for the default value
553 *
554 * Since: 0.9.5
555 **/
556 gint
557 fwupd_remote_get_priority (FwupdRemote *self)
558 {
559 FwupdRemotePrivate *priv = GET_PRIVATE (self);
560 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
561 return priv->priority;
562 }
563
564 /**
565 * fwupd_remote_get_kind:
566 * @self: A #FwupdRemote
567 *
568 * Gets the kind of the remote.
569 *
570 * Returns: a #FwupdRemoteKind, e.g. #FWUPD_REMOTE_KIND_LOCAL
571 *
572 * Since: 0.9.6
573 **/
574 FwupdRemoteKind
575 fwupd_remote_get_kind (FwupdRemote *self)
576 {
577 FwupdRemotePrivate *priv = GET_PRIVATE (self);
578 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
579 return priv->kind;
580 }
581
582 /**
583 * fwupd_remote_get_keyring_kind:
584 * @self: A #FwupdRemote
585 *
586 * Gets the keyring kind of the remote.
587 *
588 * Returns: a #FwupdKeyringKind, e.g. #FWUPD_KEYRING_KIND_GPG
589 *
590 * Since: 0.9.7
591 **/
592 FwupdKeyringKind
593 fwupd_remote_get_keyring_kind (FwupdRemote *self)
594 {
595 FwupdRemotePrivate *priv = GET_PRIVATE (self);
596 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
597 return priv->keyring_kind;
598 }
599
600 /**
601 * fwupd_remote_get_age:
602 * @self: A #FwupdRemote
603 *
604 * Gets the age of the remote in seconds.
605 *
606 * Returns: a age, or %G_MAXUINT64 for unavailable
607 *
608 * Since: 0.9.5
609 **/
610 guint64
611 fwupd_remote_get_age (FwupdRemote *self)
612 {
613 FwupdRemotePrivate *priv = GET_PRIVATE (self);
614 guint64 now;
615 g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0);
616 now = (guint64) g_get_real_time () / G_USEC_PER_SEC;
617 if (priv->mtime > now)
618 return G_MAXUINT64;
619 return now - priv->mtime;
620 }
621
622 /**
623 * fwupd_remote_set_priority:
624 * @self: A #FwupdRemote
625 * @priority: an integer, where 1 is better
626 *
627 * Sets the plugin priority.
628 *
629 * Since: 0.9.5
630 **/
631 void
632 fwupd_remote_set_priority (FwupdRemote *self, gint priority)
633 {
634 FwupdRemotePrivate *priv = GET_PRIVATE (self);
635 g_return_if_fail (FWUPD_IS_REMOTE (self));
636 priv->priority = priority;
637 }
638
639 /**
640 * fwupd_remote_set_mtime:
641 * @self: A #FwupdRemote
642 * @mtime: a UNIX itmestamp
643 *
644 * Sets the plugin modification time.
645 *
646 * Since: 0.9.5
647 **/
648 void
649 fwupd_remote_set_mtime (FwupdRemote *self, guint64 mtime)
650 {
651 FwupdRemotePrivate *priv = GET_PRIVATE (self);
652 g_return_if_fail (FWUPD_IS_REMOTE (self));
653 priv->mtime = mtime;
654 }
655
656 /**
657 * fwupd_remote_get_username:
658 * @self: A #FwupdRemote
659 *
660 * Gets the username configured for the remote.
661 *
662 * Returns: a string, or %NULL for unset
663 *
664 * Since: 0.9.5
665 **/
666 const gchar *
667 fwupd_remote_get_username (FwupdRemote *self)
668 {
669 FwupdRemotePrivate *priv = GET_PRIVATE (self);
670 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
671 return priv->username;
672 }
673
674 /**
675 * fwupd_remote_get_password:
676 * @self: A #FwupdRemote
677 *
678 * Gets the password configured for the remote.
679 *
680 * Returns: a string, or %NULL for unset
681 *
682 * Since: 0.9.5
683 **/
684 const gchar *
685 fwupd_remote_get_password (FwupdRemote *self)
686 {
687 FwupdRemotePrivate *priv = GET_PRIVATE (self);
688 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
689 return priv->password;
690 }
691
692 /**
693 * fwupd_remote_get_title:
694 * @self: A #FwupdRemote
695 *
696 * Gets the remote title, e.g. `Linux Vendor Firmware Service`.
697 *
698 * Returns: a string, or %NULL if unset
699 *
700 * Since: 0.9.8
701 **/
702 const gchar *
703 fwupd_remote_get_title (FwupdRemote *self)
704 {
705 FwupdRemotePrivate *priv = GET_PRIVATE (self);
706 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
707 return priv->title;
708 }
709
710 /**
711 * fwupd_remote_get_checksum:
712 * @self: A #FwupdRemote
713 *
714 * Gets the remote checksum.
715 *
716 * Returns: a string, or %NULL if unset
717 *
718 * Since: 1.0.0
719 **/
720 const gchar *
721 fwupd_remote_get_checksum (FwupdRemote *self)
722 {
723 FwupdRemotePrivate *priv = GET_PRIVATE (self);
724 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
725 return priv->checksum;
583726 }
584727
585728 /**
605748 }
606749
607750 /**
608 * fwupd_remote_get_uri:
609 * @self: A #FwupdRemote
610 *
611 * Gets the URI for the remote metadata.
612 *
613 * Returns: (transfer none): a #SoupURI, or %NULL for invalid.
614 *
615 * Since: 0.9.3
616 **/
617 SoupURI *
618 fwupd_remote_get_uri (FwupdRemote *self)
619 {
620 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
621 return self->uri;
622 }
623
624 /**
625 * fwupd_remote_get_uri_asc:
626 * @self: A #FwupdRemote
627 *
628 * Gets the URI for the remote signature.
629 *
630 * Returns: (transfer none): a #SoupURI, or %NULL for invalid.
631 *
632 * Since: 0.9.3
633 **/
634 SoupURI *
635 fwupd_remote_get_uri_asc (FwupdRemote *self)
636 {
637 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
638 return self->uri_asc;
639 }
640
641 /**
642751 * fwupd_remote_get_metadata_uri:
643752 * @self: A #FwupdRemote
644753 *
651760 const gchar *
652761 fwupd_remote_get_metadata_uri (FwupdRemote *self)
653762 {
654 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
655 return self->metadata_uri;
763 FwupdRemotePrivate *priv = GET_PRIVATE (self);
764 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
765 return priv->metadata_uri;
656766 }
657767
658768 /**
668778 const gchar *
669779 fwupd_remote_get_metadata_uri_sig (FwupdRemote *self)
670780 {
671 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
672 return self->metadata_uri_sig;
781 FwupdRemotePrivate *priv = GET_PRIVATE (self);
782 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
783 return priv->metadata_uri_sig;
673784 }
674785
675786 /**
685796 const gchar *
686797 fwupd_remote_get_firmware_base_uri (FwupdRemote *self)
687798 {
688 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
689 return self->firmware_base_uri;
799 FwupdRemotePrivate *priv = GET_PRIVATE (self);
800 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
801 return priv->firmware_base_uri;
690802 }
691803
692804 /**
702814 gboolean
703815 fwupd_remote_get_enabled (FwupdRemote *self)
704816 {
817 FwupdRemotePrivate *priv = GET_PRIVATE (self);
705818 g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE);
706 return self->enabled;
819 return priv->enabled;
707820 }
708821
709822 /**
710823 * fwupd_remote_get_id:
711824 * @self: A #FwupdRemote
712825 *
713 * Gets the remote ID, e.g. "lvfs-testing".
826 * Gets the remote ID, e.g. `lvfs-testing`.
714827 *
715828 * Returns: a string, or %NULL if unset
716829 *
719832 const gchar *
720833 fwupd_remote_get_id (FwupdRemote *self)
721834 {
722 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
723 return self->id;
724 }
725
726 static void
727 fwupd_remote_to_variant_builder (FwupdRemote *self, GVariantBuilder *builder)
728 {
729 if (self->id != NULL) {
730 g_variant_builder_add (builder, "{sv}", "Id",
731 g_variant_new_string (self->id));
732 }
733 if (self->username != NULL) {
734 g_variant_builder_add (builder, "{sv}", "Username",
735 g_variant_new_string (self->username));
736 }
737 if (self->password != NULL) {
738 g_variant_builder_add (builder, "{sv}", "Password",
739 g_variant_new_string (self->password));
740 }
741 if (self->metadata_uri != NULL) {
742 g_variant_builder_add (builder, "{sv}", "Url",
743 g_variant_new_string (self->metadata_uri));
744 }
745 if (self->firmware_base_uri != NULL) {
746 g_variant_builder_add (builder, "{sv}", "FirmwareBaseUri",
747 g_variant_new_string (self->firmware_base_uri));
748 }
749 if (self->priority != 0) {
750 g_variant_builder_add (builder, "{sv}", "Priority",
751 g_variant_new_int32 (self->priority));
752 }
753 if (self->kind != FWUPD_REMOTE_KIND_UNKNOWN) {
754 g_variant_builder_add (builder, "{sv}", "Type",
755 g_variant_new_uint32 (self->kind));
756 }
757 if (self->keyring_kind != FWUPD_KEYRING_KIND_UNKNOWN) {
758 g_variant_builder_add (builder, "{sv}", "Keyring",
759 g_variant_new_uint32 (self->keyring_kind));
760 }
761 if (self->mtime != 0) {
762 g_variant_builder_add (builder, "{sv}", "ModificationTime",
763 g_variant_new_uint64 (self->mtime));
764 }
765 if (self->filename_cache != NULL) {
766 g_variant_builder_add (builder, "{sv}", "FilenameCache",
767 g_variant_new_string (self->filename_cache));
768 }
769 g_variant_builder_add (builder, "{sv}", "Enabled",
770 g_variant_new_boolean (self->enabled));
835 FwupdRemotePrivate *priv = GET_PRIVATE (self);
836 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
837 return priv->id;
771838 }
772839
773840 static void
774841 fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
775842 {
843 FwupdRemotePrivate *priv = GET_PRIVATE (self);
776844 GVariant *value;
777845 const gchar *key;
778846 g_autoptr(GVariantIter) iter2 = g_variant_iter_copy (iter);
780848
781849 /* three passes, as we have to construct Id -> Url -> * */
782850 while (g_variant_iter_loop (iter, "{sv}", &key, &value)) {
783 if (g_strcmp0 (key, "Id") == 0)
851 if (g_strcmp0 (key, FWUPD_RESULT_KEY_REMOTE_ID) == 0)
784852 fwupd_remote_set_id (self, g_variant_get_string (value, NULL));
785853 if (g_strcmp0 (key, "Type") == 0)
786854 fwupd_remote_set_kind (self, g_variant_get_uint32 (value));
788856 fwupd_remote_set_keyring_kind (self, g_variant_get_uint32 (value));
789857 }
790858 while (g_variant_iter_loop (iter2, "{sv}", &key, &value)) {
791 if (g_strcmp0 (key, "Url") == 0)
859 if (g_strcmp0 (key, FWUPD_RESULT_KEY_URI) == 0)
792860 fwupd_remote_set_metadata_uri (self, g_variant_get_string (value, NULL));
793861 if (g_strcmp0 (key, "FilenameCache") == 0)
794862 fwupd_remote_set_filename_cache (self, g_variant_get_string (value, NULL));
863 if (g_strcmp0 (key, "FilenameSource") == 0)
864 fwupd_remote_set_filename_source (self, g_variant_get_string (value, NULL));
795865 }
796866 while (g_variant_iter_loop (iter3, "{sv}", &key, &value)) {
797867 if (g_strcmp0 (key, "Username") == 0) {
798868 fwupd_remote_set_username (self, g_variant_get_string (value, NULL));
799869 } else if (g_strcmp0 (key, "Password") == 0) {
800870 fwupd_remote_set_password (self, g_variant_get_string (value, NULL));
871 } else if (g_strcmp0 (key, "Title") == 0) {
872 fwupd_remote_set_title (self, g_variant_get_string (value, NULL));
873 } else if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) {
874 fwupd_remote_set_checksum (self, g_variant_get_string (value, NULL));
801875 } else if (g_strcmp0 (key, "Enabled") == 0) {
802 self->enabled = g_variant_get_boolean (value);
876 priv->enabled = g_variant_get_boolean (value);
803877 } else if (g_strcmp0 (key, "Priority") == 0) {
804 self->priority = g_variant_get_int32 (value);
878 priv->priority = g_variant_get_int32 (value);
805879 } else if (g_strcmp0 (key, "ModificationTime") == 0) {
806 self->mtime = g_variant_get_uint64 (value);
880 priv->mtime = g_variant_get_uint64 (value);
807881 } else if (g_strcmp0 (key, "FirmwareBaseUri") == 0) {
808882 fwupd_remote_set_firmware_base_uri (self, g_variant_get_string (value, NULL));
809883 }
811885 }
812886
813887 /**
814 * fwupd_remote_to_data:
815 * @remote: A #FwupdRemote
816 * @type_string: The Gvariant type string, e.g. "a{sv}" or "(a{sv})"
888 * fwupd_remote_to_variant:
889 * @self: A #FwupdRemote
817890 *
818891 * Creates a GVariant from the remote data.
819892 *
820893 * Returns: the GVariant, or %NULL for error
821894 *
822 * Since: 0.9.5
895 * Since: 1.0.0
823896 **/
824897 GVariant *
825 fwupd_remote_to_data (FwupdRemote *self, const gchar *type_string)
826 {
898 fwupd_remote_to_variant (FwupdRemote *self)
899 {
900 FwupdRemotePrivate *priv = GET_PRIVATE (self);
827901 GVariantBuilder builder;
828902
829903 g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
830 g_return_val_if_fail (type_string != NULL, NULL);
831904
832905 /* create an array with all the metadata in */
833906 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
834 fwupd_remote_to_variant_builder (self, &builder);
835
836 /* supported types */
837 if (g_strcmp0 (type_string, "a{sv}") == 0)
838 return g_variant_new ("a{sv}", &builder);
839 if (g_strcmp0 (type_string, "(a{sv})") == 0)
840 return g_variant_new ("(a{sv})", &builder);
841 return NULL;
907 if (priv->id != NULL) {
908 g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_REMOTE_ID,
909 g_variant_new_string (priv->id));
910 }
911 if (priv->username != NULL) {
912 g_variant_builder_add (&builder, "{sv}", "Username",
913 g_variant_new_string (priv->username));
914 }
915 if (priv->password != NULL) {
916 g_variant_builder_add (&builder, "{sv}", "Password",
917 g_variant_new_string (priv->password));
918 }
919 if (priv->title != NULL) {
920 g_variant_builder_add (&builder, "{sv}", "Title",
921 g_variant_new_string (priv->title));
922 }
923 if (priv->checksum != NULL) {
924 g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_CHECKSUM,
925 g_variant_new_string (priv->checksum));
926 }
927 if (priv->metadata_uri != NULL) {
928 g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_URI,
929 g_variant_new_string (priv->metadata_uri));
930 }
931 if (priv->firmware_base_uri != NULL) {
932 g_variant_builder_add (&builder, "{sv}", "FirmwareBaseUri",
933 g_variant_new_string (priv->firmware_base_uri));
934 }
935 if (priv->priority != 0) {
936 g_variant_builder_add (&builder, "{sv}", "Priority",
937 g_variant_new_int32 (priv->priority));
938 }
939 if (priv->kind != FWUPD_REMOTE_KIND_UNKNOWN) {
940 g_variant_builder_add (&builder, "{sv}", "Type",
941 g_variant_new_uint32 (priv->kind));
942 }
943 if (priv->keyring_kind != FWUPD_KEYRING_KIND_UNKNOWN) {
944 g_variant_builder_add (&builder, "{sv}", "Keyring",
945 g_variant_new_uint32 (priv->keyring_kind));
946 }
947 if (priv->mtime != 0) {
948 g_variant_builder_add (&builder, "{sv}", "ModificationTime",
949 g_variant_new_uint64 (priv->mtime));
950 }
951 if (priv->filename_cache != NULL) {
952 g_variant_builder_add (&builder, "{sv}", "FilenameCache",
953 g_variant_new_string (priv->filename_cache));
954 }
955 if (priv->filename_source != NULL) {
956 g_variant_builder_add (&builder, "{sv}", "FilenameSource",
957 g_variant_new_string (priv->filename_source));
958 }
959 g_variant_builder_add (&builder, "{sv}", "Enabled",
960 g_variant_new_boolean (priv->enabled));
961 return g_variant_new ("a{sv}", &builder);
842962 }
843963
844964 static void
846966 GValue *value, GParamSpec *pspec)
847967 {
848968 FwupdRemote *self = FWUPD_REMOTE (obj);
969 FwupdRemotePrivate *priv = GET_PRIVATE (self);
849970
850971 switch (prop_id) {
851972 case PROP_ENABLED:
852 g_value_set_boolean (value, self->enabled);
973 g_value_set_boolean (value, priv->enabled);
853974 break;
854975 case PROP_ID:
855 g_value_set_string (value, self->id);
976 g_value_set_string (value, priv->id);
856977 break;
857978 default:
858979 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
865986 const GValue *value, GParamSpec *pspec)
866987 {
867988 FwupdRemote *self = FWUPD_REMOTE (obj);
989 FwupdRemotePrivate *priv = GET_PRIVATE (self);
868990
869991 switch (prop_id) {
870992 case PROP_ENABLED:
871 self->enabled = g_value_get_boolean (value);
993 priv->enabled = g_value_get_boolean (value);
872994 break;
873995 case PROP_ID:
874996 fwupd_remote_set_id (self, g_value_get_string (value));
9201042 fwupd_remote_finalize (GObject *obj)
9211043 {
9221044 FwupdRemote *self = FWUPD_REMOTE (obj);
923
924 g_free (self->id);
925 g_free (self->metadata_uri);
926 g_free (self->metadata_uri_sig);
927 g_free (self->firmware_base_uri);
928 g_free (self->username);
929 g_free (self->password);
930 g_free (self->filename);
931 g_free (self->filename_asc);
932 g_free (self->filename_cache);
933 g_free (self->filename_cache_sig);
934 g_strfreev (self->order_after);
935 g_strfreev (self->order_before);
936 if (self->uri != NULL)
937 soup_uri_free (self->uri);
938 if (self->uri_asc != NULL)
939 soup_uri_free (self->uri_asc);
1045 FwupdRemotePrivate *priv = GET_PRIVATE (self);
1046
1047 g_free (priv->id);
1048 g_free (priv->metadata_uri);
1049 g_free (priv->metadata_uri_sig);
1050 g_free (priv->firmware_base_uri);
1051 g_free (priv->username);
1052 g_free (priv->password);
1053 g_free (priv->title);
1054 g_free (priv->checksum);
1055 g_free (priv->filename_cache);
1056 g_free (priv->filename_cache_sig);
1057 g_free (priv->filename_source);
1058 g_strfreev (priv->order_after);
1059 g_strfreev (priv->order_before);
9401060
9411061 G_OBJECT_CLASS (fwupd_remote_parent_class)->finalize (obj);
9421062 }
9431063
9441064 /**
945 * fwupd_remote_new_from_data:
1065 * fwupd_remote_from_variant:
9461066 * @data: a #GVariant
9471067 *
9481068 * Creates a new remote using packed data.
9491069 *
950 * Returns: a new #FwupdRemote, or %NULL if @data was invalid
951 *
952 * Since: 0.9.5
1070 * Returns: (transfer full): a new #FwupdRemote, or %NULL if @data was invalid
1071 *
1072 * Since: 1.0.0
9531073 **/
9541074 FwupdRemote *
955 fwupd_remote_new_from_data (GVariant *data)
1075 fwupd_remote_from_variant (GVariant *data)
9561076 {
9571077 FwupdRemote *rel = NULL;
9581078 const gchar *type_string;
2121 #ifndef __FWUPD_REMOTE_H
2222 #define __FWUPD_REMOTE_H
2323
24 #include <libsoup/soup.h>
25
2624 #include "fwupd-enums.h"
2725
2826 G_BEGIN_DECLS
2927
3028 #define FWUPD_TYPE_REMOTE (fwupd_remote_get_type ())
31 G_DECLARE_FINAL_TYPE (FwupdRemote, fwupd_remote, FWUPD, REMOTE, GObject)
29 G_DECLARE_DERIVABLE_TYPE (FwupdRemote, fwupd_remote, FWUPD, REMOTE, GObject)
30
31 struct _FwupdRemoteClass
32 {
33 GObjectClass parent_class;
34 /*< private >*/
35 void (*_fwupd_reserved1) (void);
36 void (*_fwupd_reserved2) (void);
37 void (*_fwupd_reserved3) (void);
38 void (*_fwupd_reserved4) (void);
39 void (*_fwupd_reserved5) (void);
40 void (*_fwupd_reserved6) (void);
41 void (*_fwupd_reserved7) (void);
42 };
3243
3344 typedef enum {
3445 FWUPD_REMOTE_KIND_UNKNOWN,
4354
4455 FwupdRemote *fwupd_remote_new (void);
4556 const gchar *fwupd_remote_get_id (FwupdRemote *self);
46 const gchar *fwupd_remote_get_filename (FwupdRemote *self);
47 const gchar *fwupd_remote_get_filename_asc (FwupdRemote *self);
57 const gchar *fwupd_remote_get_title (FwupdRemote *self);
58 const gchar *fwupd_remote_get_checksum (FwupdRemote *self);
4859 const gchar *fwupd_remote_get_username (FwupdRemote *self);
4960 const gchar *fwupd_remote_get_password (FwupdRemote *self);
5061 const gchar *fwupd_remote_get_filename_cache (FwupdRemote *self);
5162 const gchar *fwupd_remote_get_filename_cache_sig (FwupdRemote *self);
63 const gchar *fwupd_remote_get_filename_source (FwupdRemote *self);
5264 const gchar *fwupd_remote_get_firmware_base_uri (FwupdRemote *self);
5365 const gchar *fwupd_remote_get_metadata_uri (FwupdRemote *self);
5466 const gchar *fwupd_remote_get_metadata_uri_sig (FwupdRemote *self);
6072 gchar *fwupd_remote_build_firmware_uri (FwupdRemote *self,
6173 const gchar *url,
6274 GError **error);
63 SoupURI *fwupd_remote_build_uri (FwupdRemote *self,
64 const gchar *url,
65 GError **error);
66
67 /* deprecated */
68 SoupURI *fwupd_remote_get_uri (FwupdRemote *self)
69 G_DEPRECATED_FOR(fwupd_remote_get_metadata_uri);
70 SoupURI *fwupd_remote_get_uri_asc (FwupdRemote *self)
71 G_DEPRECATED_FOR(fwupd_remote_get_metadata_uri_sig);
7275
7376 G_END_DECLS
7477
+0
-1662
libfwupd/fwupd-result.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <glib-object.h>
24 #include <gio/gio.h>
25 #include <string.h>
26
27 #include "fwupd-common-private.h"
28 #include "fwupd-device-private.h"
29 #include "fwupd-enums-private.h"
30 #include "fwupd-error.h"
31 #include "fwupd-release-private.h"
32 #include "fwupd-result.h"
33
34 static void fwupd_result_finalize (GObject *object);
35
36 typedef struct {
37 gchar *unique_id;
38 FwupdTrustFlags update_trust_flags;
39 FwupdUpdateState update_state;
40 gchar *update_error;
41 FwupdDevice *device;
42 FwupdRelease *release;
43 } FwupdResultPrivate;
44
45 enum {
46 SIGNAL_LAST
47 };
48
49 enum {
50 PROP_0,
51 PROP_DEVICE_ID,
52 PROP_UNIQUE_ID,
53 PROP_LAST
54 };
55
56 G_DEFINE_TYPE_WITH_PRIVATE (FwupdResult, fwupd_result, G_TYPE_OBJECT)
57 #define GET_PRIVATE(o) (fwupd_result_get_instance_private (o))
58
59 /**
60 * fwupd_result_get_unique_id:
61 * @result: A #FwupdResult
62 *
63 * Gets the unique ID that can be used for caching.
64 *
65 * Returns: the ID, or %NULL if unset
66 *
67 * Since: 0.7.3
68 **/
69 const gchar *
70 fwupd_result_get_unique_id (FwupdResult *result)
71 {
72 FwupdResultPrivate *priv = GET_PRIVATE (result);
73 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
74 return priv->unique_id;
75 }
76
77 /**
78 * fwupd_result_set_unique_id:
79 * @result: A #FwupdResult
80 * @unique_id: the result ID, e.g. "USB:foo"
81 *
82 * Sets the unique ID that can be used for caching.
83 *
84 * Since: 0.7.3
85 **/
86 void
87 fwupd_result_set_unique_id (FwupdResult *result, const gchar *unique_id)
88 {
89 FwupdResultPrivate *priv = GET_PRIVATE (result);
90 g_return_if_fail (FWUPD_IS_RESULT (result));
91 g_free (priv->unique_id);
92 priv->unique_id = g_strdup (unique_id);
93 }
94
95 /**
96 * fwupd_result_get_release:
97 * @result: A #FwupdResult
98 *
99 * Gets the default release for this result.
100 *
101 * Returns: (transfer none): the #FwupdRelease
102 *
103 * Since: 0.9.3
104 **/
105 FwupdRelease *
106 fwupd_result_get_release (FwupdResult *result)
107 {
108 FwupdResultPrivate *priv = GET_PRIVATE (result);
109 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
110 return priv->release;
111 }
112
113 /**
114 * fwupd_result_get_device:
115 * @result: A #FwupdResult
116 *
117 * Gets the default device for this result.
118 *
119 * Returns: (transfer none): the #FwupdDevice
120 *
121 * Since: 0.9.3
122 **/
123 FwupdDevice *
124 fwupd_result_get_device (FwupdResult *result)
125 {
126 FwupdResultPrivate *priv = GET_PRIVATE (result);
127 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
128 return priv->device;
129 }
130
131 /**
132 * fwupd_result_get_device_id:
133 * @result: A #FwupdResult
134 *
135 * Gets the ID.
136 *
137 * Returns: the ID, or %NULL if unset
138 *
139 * Since: 0.7.0
140 **/
141 const gchar *
142 fwupd_result_get_device_id (FwupdResult *result)
143 {
144 FwupdResultPrivate *priv = GET_PRIVATE (result);
145 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
146 return fwupd_device_get_id (priv->device);
147 }
148
149 /**
150 * fwupd_result_set_device_id:
151 * @result: A #FwupdResult
152 * @device_id: the result ID, e.g. "USB:foo"
153 *
154 * Sets the ID.
155 *
156 * Since: 0.7.0
157 **/
158 void
159 fwupd_result_set_device_id (FwupdResult *result, const gchar *device_id)
160 {
161 FwupdResultPrivate *priv = GET_PRIVATE (result);
162 g_return_if_fail (FWUPD_IS_RESULT (result));
163 fwupd_device_set_id (priv->device, device_id);
164 }
165
166 /**
167 * fwupd_result_get_guids:
168 * @result: A #FwupdResult
169 *
170 * Gets the GUIDs.
171 *
172 * Returns: (element-type utf8) (transfer none): the GUIDs
173 *
174 * Since: 0.7.2
175 **/
176 GPtrArray *
177 fwupd_result_get_guids (FwupdResult *result)
178 {
179 FwupdResultPrivate *priv = GET_PRIVATE (result);
180 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
181 return fwupd_device_get_guids (priv->device);
182 }
183
184 /**
185 * fwupd_result_has_guid:
186 * @result: A #FwupdResult
187 * @guid: the GUID, e.g. "2082b5e0-7a64-478a-b1b2-e3404fab6dad"
188 *
189 * Finds out if the device has this specific GUID.
190 *
191 * Returns: %TRUE if the GUID is found
192 *
193 * Since: 0.7.2
194 **/
195 gboolean
196 fwupd_result_has_guid (FwupdResult *result, const gchar *guid)
197 {
198 FwupdResultPrivate *priv = GET_PRIVATE (result);
199 g_return_val_if_fail (FWUPD_IS_RESULT (result), FALSE);
200 return fwupd_device_has_guid (priv->device, guid);
201 }
202
203 /**
204 * fwupd_result_add_guid:
205 * @result: A #FwupdResult
206 * @guid: the GUID, e.g. "2082b5e0-7a64-478a-b1b2-e3404fab6dad"
207 *
208 * Adds the GUID if it does not already exist.
209 *
210 * Since: 0.7.2
211 **/
212 void
213 fwupd_result_add_guid (FwupdResult *result, const gchar *guid)
214 {
215 FwupdResultPrivate *priv = GET_PRIVATE (result);
216 g_return_if_fail (FWUPD_IS_RESULT (result));
217 fwupd_device_add_guid (priv->device, guid);
218 }
219
220 /**
221 * fwupd_result_get_guid_default:
222 * @result: A #FwupdResult
223 *
224 * Gets the default GUID.
225 *
226 * Returns: the GUID, or %NULL if unset
227 *
228 * Since: 0.7.2
229 **/
230 const gchar *
231 fwupd_result_get_guid_default (FwupdResult *result)
232 {
233 FwupdResultPrivate *priv = GET_PRIVATE (result);
234 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
235 return fwupd_device_get_guid_default (priv->device);
236 }
237
238 /**
239 * fwupd_result_get_guid:
240 * @result: A #FwupdResult
241 *
242 * Gets the GUID.
243 *
244 * Returns: the GUID, or %NULL if unset
245 *
246 * This function has been deprecated since 0.7.2.
247 *
248 * Since: 0.7.0
249 **/
250 const gchar *
251 fwupd_result_get_guid (FwupdResult *result)
252 {
253 FwupdResultPrivate *priv = GET_PRIVATE (result);
254 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
255 return fwupd_device_get_guid_default (priv->device);
256 }
257
258 /**
259 * fwupd_result_set_guid:
260 * @result: A #FwupdResult
261 * @guid: the GUID, e.g. "2082b5e0-7a64-478a-b1b2-e3404fab6dad"
262 *
263 * Sets the GUID.
264 *
265 * This function has been deprecated since 0.7.2.
266 *
267 * Since: 0.7.0
268 **/
269 void
270 fwupd_result_set_guid (FwupdResult *result, const gchar *guid)
271 {
272 FwupdResultPrivate *priv = GET_PRIVATE (result);
273 fwupd_device_add_guid (priv->device, guid);
274 }
275
276 /**
277 * fwupd_result_get_device_name:
278 * @result: A #FwupdResult
279 *
280 * Gets the device name.
281 *
282 * Returns: the device name, or %NULL if unset
283 *
284 * Since: 0.7.0
285 **/
286 const gchar *
287 fwupd_result_get_device_name (FwupdResult *result)
288 {
289 FwupdResultPrivate *priv = GET_PRIVATE (result);
290 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
291 return fwupd_device_get_name (priv->device);
292 }
293
294 /**
295 * fwupd_result_set_device_name:
296 * @result: A #FwupdResult
297 * @device_name: the device update_name, e.g. "ColorHug2"
298 *
299 * Sets the device update_name.
300 *
301 * Since: 0.7.0
302 **/
303 void
304 fwupd_result_set_device_name (FwupdResult *result, const gchar *device_name)
305 {
306 FwupdResultPrivate *priv = GET_PRIVATE (result);
307 g_return_if_fail (FWUPD_IS_RESULT (result));
308 fwupd_device_set_name (priv->device, device_name);
309 }
310
311 /**
312 * fwupd_result_get_device_vendor:
313 * @result: A #FwupdResult
314 *
315 * Gets the device vendor.
316 *
317 * Returns: the device vendor, or %NULL if unset
318 *
319 * Since: 0.7.0
320 **/
321 const gchar *
322 fwupd_result_get_device_vendor (FwupdResult *result)
323 {
324 FwupdResultPrivate *priv = GET_PRIVATE (result);
325 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
326 return fwupd_device_get_vendor (priv->device);
327 }
328
329 /**
330 * fwupd_result_set_device_vendor:
331 * @result: A #FwupdResult
332 * @device_vendor: the description
333 *
334 * Sets the device vendor.
335 *
336 * Since: 0.7.0
337 **/
338 void
339 fwupd_result_set_device_vendor (FwupdResult *result, const gchar *device_vendor)
340 {
341 FwupdResultPrivate *priv = GET_PRIVATE (result);
342 g_return_if_fail (FWUPD_IS_RESULT (result));
343 fwupd_device_set_vendor (priv->device, device_vendor);
344 }
345
346 /**
347 * fwupd_result_get_device_description:
348 * @result: A #FwupdResult
349 *
350 * Gets the device description in AppStream markup format.
351 *
352 * Returns: the device description, or %NULL if unset
353 *
354 * Since: 0.7.0
355 **/
356 const gchar *
357 fwupd_result_get_device_description (FwupdResult *result)
358 {
359 FwupdResultPrivate *priv = GET_PRIVATE (result);
360 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
361 return fwupd_device_get_description (priv->device);
362 }
363
364 /**
365 * fwupd_result_set_device_description:
366 * @result: A #FwupdResult
367 * @device_description: the description in AppStream markup format
368 *
369 * Sets the device description.
370 *
371 * Since: 0.7.0
372 **/
373 void
374 fwupd_result_set_device_description (FwupdResult *result, const gchar *device_description)
375 {
376 FwupdResultPrivate *priv = GET_PRIVATE (result);
377 g_return_if_fail (FWUPD_IS_RESULT (result));
378 fwupd_device_set_description (priv->device, device_description);
379 }
380
381 /**
382 * fwupd_result_get_device_version:
383 * @result: A #FwupdResult
384 *
385 * Gets the device version.
386 *
387 * Returns: the device version, or %NULL if unset
388 *
389 * Since: 0.7.0
390 **/
391 const gchar *
392 fwupd_result_get_device_version (FwupdResult *result)
393 {
394 FwupdResultPrivate *priv = GET_PRIVATE (result);
395 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
396 return fwupd_device_get_version (priv->device);
397 }
398
399 /**
400 * fwupd_result_set_device_version:
401 * @result: A #FwupdResult
402 * @device_version: the device version, e.g. "1.2.3"
403 *
404 * Sets the device version.
405 *
406 * Since: 0.7.0
407 **/
408 void
409 fwupd_result_set_device_version (FwupdResult *result, const gchar *device_version)
410 {
411 FwupdResultPrivate *priv = GET_PRIVATE (result);
412 g_return_if_fail (FWUPD_IS_RESULT (result));
413 fwupd_device_set_version (priv->device, device_version);
414 }
415
416 /**
417 * fwupd_result_get_update_version:
418 * @result: A #FwupdResult
419 *
420 * Gets the update version.
421 *
422 * Returns: the update version, or %NULL if unset
423 *
424 * Since: 0.7.0
425 **/
426 const gchar *
427 fwupd_result_get_update_version (FwupdResult *result)
428 {
429 FwupdResultPrivate *priv = GET_PRIVATE (result);
430 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
431 return fwupd_release_get_version (priv->release);
432 }
433
434 /**
435 * fwupd_result_get_device_version_lowest:
436 * @result: A #FwupdResult
437 *
438 * Gets the lowest version of firmware the device will accept.
439 *
440 * Returns: the device version_lowest, or %NULL if unset
441 *
442 * Since: 0.7.0
443 **/
444 const gchar *
445 fwupd_result_get_device_version_lowest (FwupdResult *result)
446 {
447 FwupdResultPrivate *priv = GET_PRIVATE (result);
448 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
449 return fwupd_device_get_version_lowest (priv->device);
450 }
451
452 /**
453 * fwupd_result_set_device_version_lowest:
454 * @result: A #FwupdResult
455 * @device_version_lowest: the description
456 *
457 * Sets the lowest version of firmware the device will accept.
458 *
459 * Since: 0.7.0
460 **/
461 void
462 fwupd_result_set_device_version_lowest (FwupdResult *result, const gchar *device_version_lowest)
463 {
464 FwupdResultPrivate *priv = GET_PRIVATE (result);
465 g_return_if_fail (FWUPD_IS_RESULT (result));
466 fwupd_device_set_version_lowest (priv->device, device_version_lowest);
467 }
468
469 /**
470 * fwupd_result_get_device_version_bootloader:
471 * @result: A #FwupdResult
472 *
473 * Gets the version of the bootloader.
474 *
475 * Returns: the device version_bootloader, or %NULL if unset
476 *
477 * Since: 0.8.0
478 **/
479 const gchar *
480 fwupd_result_get_device_version_bootloader (FwupdResult *result)
481 {
482 FwupdResultPrivate *priv = GET_PRIVATE (result);
483 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
484 return fwupd_device_get_version_bootloader (priv->device);
485 }
486
487 /**
488 * fwupd_result_set_device_version_bootloader:
489 * @result: A #FwupdResult
490 * @device_version_bootloader: the description
491 *
492 * Sets the bootloader version.
493 *
494 * Since: 0.8.0
495 **/
496 void
497 fwupd_result_set_device_version_bootloader (FwupdResult *result,
498 const gchar *device_version_bootloader)
499 {
500 FwupdResultPrivate *priv = GET_PRIVATE (result);
501 g_return_if_fail (FWUPD_IS_RESULT (result));
502 fwupd_device_set_version_bootloader (priv->device, device_version_bootloader);
503 }
504
505 /**
506 * fwupd_result_device_get_flashes_left:
507 * @result: A #FwupdResult
508 *
509 * Gets the number of flash cycles left on the device
510 *
511 * Returns: the flash cycles left, or %NULL if unset
512 *
513 * Since: 0.7.1
514 **/
515 guint32
516 fwupd_result_get_device_flashes_left (FwupdResult *result)
517 {
518 FwupdResultPrivate *priv = GET_PRIVATE (result);
519 g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
520 return fwupd_device_get_flashes_left (priv->device);
521 }
522
523 /**
524 * fwupd_result_device_set_flashes_left:
525 * @result: A #FwupdResult
526 * @flashes_left: the description
527 *
528 * Sets the number of flash cycles left on the device
529 *
530 * Since: 0.7.1
531 **/
532 void
533 fwupd_result_set_device_flashes_left (FwupdResult *result, guint32 flashes_left)
534 {
535 FwupdResultPrivate *priv = GET_PRIVATE (result);
536 g_return_if_fail (FWUPD_IS_RESULT (result));
537 fwupd_device_set_flashes_left (priv->device, flashes_left);
538 }
539
540 /**
541 * fwupd_result_set_update_version:
542 * @result: A #FwupdResult
543 * @update_version: the update version, e.g. "1.2.4"
544 *
545 * Sets the update version.
546 *
547 * Since: 0.7.0
548 **/
549 void
550 fwupd_result_set_update_version (FwupdResult *result, const gchar *update_version)
551 {
552 FwupdResultPrivate *priv = GET_PRIVATE (result);
553 g_return_if_fail (FWUPD_IS_RESULT (result));
554 fwupd_release_set_version (priv->release, update_version);
555 }
556
557 /**
558 * fwupd_result_get_update_filename:
559 * @result: A #FwupdResult
560 *
561 * Gets the update filename.
562 *
563 * Returns: the update filename, or %NULL if unset
564 *
565 * Since: 0.7.0
566 **/
567 const gchar *
568 fwupd_result_get_update_filename (FwupdResult *result)
569 {
570 FwupdResultPrivate *priv = GET_PRIVATE (result);
571 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
572 return fwupd_release_get_filename (priv->release);
573 }
574
575 /**
576 * fwupd_result_set_update_filename:
577 * @result: A #FwupdResult
578 * @update_filename: the update filename on disk
579 *
580 * Sets the update filename.
581 *
582 * Since: 0.7.0
583 **/
584 void
585 fwupd_result_set_update_filename (FwupdResult *result, const gchar *update_filename)
586 {
587 FwupdResultPrivate *priv = GET_PRIVATE (result);
588 g_return_if_fail (FWUPD_IS_RESULT (result));
589 fwupd_release_set_filename (priv->release, update_filename);
590 }
591
592 /**
593 * fwupd_result_get_update_state:
594 * @result: A #FwupdResult
595 *
596 * Gets the update state.
597 *
598 * Returns: the update state, or %FWUPD_UPDATE_STATE_UNKNOWN if unset
599 *
600 * Since: 0.7.0
601 **/
602 FwupdUpdateState
603 fwupd_result_get_update_state (FwupdResult *result)
604 {
605 FwupdResultPrivate *priv = GET_PRIVATE (result);
606 g_return_val_if_fail (FWUPD_IS_RESULT (result), FWUPD_UPDATE_STATE_UNKNOWN);
607 return priv->update_state;
608 }
609
610 /**
611 * fwupd_result_set_update_state:
612 * @result: A #FwupdResult
613 * @update_state: the state, e.g. %FWUPD_UPDATE_STATE_PENDING
614 *
615 * Sets the update state.
616 *
617 * Since: 0.7.0
618 **/
619 void
620 fwupd_result_set_update_state (FwupdResult *result, FwupdUpdateState update_state)
621 {
622 FwupdResultPrivate *priv = GET_PRIVATE (result);
623 g_return_if_fail (FWUPD_IS_RESULT (result));
624 priv->update_state = update_state;
625 }
626
627 /**
628 * fwupd_result_get_update_checksum:
629 * @result: A #FwupdResult
630 *
631 * Gets the update checksum.
632 *
633 * Returns: the update checksum, or %NULL if unset
634 *
635 * Since: 0.7.0
636 **/
637 const gchar *
638 fwupd_result_get_update_checksum (FwupdResult *result)
639 {
640 FwupdResultPrivate *priv = GET_PRIVATE (result);
641 GPtrArray *checksums;
642 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
643 checksums = fwupd_release_get_checksums (priv->release);
644 for (guint i = 0; i < checksums->len; i++) {
645 const gchar *checksum = g_ptr_array_index (checksums, i);
646 if (fwupd_checksum_guess_kind (checksum) == G_CHECKSUM_SHA1)
647 return checksum;
648 }
649 return NULL;
650 }
651
652 /**
653 * fwupd_result_set_update_checksum:
654 * @result: A #FwupdResult
655 * @update_checksum: the update checksum
656 *
657 * Sets the update checksum.
658 *
659 * Since: 0.7.0
660 **/
661 void
662 fwupd_result_set_update_checksum (FwupdResult *result, const gchar *update_checksum)
663 {
664 FwupdResultPrivate *priv = GET_PRIVATE (result);
665 g_return_if_fail (FWUPD_IS_RESULT (result));
666 fwupd_release_add_checksum (priv->release, update_checksum);
667 }
668
669 /**
670 * fwupd_result_get_update_checksum_kind:
671 * @result: A #FwupdResult
672 *
673 * Gets the update checkum kind.
674 *
675 * Returns: the #GChecksumType
676 *
677 * Since: 0.7.0
678 **/
679 GChecksumType
680 fwupd_result_get_update_checksum_kind (FwupdResult *result)
681 {
682 return G_CHECKSUM_SHA1;
683 }
684
685 /**
686 * fwupd_result_set_update_checksum_kind:
687 * @result: A #FwupdResult
688 * @checkum_kind: the checksum kind, e.g. %G_CHECKSUM_SHA1
689 *
690 * Sets the update checkum kind.
691 *
692 * Since: 0.7.0
693 **/
694 void
695 fwupd_result_set_update_checksum_kind (FwupdResult *result, GChecksumType checkum_kind)
696 {
697 }
698
699 /**
700 * fwupd_result_get_update_uri:
701 * @result: A #FwupdResult
702 *
703 * Gets the update uri.
704 *
705 * Returns: the update uri, or %NULL if unset
706 *
707 * Since: 0.7.0
708 **/
709 const gchar *
710 fwupd_result_get_update_uri (FwupdResult *result)
711 {
712 FwupdResultPrivate *priv = GET_PRIVATE (result);
713 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
714 return fwupd_release_get_uri (priv->release);
715 }
716
717 /**
718 * fwupd_result_set_update_uri:
719 * @result: A #FwupdResult
720 * @update_uri: the update URI
721 *
722 * Sets the update uri, i.e. where you can download the firmware from.
723 *
724 * Since: 0.7.0
725 **/
726 void
727 fwupd_result_set_update_uri (FwupdResult *result, const gchar *update_uri)
728 {
729 FwupdResultPrivate *priv = GET_PRIVATE (result);
730 g_return_if_fail (FWUPD_IS_RESULT (result));
731 fwupd_release_set_uri (priv->release, update_uri);
732 }
733
734 /**
735 * fwupd_result_get_update_homepage:
736 * @result: A #FwupdResult
737 *
738 * Gets the update homepage.
739 *
740 * Returns: the update homepage, or %NULL if unset
741 *
742 * Since: 0.7.0
743 **/
744 const gchar *
745 fwupd_result_get_update_homepage (FwupdResult *result)
746 {
747 FwupdResultPrivate *priv = GET_PRIVATE (result);
748 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
749 return fwupd_release_get_homepage (priv->release);
750 }
751
752 /**
753 * fwupd_result_set_update_homepage:
754 * @result: A #FwupdResult
755 * @update_homepage: the description
756 *
757 * Sets the update homepage.
758 *
759 * Since: 0.7.0
760 **/
761 void
762 fwupd_result_set_update_homepage (FwupdResult *result, const gchar *update_homepage)
763 {
764 FwupdResultPrivate *priv = GET_PRIVATE (result);
765 g_return_if_fail (FWUPD_IS_RESULT (result));
766 fwupd_release_set_homepage (priv->release, update_homepage);
767 }
768
769 /**
770 * fwupd_result_get_update_description:
771 * @result: A #FwupdResult
772 *
773 * Gets the update description in AppStream markup format.
774 *
775 * Returns: the update description, or %NULL if unset
776 *
777 * Since: 0.7.0
778 **/
779 const gchar *
780 fwupd_result_get_update_description (FwupdResult *result)
781 {
782 FwupdResultPrivate *priv = GET_PRIVATE (result);
783 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
784 return fwupd_release_get_description (priv->release);
785 }
786
787 /**
788 * fwupd_result_set_update_description:
789 * @result: A #FwupdResult
790 * @update_description: the update description in AppStream markup format
791 *
792 * Sets the update description.
793 *
794 * Since: 0.7.0
795 **/
796 void
797 fwupd_result_set_update_description (FwupdResult *result, const gchar *update_description)
798 {
799 FwupdResultPrivate *priv = GET_PRIVATE (result);
800 g_return_if_fail (FWUPD_IS_RESULT (result));
801 fwupd_release_set_description (priv->release, update_description);
802 }
803
804 /**
805 * fwupd_result_get_update_id:
806 * @result: A #FwupdResult
807 *
808 * Gets the update id.
809 *
810 * Returns: the update id, or %NULL if unset
811 *
812 * Since: 0.7.0
813 **/
814 const gchar *
815 fwupd_result_get_update_id (FwupdResult *result)
816 {
817 FwupdResultPrivate *priv = GET_PRIVATE (result);
818 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
819 return fwupd_release_get_appstream_id (priv->release);
820 }
821
822 /**
823 * fwupd_result_set_update_id:
824 * @result: A #FwupdResult
825 * @update_id: the AppStream component ID, e.g. "org.hughski.ColorHug2.firmware"
826 *
827 * Sets the update id.
828 *
829 * Since: 0.7.0
830 **/
831 void
832 fwupd_result_set_update_id (FwupdResult *result, const gchar *update_id)
833 {
834 FwupdResultPrivate *priv = GET_PRIVATE (result);
835 g_return_if_fail (FWUPD_IS_RESULT (result));
836 fwupd_release_set_appstream_id (priv->release, update_id);
837 }
838
839 /**
840 * fwupd_result_get_update_size:
841 * @result: A #FwupdResult
842 *
843 * Gets the update size.
844 *
845 * Returns: the update size in bytes, or 0 if unset
846 *
847 * Since: 0.7.0
848 **/
849 guint64
850 fwupd_result_get_update_size (FwupdResult *result)
851 {
852 FwupdResultPrivate *priv = GET_PRIVATE (result);
853 g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
854 return fwupd_release_get_size (priv->release);
855 }
856
857 /**
858 * fwupd_result_set_update_size:
859 * @result: A #FwupdResult
860 * @update_size: the update size in bytes
861 *
862 * Sets the update size.
863 *
864 * Since: 0.7.0
865 **/
866 void
867 fwupd_result_set_update_size (FwupdResult *result, guint64 update_size)
868 {
869 FwupdResultPrivate *priv = GET_PRIVATE (result);
870 g_return_if_fail (FWUPD_IS_RESULT (result));
871 fwupd_release_set_size (priv->release, update_size);
872 }
873
874 /**
875 * fwupd_result_get_device_checksum:
876 * @result: A #FwupdResult
877 *
878 * Gets the device checksum.
879 *
880 * Returns: the device checksum, or %NULL if unset
881 *
882 * Since: 0.7.0
883 **/
884 const gchar *
885 fwupd_result_get_device_checksum (FwupdResult *result)
886 {
887 FwupdResultPrivate *priv = GET_PRIVATE (result);
888 GPtrArray *checksums;
889 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
890 checksums = fwupd_device_get_checksums (priv->device);
891 for (guint i = 0; i < checksums->len; i++) {
892 const gchar *checksum = g_ptr_array_index (checksums, i);
893 if (fwupd_checksum_guess_kind (checksum) == G_CHECKSUM_SHA1)
894 return checksum;
895 }
896 return NULL;
897 }
898
899 /**
900 * fwupd_result_set_device_checksum:
901 * @result: A #FwupdResult
902 * @device_checksum: the device checksum
903 *
904 * Sets the device checksum, i.e. what is on the device right now.
905 *
906 * Since: 0.7.0
907 **/
908 void
909 fwupd_result_set_device_checksum (FwupdResult *result, const gchar *device_checksum)
910 {
911 FwupdResultPrivate *priv = GET_PRIVATE (result);
912 g_return_if_fail (FWUPD_IS_RESULT (result));
913 fwupd_device_add_checksum (priv->device, device_checksum);
914 }
915
916 /**
917 * fwupd_result_get_device_checksum_kind:
918 * @result: A #FwupdResult
919 *
920 * Gets the device checkum kind.
921 *
922 * Returns: the #GChecksumType
923 *
924 * Since: 0.7.0
925 **/
926 GChecksumType
927 fwupd_result_get_device_checksum_kind (FwupdResult *result)
928 {
929 return G_CHECKSUM_SHA1;
930 }
931
932 /**
933 * fwupd_result_set_device_checksum_kind:
934 * @result: A #FwupdResult
935 * @checkum_kind: the checksum kind, e.g. %G_CHECKSUM_SHA1
936 *
937 * Sets the device checkum kind.
938 *
939 * Since: 0.7.0
940 **/
941 void
942 fwupd_result_set_device_checksum_kind (FwupdResult *result, GChecksumType checkum_kind)
943 {
944 }
945
946 /**
947 * fwupd_result_get_update_summary:
948 * @result: A #FwupdResult
949 *
950 * Gets the update summary.
951 *
952 * Returns: the update summary, or %NULL if unset
953 *
954 * Since: 0.7.0
955 **/
956 const gchar *
957 fwupd_result_get_update_summary (FwupdResult *result)
958 {
959 FwupdResultPrivate *priv = GET_PRIVATE (result);
960 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
961 return fwupd_release_get_summary (priv->release);
962 }
963
964 /**
965 * fwupd_result_set_update_summary:
966 * @result: A #FwupdResult
967 * @update_summary: the update one line summary
968 *
969 * Sets the update summary.
970 *
971 * Since: 0.7.0
972 **/
973 void
974 fwupd_result_set_update_summary (FwupdResult *result, const gchar *update_summary)
975 {
976 FwupdResultPrivate *priv = GET_PRIVATE (result);
977 g_return_if_fail (FWUPD_IS_RESULT (result));
978 fwupd_release_set_summary (priv->release, update_summary);
979 }
980
981 /**
982 * fwupd_result_get_device_provider:
983 * @result: A #FwupdResult
984 *
985 * Gets the device provider.
986 *
987 * Returns: the device provider, or %NULL if unset
988 *
989 * Since: 0.7.0
990 **/
991 const gchar *
992 fwupd_result_get_device_provider (FwupdResult *result)
993 {
994 FwupdResultPrivate *priv = GET_PRIVATE (result);
995 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
996 return fwupd_device_get_provider (priv->device);
997 }
998
999 /**
1000 * fwupd_result_set_device_provider:
1001 * @result: A #FwupdResult
1002 * @device_provider: the provider name, e.g. "colorhug"
1003 *
1004 * Sets the device provider.
1005 *
1006 * Since: 0.7.0
1007 **/
1008 void
1009 fwupd_result_set_device_provider (FwupdResult *result, const gchar *device_provider)
1010 {
1011 FwupdResultPrivate *priv = GET_PRIVATE (result);
1012 g_return_if_fail (FWUPD_IS_RESULT (result));
1013 fwupd_device_set_provider (priv->device, device_provider);
1014 }
1015
1016 /**
1017 * fwupd_result_get_update_error:
1018 * @result: A #FwupdResult
1019 *
1020 * Gets the update error.
1021 *
1022 * Returns: the update error, or %NULL if unset
1023 *
1024 * Since: 0.7.0
1025 **/
1026 const gchar *
1027 fwupd_result_get_update_error (FwupdResult *result)
1028 {
1029 FwupdResultPrivate *priv = GET_PRIVATE (result);
1030 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
1031 return priv->update_error;
1032 }
1033
1034 /**
1035 * fwupd_result_set_update_error:
1036 * @result: A #FwupdResult
1037 * @update_error: the update error string
1038 *
1039 * Sets the update error.
1040 *
1041 * Since: 0.7.0
1042 **/
1043 void
1044 fwupd_result_set_update_error (FwupdResult *result, const gchar *update_error)
1045 {
1046 FwupdResultPrivate *priv = GET_PRIVATE (result);
1047 g_return_if_fail (FWUPD_IS_RESULT (result));
1048 g_free (priv->update_error);
1049 priv->update_error = g_strdup (update_error);
1050 }
1051
1052 /**
1053 * fwupd_result_get_update_trust_flags:
1054 * @result: A #FwupdResult
1055 *
1056 * Gets the update trust_flags.
1057 *
1058 * Returns: the #FwupdTrustFlags, or 0 if unset
1059 *
1060 * Since: 0.7.0
1061 **/
1062 FwupdTrustFlags
1063 fwupd_result_get_update_trust_flags (FwupdResult *result)
1064 {
1065 FwupdResultPrivate *priv = GET_PRIVATE (result);
1066 g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
1067 return priv->update_trust_flags;
1068 }
1069
1070 /**
1071 * fwupd_result_set_update_trust_flags:
1072 * @result: A #FwupdResult
1073 * @trust_flags: the trust flags, e.g. %FWUPD_TRUST_FLAG_PAYLOAD
1074 *
1075 * Sets the update trust_flags.
1076 *
1077 * Since: 0.7.0
1078 **/
1079 void
1080 fwupd_result_set_update_trust_flags (FwupdResult *result, FwupdTrustFlags trust_flags)
1081 {
1082 FwupdResultPrivate *priv = GET_PRIVATE (result);
1083 g_return_if_fail (FWUPD_IS_RESULT (result));
1084 priv->update_trust_flags = trust_flags;
1085 }
1086
1087 /**
1088 * fwupd_result_get_update_vendor:
1089 * @result: A #FwupdResult
1090 *
1091 * Gets the update vendor.
1092 *
1093 * Returns: the update vendor, or %NULL if unset
1094 *
1095 * Since: 0.7.0
1096 **/
1097 const gchar *
1098 fwupd_result_get_update_vendor (FwupdResult *result)
1099 {
1100 FwupdResultPrivate *priv = GET_PRIVATE (result);
1101 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
1102 return fwupd_release_get_vendor (priv->release);
1103 }
1104
1105 /**
1106 * fwupd_result_set_update_vendor:
1107 * @result: A #FwupdResult
1108 * @update_vendor: the vendor name, e.g. "Hughski Limited"
1109 *
1110 * Sets the update vendor.
1111 *
1112 * Since: 0.7.0
1113 **/
1114 void
1115 fwupd_result_set_update_vendor (FwupdResult *result, const gchar *update_vendor)
1116 {
1117 FwupdResultPrivate *priv = GET_PRIVATE (result);
1118 g_return_if_fail (FWUPD_IS_RESULT (result));
1119 fwupd_release_set_vendor (priv->release, update_vendor);
1120 }
1121
1122 /**
1123 * fwupd_result_get_update_license:
1124 * @result: A #FwupdResult
1125 *
1126 * Gets the update license.
1127 *
1128 * Returns: the update license, or %NULL if unset
1129 *
1130 * Since: 0.7.0
1131 **/
1132 const gchar *
1133 fwupd_result_get_update_license (FwupdResult *result)
1134 {
1135 FwupdResultPrivate *priv = GET_PRIVATE (result);
1136 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
1137 return fwupd_release_get_license (priv->release);
1138 }
1139
1140 /**
1141 * fwupd_result_set_update_license:
1142 * @result: A #FwupdResult
1143 * @update_license: the description
1144 *
1145 * Sets the update license.
1146 *
1147 * Since: 0.7.0
1148 **/
1149 void
1150 fwupd_result_set_update_license (FwupdResult *result, const gchar *update_license)
1151 {
1152 FwupdResultPrivate *priv = GET_PRIVATE (result);
1153 g_return_if_fail (FWUPD_IS_RESULT (result));
1154 fwupd_release_set_license (priv->release, update_license);
1155 }
1156
1157 /**
1158 * fwupd_result_get_update_name:
1159 * @result: A #FwupdResult
1160 *
1161 * Gets the update name.
1162 *
1163 * Returns: the update name, or %NULL if unset
1164 *
1165 * Since: 0.7.0
1166 **/
1167 const gchar *
1168 fwupd_result_get_update_name (FwupdResult *result)
1169 {
1170 FwupdResultPrivate *priv = GET_PRIVATE (result);
1171 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
1172 return fwupd_release_get_name (priv->release);
1173 }
1174
1175 /**
1176 * fwupd_result_set_update_name:
1177 * @result: A #FwupdResult
1178 * @update_name: the description
1179 *
1180 * Sets the update name.
1181 *
1182 * Since: 0.7.0
1183 **/
1184 void
1185 fwupd_result_set_update_name (FwupdResult *result, const gchar *update_name)
1186 {
1187 FwupdResultPrivate *priv = GET_PRIVATE (result);
1188 g_return_if_fail (FWUPD_IS_RESULT (result));
1189 fwupd_release_set_name (priv->release, update_name);
1190 }
1191
1192 /**
1193 * fwupd_result_get_device_flags:
1194 * @result: A #FwupdResult
1195 *
1196 * Gets the device flags.
1197 *
1198 * Returns: the device flags, or 0 if unset
1199 *
1200 * Since: 0.7.0
1201 **/
1202 guint64
1203 fwupd_result_get_device_flags (FwupdResult *result)
1204 {
1205 FwupdResultPrivate *priv = GET_PRIVATE (result);
1206 g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
1207 return fwupd_device_get_flags (priv->device);
1208 }
1209
1210 /**
1211 * fwupd_result_set_device_flags:
1212 * @result: A #FwupdResult
1213 * @device_flags: the device flags, e.g. %FWUPD_DEVICE_FLAG_REQUIRE_AC
1214 *
1215 * Sets the device flags.
1216 *
1217 * Since: 0.7.0
1218 **/
1219 void
1220 fwupd_result_set_device_flags (FwupdResult *result, guint64 device_flags)
1221 {
1222 FwupdResultPrivate *priv = GET_PRIVATE (result);
1223 g_return_if_fail (FWUPD_IS_RESULT (result));
1224 fwupd_device_set_flags (priv->device, device_flags);
1225 }
1226
1227 /**
1228 * fwupd_result_add_device_flag:
1229 * @result: A #FwupdResult
1230 * @flag: the #FwupdDeviceFlags
1231 *
1232 * Adds a specific device flag to the result.
1233 *
1234 * Since: 0.7.0
1235 **/
1236 void
1237 fwupd_result_add_device_flag (FwupdResult *result, FwupdDeviceFlags flag)
1238 {
1239 FwupdResultPrivate *priv = GET_PRIVATE (result);
1240 g_return_if_fail (FWUPD_IS_RESULT (result));
1241 fwupd_device_add_flag (priv->device, flag);
1242 }
1243
1244 /**
1245 * fwupd_result_remove_device_flag:
1246 * @result: A #FwupdResult
1247 * @flag: the #FwupdDeviceFlags
1248 *
1249 * Removes a specific device flag from the result.
1250 *
1251 * Since: 0.7.3
1252 **/
1253 void
1254 fwupd_result_remove_device_flag (FwupdResult *result, FwupdDeviceFlags flag)
1255 {
1256 FwupdResultPrivate *priv = GET_PRIVATE (result);
1257 g_return_if_fail (FWUPD_IS_RESULT (result));
1258 fwupd_device_remove_flag (priv->device, flag);
1259 }
1260
1261 /**
1262 * fwupd_result_has_device_flag:
1263 * @result: A #FwupdResult
1264 * @flag: the #FwupdDeviceFlags
1265 *
1266 * Finds if the device has a specific device flag.
1267 *
1268 * Returns: %TRUE if the flag is set
1269 *
1270 * Since: 0.7.0
1271 **/
1272 gboolean
1273 fwupd_result_has_device_flag (FwupdResult *result, FwupdDeviceFlags flag)
1274 {
1275 FwupdResultPrivate *priv = GET_PRIVATE (result);
1276 g_return_val_if_fail (FWUPD_IS_RESULT (result), FALSE);
1277 return fwupd_device_has_flag (priv->device, flag);
1278 }
1279
1280 /**
1281 * fwupd_result_get_device_created:
1282 * @result: A #FwupdResult
1283 *
1284 * Gets when the result was device_created.
1285 *
1286 * Returns: the UNIX time, or 0 if unset
1287 *
1288 * Since: 0.7.0
1289 **/
1290 guint64
1291 fwupd_result_get_device_created (FwupdResult *result)
1292 {
1293 FwupdResultPrivate *priv = GET_PRIVATE (result);
1294 g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
1295 return fwupd_device_get_created (priv->device);
1296 }
1297
1298
1299 /**
1300 * fwupd_result_set_device_created:
1301 * @result: A #FwupdResult
1302 * @device_created: the UNIX time
1303 *
1304 * Sets when the result was device_created.
1305 *
1306 * Since: 0.7.0
1307 **/
1308 void
1309 fwupd_result_set_device_created (FwupdResult *result, guint64 device_created)
1310 {
1311 FwupdResultPrivate *priv = GET_PRIVATE (result);
1312 g_return_if_fail (FWUPD_IS_RESULT (result));
1313 fwupd_device_set_created (priv->device, device_created);
1314 }
1315
1316 /**
1317 * fwupd_result_get_device_modified:
1318 * @result: A #FwupdResult
1319 *
1320 * Gets when the result was device_modified.
1321 *
1322 * Returns: the UNIX time, or 0 if unset
1323 *
1324 * Since: 0.7.0
1325 **/
1326 guint64
1327 fwupd_result_get_device_modified (FwupdResult *result)
1328 {
1329 FwupdResultPrivate *priv = GET_PRIVATE (result);
1330 g_return_val_if_fail (FWUPD_IS_RESULT (result), 0);
1331 return fwupd_device_get_modified (priv->device);
1332 }
1333
1334 /**
1335 * fwupd_result_set_device_modified:
1336 * @result: A #FwupdResult
1337 * @device_modified: the UNIX time
1338 *
1339 * Sets when the result was device_modified.
1340 *
1341 * Since: 0.7.0
1342 **/
1343 void
1344 fwupd_result_set_device_modified (FwupdResult *result, guint64 device_modified)
1345 {
1346 FwupdResultPrivate *priv = GET_PRIVATE (result);
1347 g_return_if_fail (FWUPD_IS_RESULT (result));
1348 fwupd_device_set_modified (priv->device, device_modified);
1349 }
1350
1351 /**
1352 * fwupd_result_to_data:
1353 * @result: A #FwupdResult
1354 * @type_string: The Gvariant type string, e.g. "{sa{sv}}" or "(a{sv})"
1355 *
1356 * Creates a GVariant from the result data.
1357 *
1358 * Returns: the GVariant, or %NULL for error
1359 *
1360 * Since: 0.7.0
1361 **/
1362 GVariant *
1363 fwupd_result_to_data (FwupdResult *result, const gchar *type_string)
1364 {
1365 FwupdResultPrivate *priv = GET_PRIVATE (result);
1366 GVariantBuilder builder;
1367
1368 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
1369 g_return_val_if_fail (type_string != NULL, NULL);
1370
1371 /* create an array with all the metadata in */
1372 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
1373 if (priv->unique_id != NULL) {
1374 g_variant_builder_add (&builder, "{sv}",
1375 FWUPD_RESULT_KEY_UNIQUE_ID,
1376 g_variant_new_string (priv->unique_id));
1377 }
1378 if (priv->update_error != NULL) {
1379 g_variant_builder_add (&builder, "{sv}",
1380 FWUPD_RESULT_KEY_UPDATE_ERROR,
1381 g_variant_new_string (priv->update_error));
1382 }
1383 if (priv->update_state != FWUPD_UPDATE_STATE_UNKNOWN) {
1384 g_variant_builder_add (&builder, "{sv}",
1385 FWUPD_RESULT_KEY_UPDATE_STATE,
1386 g_variant_new_uint32 (priv->update_state));
1387 }
1388 if (priv->update_trust_flags != 0) {
1389 g_variant_builder_add (&builder, "{sv}",
1390 FWUPD_RESULT_KEY_UPDATE_TRUST_FLAGS,
1391 g_variant_new_uint64 (priv->update_trust_flags));
1392 }
1393
1394 /* device and release objects */
1395 fwupd_release_to_variant_builder (priv->release, &builder);
1396 fwupd_device_to_variant_builder (priv->device, &builder);
1397
1398 /* supported types */
1399 if (g_strcmp0 (type_string, "{sa{sv}}") == 0) {
1400 const gchar *device_id = fwupd_device_get_id (priv->device);
1401 if (device_id == NULL)
1402 device_id = "";
1403 return g_variant_new ("{sa{sv}}", device_id, &builder);
1404 }
1405 if (g_strcmp0 (type_string, "(a{sv})") == 0)
1406 return g_variant_new ("(a{sv})", &builder);
1407 return NULL;
1408 }
1409
1410 static void
1411 fwupd_result_from_key_value (FwupdResult *result, const gchar *key, GVariant *value)
1412 {
1413 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UNIQUE_ID) == 0) {
1414 fwupd_result_set_unique_id (result, g_variant_get_string (value, NULL));
1415 return;
1416 }
1417 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_TRUST_FLAGS) == 0) {
1418 fwupd_result_set_update_trust_flags (result, g_variant_get_uint64 (value));
1419 return;
1420 }
1421 if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_STATE) == 0) {
1422 /* old daemon version and new client */
1423 if (g_strcmp0 (g_variant_get_type_string (value), "s") == 0) {
1424 FwupdUpdateState tmp;
1425 tmp = fwupd_update_state_from_string (g_variant_get_string (value, NULL));
1426 fwupd_result_set_update_state (result, tmp);
1427 } else {
1428 fwupd_result_set_update_state (result, g_variant_get_uint32 (value));
1429 }
1430 return;
1431 }
1432 }
1433
1434 static void
1435 fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value)
1436 {
1437 /* ignore */
1438 if (key == NULL || value == NULL)
1439 return;
1440 g_string_append_printf (str, " %s: ", key);
1441 for (gsize i = strlen (key); i < 20; i++)
1442 g_string_append (str, " ");
1443 g_string_append_printf (str, "%s\n", value);
1444 }
1445
1446 static void
1447 fwupd_pad_kv_ups (GString *str, const gchar *key, FwupdUpdateState value)
1448 {
1449 if (value == FWUPD_UPDATE_STATE_UNKNOWN)
1450 return;
1451 fwupd_pad_kv_str (str, key, fwupd_update_state_to_string (value));
1452 }
1453
1454 static void
1455 fwupd_pad_kv_tfl (GString *str, const gchar *key, FwupdTrustFlags trust_flags)
1456 {
1457 guint i;
1458 g_autoptr(GString) tmp = NULL;
1459
1460 tmp = g_string_new ("");
1461 for (i = 1; i < FWUPD_TRUST_FLAG_LAST; i *= 2) {
1462 if ((trust_flags & i) == 0)
1463 continue;
1464 g_string_append_printf (tmp, "%s|",
1465 fwupd_trust_flag_to_string (i));
1466 }
1467 if (tmp->len == 0) {
1468 g_string_append (tmp, fwupd_trust_flag_to_string (0));
1469 } else {
1470 g_string_truncate (tmp, tmp->len - 1);
1471 }
1472 fwupd_pad_kv_str (str, key, tmp->str);
1473 }
1474
1475 /**
1476 * fwupd_result_to_string:
1477 * @result: A #FwupdResult
1478 *
1479 * Builds a text representation of the object.
1480 *
1481 * Returns: text, or %NULL for invalid
1482 *
1483 * Since: 0.7.0
1484 **/
1485 gchar *
1486 fwupd_result_to_string (FwupdResult *result)
1487 {
1488 FwupdResultPrivate *priv = GET_PRIVATE (result);
1489 GString *str;
1490 g_autofree gchar *device_str = NULL;
1491 g_autofree gchar *release_str = NULL;
1492
1493 g_return_val_if_fail (FWUPD_IS_RESULT (result), NULL);
1494
1495 str = g_string_new ("");
1496
1497 /* device and release */
1498 device_str = fwupd_device_to_string (priv->device);
1499 g_string_append (str, device_str);
1500 release_str = fwupd_release_to_string (priv->release);
1501 g_string_append (str, release_str);
1502 if (fwupd_release_get_version (priv->release) != NULL)
1503 fwupd_pad_kv_tfl (str, FWUPD_RESULT_KEY_UPDATE_TRUST_FLAGS, priv->update_trust_flags);
1504
1505 /* device */
1506 fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UNIQUE_ID, priv->unique_id);
1507 fwupd_pad_kv_ups (str, FWUPD_RESULT_KEY_UPDATE_STATE, priv->update_state);
1508
1509 return g_string_free (str, FALSE);
1510 }
1511
1512 static void
1513 fwupd_result_get_property (GObject *object, guint prop_id,
1514 GValue *value, GParamSpec *pspec)
1515 {
1516 FwupdResult *result = FWUPD_RESULT (object);
1517 FwupdResultPrivate *priv = GET_PRIVATE (result);
1518
1519 switch (prop_id) {
1520 case PROP_DEVICE_ID:
1521 g_value_set_string (value, fwupd_device_get_id (priv->device));
1522 break;
1523 case PROP_UNIQUE_ID:
1524 g_value_set_string (value, priv->unique_id);
1525 break;
1526 default:
1527 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1528 break;
1529 }
1530 }
1531
1532 static void
1533 fwupd_result_set_property (GObject *object, guint prop_id,
1534 const GValue *value, GParamSpec *pspec)
1535 {
1536 FwupdResult *result = FWUPD_RESULT (object);
1537 FwupdResultPrivate *priv = GET_PRIVATE (result);
1538
1539 switch (prop_id) {
1540 case PROP_DEVICE_ID:
1541 fwupd_device_set_id (priv->device, g_value_get_string (value));
1542 break;
1543 case PROP_UNIQUE_ID:
1544 g_free (priv->unique_id);
1545 priv->unique_id = g_strdup (g_value_get_string (value));
1546 break;
1547 default:
1548 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1549 break;
1550 }
1551 }
1552
1553 static void
1554 fwupd_result_class_init (FwupdResultClass *klass)
1555 {
1556 GParamSpec *pspec;
1557 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1558 object_class->finalize = fwupd_result_finalize;
1559 object_class->get_property = fwupd_result_get_property;
1560 object_class->set_property = fwupd_result_set_property;
1561
1562 /**
1563 * FwupdResult:device-id:
1564 *
1565 * The device ID for this result.
1566 *
1567 * Since: 0.7.0
1568 */
1569 pspec = g_param_spec_string ("device-id", NULL, NULL,
1570 NULL,
1571 G_PARAM_READWRITE);
1572 g_object_class_install_property (object_class, PROP_DEVICE_ID, pspec);
1573 }
1574
1575 static void
1576 fwupd_result_init (FwupdResult *result)
1577 {
1578 FwupdResultPrivate *priv = GET_PRIVATE (result);
1579 priv->release = fwupd_release_new ();
1580 priv->device = fwupd_device_new ();
1581 }
1582
1583 static void
1584 fwupd_result_finalize (GObject *object)
1585 {
1586 FwupdResult *result = FWUPD_RESULT (object);
1587 FwupdResultPrivate *priv = GET_PRIVATE (result);
1588
1589 g_object_unref (priv->device);
1590 g_object_unref (priv->release);
1591 g_free (priv->unique_id);
1592 g_free (priv->update_error);
1593
1594 G_OBJECT_CLASS (fwupd_result_parent_class)->finalize (object);
1595 }
1596
1597 static void
1598 fwupd_result_from_variant_iter (FwupdResult *result, GVariantIter *iter)
1599 {
1600 FwupdResultPrivate *priv = GET_PRIVATE (result);
1601 GVariant *value;
1602 const gchar *key;
1603 while (g_variant_iter_next (iter, "{&sv}", &key, &value)) {
1604 fwupd_result_from_key_value (result, key, value);
1605 fwupd_release_from_key_value (priv->release, key, value);
1606 fwupd_device_from_key_value (priv->device, key, value);
1607 g_variant_unref (value);
1608 }
1609 }
1610
1611 /**
1612 * fwupd_result_new_from_data:
1613 * @data: a #GVariant
1614 *
1615 * Creates a new result using packed data.
1616 *
1617 * Returns: a new #FwupdResult, or %NULL if @data was invalid
1618 *
1619 * Since: 0.7.0
1620 **/
1621 FwupdResult *
1622 fwupd_result_new_from_data (GVariant *data)
1623 {
1624 FwupdResult *res = NULL;
1625 const gchar *id;
1626 const gchar *type_string;
1627 g_autoptr(GVariantIter) iter = NULL;
1628
1629 /* format from GetDetails */
1630 type_string = g_variant_get_type_string (data);
1631 if (g_strcmp0 (type_string, "(a{sv})") == 0) {
1632 res = fwupd_result_new ();
1633 g_variant_get (data, "(a{sv})", &iter);
1634 fwupd_result_from_variant_iter (res, iter);
1635 } else if (g_strcmp0 (type_string, "{sa{sv}}") == 0) {
1636 res = fwupd_result_new ();
1637 g_variant_get (data, "{&sa{sv}}", &id, &iter);
1638 fwupd_device_set_id (fwupd_result_get_device (res), id);
1639 fwupd_result_from_variant_iter (res, iter);
1640 } else {
1641 g_warning ("type %s not known", type_string);
1642 }
1643 return res;
1644 }
1645
1646 /**
1647 * fwupd_result_new:
1648 *
1649 * Creates a new result.
1650 *
1651 * Returns: a new #FwupdResult
1652 *
1653 * Since: 0.7.0
1654 **/
1655 FwupdResult *
1656 fwupd_result_new (void)
1657 {
1658 FwupdResult *result;
1659 result = g_object_new (FWUPD_TYPE_RESULT, NULL);
1660 return FWUPD_RESULT (result);
1661 }
+0
-244
libfwupd/fwupd-result.h less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __FWUPD_RESULT_H
22 #define __FWUPD_RESULT_H
23
24 #include <glib-object.h>
25
26 #include "fwupd-device.h"
27 #include "fwupd-enums.h"
28 #include "fwupd-release.h"
29
30 G_BEGIN_DECLS
31
32 #define FWUPD_TYPE_RESULT (fwupd_result_get_type ())
33 G_DECLARE_DERIVABLE_TYPE (FwupdResult, fwupd_result, FWUPD, RESULT, GObject)
34
35 struct _FwupdResultClass
36 {
37 GObjectClass parent_class;
38 /*< private >*/
39 void (*_fwupd_reserved1) (void);
40 void (*_fwupd_reserved2) (void);
41 void (*_fwupd_reserved3) (void);
42 void (*_fwupd_reserved4) (void);
43 void (*_fwupd_reserved5) (void);
44 void (*_fwupd_reserved6) (void);
45 void (*_fwupd_reserved7) (void);
46 };
47
48 FwupdResult *fwupd_result_new (void);
49 FwupdResult *fwupd_result_new_from_data (GVariant *data);
50
51 /* matches */
52 G_DEPRECATED_FOR(fwupd_device_add_guid)
53 void fwupd_result_add_guid (FwupdResult *result,
54 const gchar *guid);
55 G_DEPRECATED_FOR(fwupd_device_has_guid)
56 gboolean fwupd_result_has_guid (FwupdResult *result,
57 const gchar *guid);
58 G_DEPRECATED_FOR(fwupd_device_get_guids)
59 GPtrArray *fwupd_result_get_guids (FwupdResult *result);
60 G_DEPRECATED_FOR(fwupd_device_get_guid_default)
61 const gchar *fwupd_result_get_guid_default (FwupdResult *result);
62
63 const gchar *fwupd_result_get_unique_id (FwupdResult *result);
64 void fwupd_result_set_unique_id (FwupdResult *result,
65 const gchar *unique_id);
66
67 /* helper objects */
68 FwupdRelease *fwupd_result_get_release (FwupdResult *result);
69 FwupdDevice *fwupd_result_get_device (FwupdResult *result);
70
71 /* device-specific */
72 G_DEPRECATED_FOR(fwupd_device_get_id)
73 const gchar *fwupd_result_get_device_id (FwupdResult *result);
74 G_DEPRECATED_FOR(fwupd_device_set_id)
75 void fwupd_result_set_device_id (FwupdResult *result,
76 const gchar *device_id);
77 G_DEPRECATED_FOR(fwupd_device_get_name)
78 const gchar *fwupd_result_get_device_name (FwupdResult *result);
79 G_DEPRECATED_FOR(fwupd_device_set_name)
80 void fwupd_result_set_device_name (FwupdResult *result,
81 const gchar *device_name);
82 G_DEPRECATED_FOR(fwupd_device_get_description)
83 const gchar *fwupd_result_get_device_description (FwupdResult *result);
84 G_DEPRECATED_FOR(fwupd_device_set_description)
85 void fwupd_result_set_device_description (FwupdResult *result,
86 const gchar *device_description);
87 G_DEPRECATED_FOR(fwupd_device_get_version)
88 const gchar *fwupd_result_get_device_version (FwupdResult *result);
89 G_DEPRECATED_FOR(fwupd_device_set_version)
90 void fwupd_result_set_device_version (FwupdResult *result,
91 const gchar *device_version);
92 G_DEPRECATED_FOR(fwupd_device_get_version_lowest)
93 const gchar *fwupd_result_get_device_version_lowest (FwupdResult *result);
94 G_DEPRECATED_FOR(fwupd_device_set_version_lowest)
95 void fwupd_result_set_device_version_lowest (FwupdResult *result,
96 const gchar *device_version_lowest);
97 G_DEPRECATED_FOR(fwupd_device_get_version_bootloader)
98 const gchar *fwupd_result_get_device_version_bootloader (FwupdResult *result);
99 G_DEPRECATED_FOR(fwupd_device_set_version_bootloader)
100 void fwupd_result_set_device_version_bootloader (FwupdResult *result,
101 const gchar *device_version_bootloader);
102 G_DEPRECATED_FOR(fwupd_device_get_flashes_left)
103 guint32 fwupd_result_get_device_flashes_left (FwupdResult *result);
104 G_DEPRECATED_FOR(fwupd_device_set_flashes_left)
105 void fwupd_result_set_device_flashes_left (FwupdResult *result,
106 guint32 flashes_left);
107 G_DEPRECATED_FOR(fwupd_device_get_flags)
108 guint64 fwupd_result_get_device_flags (FwupdResult *result);
109 G_DEPRECATED_FOR(fwupd_device_set_flags)
110 void fwupd_result_set_device_flags (FwupdResult *result,
111 guint64 device_flags);
112 G_DEPRECATED_FOR(fwupd_device_add_flag)
113 void fwupd_result_add_device_flag (FwupdResult *result,
114 FwupdDeviceFlags flag);
115 G_DEPRECATED_FOR(fwupd_device_remove_flag)
116 void fwupd_result_remove_device_flag (FwupdResult *result,
117 FwupdDeviceFlags flag);
118 G_DEPRECATED_FOR(fwupd_device_has_flag)
119 gboolean fwupd_result_has_device_flag (FwupdResult *result,
120 FwupdDeviceFlags flag);
121 G_DEPRECATED_FOR(fwupd_device_get_created)
122 guint64 fwupd_result_get_device_created (FwupdResult *result);
123 G_DEPRECATED_FOR(fwupd_device_set_created)
124 void fwupd_result_set_device_created (FwupdResult *result,
125 guint64 device_created);
126 G_DEPRECATED_FOR(fwupd_device_get_modified)
127 guint64 fwupd_result_get_device_modified (FwupdResult *result);
128 G_DEPRECATED_FOR(fwupd_device_set_modified)
129 void fwupd_result_set_device_modified (FwupdResult *result,
130 guint64 device_modified);
131 G_DEPRECATED_FOR(fwupd_device_get_checksums)
132 const gchar *fwupd_result_get_device_checksum (FwupdResult *result);
133 G_DEPRECATED_FOR(fwupd_device_add_checksum)
134 void fwupd_result_set_device_checksum (FwupdResult *result,
135 const gchar *device_checksum);
136 G_DEPRECATED_FOR(fwupd_device_get_checksums)
137 GChecksumType fwupd_result_get_device_checksum_kind (FwupdResult *result);
138 G_DEPRECATED_FOR(fwupd_device_add_checksum)
139 void fwupd_result_set_device_checksum_kind (FwupdResult *result,
140 GChecksumType checkum_kind);
141 G_DEPRECATED_FOR(fwupd_device_get_provider)
142 const gchar *fwupd_result_get_device_provider (FwupdResult *result);
143 G_DEPRECATED_FOR(fwupd_device_set_provider)
144 void fwupd_result_set_device_provider (FwupdResult *result,
145 const gchar *device_provider);
146 G_DEPRECATED_FOR(fwupd_device_get_vendor)
147 const gchar *fwupd_result_get_device_vendor (FwupdResult *result);
148 G_DEPRECATED_FOR(fwupd_device_set_vendor)
149 void fwupd_result_set_device_vendor (FwupdResult *result,
150 const gchar *device_vendor);
151
152 /* update-specific */
153 G_DEPRECATED_FOR(fwupd_release_get_size)
154 guint64 fwupd_result_get_update_size (FwupdResult *result);
155 G_DEPRECATED_FOR(fwupd_release_set_size)
156 void fwupd_result_set_update_size (FwupdResult *result,
157 guint64 update_size);
158 G_DEPRECATED_FOR(fwupd_release_get_version)
159 const gchar *fwupd_result_get_update_version (FwupdResult *result);
160 G_DEPRECATED_FOR(fwupd_release_set_version)
161 void fwupd_result_set_update_version (FwupdResult *result,
162 const gchar *update_version);
163 G_DEPRECATED_FOR(fwupd_release_get_filename)
164 const gchar *fwupd_result_get_update_filename (FwupdResult *result);
165 G_DEPRECATED_FOR(fwupd_release_set_filename)
166 void fwupd_result_set_update_filename (FwupdResult *result,
167 const gchar *update_filename);
168 FwupdUpdateState fwupd_result_get_update_state (FwupdResult *result);
169 void fwupd_result_set_update_state (FwupdResult *result,
170 FwupdUpdateState update_state);
171 G_DEPRECATED_FOR(fwupd_release_get_checksums)
172 const gchar *fwupd_result_get_update_checksum (FwupdResult *result);
173 G_DEPRECATED_FOR(fwupd_release_add_checksum)
174 void fwupd_result_set_update_checksum (FwupdResult *result,
175 const gchar *update_checksum);
176 G_DEPRECATED_FOR(fwupd_release_get_checksums)
177 GChecksumType fwupd_result_get_update_checksum_kind (FwupdResult *result);
178 G_DEPRECATED_FOR(fwupd_release_add_checksum)
179 void fwupd_result_set_update_checksum_kind (FwupdResult *result,
180 GChecksumType checkum_kind);
181 G_DEPRECATED_FOR(fwupd_release_get_uri)
182 const gchar *fwupd_result_get_update_uri (FwupdResult *result);
183 G_DEPRECATED_FOR(fwupd_release_set_uri)
184 void fwupd_result_set_update_uri (FwupdResult *result,
185 const gchar *update_uri);
186 G_DEPRECATED_FOR(fwupd_release_get_homepage)
187 const gchar *fwupd_result_get_update_homepage (FwupdResult *result);
188 G_DEPRECATED_FOR(fwupd_release_set_homepage)
189 void fwupd_result_set_update_homepage (FwupdResult *result,
190 const gchar *update_homepage);
191 G_DEPRECATED_FOR(fwupd_release_get_appstream_id)
192 const gchar *fwupd_result_get_update_id (FwupdResult *result);
193 G_DEPRECATED_FOR(fwupd_release_set_appstream_id)
194 void fwupd_result_set_update_id (FwupdResult *result,
195 const gchar *update_id);
196 G_DEPRECATED_FOR(fwupd_release_get_description)
197 const gchar *fwupd_result_get_update_description (FwupdResult *result);
198 G_DEPRECATED_FOR(fwupd_release_set_description)
199 void fwupd_result_set_update_description (FwupdResult *result,
200 const gchar *update_description);
201 G_DEPRECATED_FOR(fwupd_release_get_vendor)
202 const gchar *fwupd_result_get_update_vendor (FwupdResult *result);
203 G_DEPRECATED_FOR(fwupd_release_set_vendor)
204 void fwupd_result_set_update_vendor (FwupdResult *result,
205 const gchar *update_vendor);
206 G_DEPRECATED_FOR(fwupd_release_get_summary)
207 const gchar *fwupd_result_get_update_summary (FwupdResult *result);
208 G_DEPRECATED_FOR(fwupd_release_set_summary)
209 void fwupd_result_set_update_summary (FwupdResult *result,
210 const gchar *update_summary);
211 const gchar *fwupd_result_get_update_error (FwupdResult *result);
212 void fwupd_result_set_update_error (FwupdResult *result,
213 const gchar *update_error);
214 FwupdTrustFlags fwupd_result_get_update_trust_flags (FwupdResult *result);
215 void fwupd_result_set_update_trust_flags (FwupdResult *result,
216 FwupdTrustFlags trust_flags);
217 G_DEPRECATED_FOR(fwupd_release_get_license)
218 const gchar *fwupd_result_get_update_license (FwupdResult *result);
219 G_DEPRECATED_FOR(fwupd_release_set_license)
220 void fwupd_result_set_update_license (FwupdResult *result,
221 const gchar *update_license);
222 G_DEPRECATED_FOR(fwupd_release_get_name)
223 const gchar *fwupd_result_get_update_name (FwupdResult *result);
224 G_DEPRECATED_FOR(fwupd_release_set_name)
225 void fwupd_result_set_update_name (FwupdResult *result,
226 const gchar *update_name);
227
228 /* helpers */
229 GVariant *fwupd_result_to_data (FwupdResult *result,
230 const gchar *type_string);
231 gchar *fwupd_result_to_string (FwupdResult *result);
232
233 /* deprecated */
234 G_DEPRECATED_FOR(fwupd_result_get_guids)
235 const gchar *fwupd_result_get_guid (FwupdResult *result);
236 G_DEPRECATED_FOR(fwupd_result_add_guid)
237 void fwupd_result_set_guid (FwupdResult *result,
238 const gchar *guid);
239
240 G_END_DECLS
241
242 #endif /* __FWUPD_RESULT_H */
243
2222
2323 #include <glib-object.h>
2424 #include <fnmatch.h>
25 #include <appstream-glib.h>
2526
2627 #include "fwupd-client.h"
2728 #include "fwupd-enums.h"
2829 #include "fwupd-error.h"
2930 #include "fwupd-remote-private.h"
30 #include "fwupd-result.h"
3131
3232 static gboolean
3333 as_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error)
5959 static void
6060 fwupd_enums_func (void)
6161 {
62 const gchar *tmp;
63 guint64 i;
64
6562 /* enums */
66 for (i = 0; i < FWUPD_ERROR_LAST; i++) {
67 tmp = fwupd_error_to_string (i);
63 for (guint i = 0; i < FWUPD_ERROR_LAST; i++) {
64 const gchar *tmp = fwupd_error_to_string (i);
6865 g_assert_cmpstr (tmp, !=, NULL);
6966 g_assert_cmpint (fwupd_error_from_string (tmp), ==, i);
7067 }
71 for (i = 0; i < FWUPD_STATUS_LAST; i++) {
72 tmp = fwupd_status_to_string (i);
68 for (guint i = 0; i < FWUPD_STATUS_LAST; i++) {
69 const gchar *tmp = fwupd_status_to_string (i);
7370 g_assert_cmpstr (tmp, !=, NULL);
7471 g_assert_cmpint (fwupd_status_from_string (tmp), ==, i);
7572 }
76 for (i = 0; i < FWUPD_UPDATE_STATE_LAST; i++) {
77 tmp = fwupd_update_state_to_string (i);
73 for (guint i = 0; i < FWUPD_UPDATE_STATE_LAST; i++) {
74 const gchar *tmp = fwupd_update_state_to_string (i);
7875 g_assert_cmpstr (tmp, !=, NULL);
7976 g_assert_cmpint (fwupd_update_state_from_string (tmp), ==, i);
8077 }
81 for (i = 0; i < FWUPD_TRUST_FLAG_LAST; i++) {
82 tmp = fwupd_trust_flag_to_string (i);
78 for (guint i = 0; i < FWUPD_TRUST_FLAG_LAST; i++) {
79 const gchar *tmp = fwupd_trust_flag_to_string (i);
8380 g_assert_cmpstr (tmp, !=, NULL);
8481 g_assert_cmpint (fwupd_trust_flag_from_string (tmp), ==, i);
8582 }
8683
8784 /* bitfield */
88 for (i = 1; i < FWUPD_DEVICE_FLAG_UNKNOWN; i *= 2) {
89 tmp = fwupd_device_flag_to_string (i);
85 for (guint64 i = 1; i < FWUPD_DEVICE_FLAG_UNKNOWN; i *= 2) {
86 const gchar *tmp = fwupd_device_flag_to_string (i);
9087 if (tmp == NULL)
9188 break;
9289 g_assert_cmpint (fwupd_device_flag_from_string (tmp), ==, i);
112109 g_assert (fwupd_remote_get_enabled (remote));
113110 g_assert (fwupd_remote_get_metadata_uri (remote) != NULL);
114111 g_assert (fwupd_remote_get_metadata_uri_sig (remote) != NULL);
115 g_assert_cmpstr (fwupd_remote_get_filename (remote), ==, "lvfs-firmware.xml.gz");
116 g_assert_cmpstr (fwupd_remote_get_filename_asc (remote), ==, "lvfs-firmware.xml.gz.asc");
112 g_assert_cmpstr (fwupd_remote_get_title (remote), ==, "Linux Vendor Firmware Service");
117113 g_assert_cmpstr (fwupd_remote_get_filename_cache (remote), ==,
118114 LOCALSTATEDIR "/lib/fwupd/remotes.d/lvfs/metadata.xml.gz");
119115 g_assert_cmpstr (fwupd_remote_get_filename_cache_sig (remote), ==,
139135 g_assert_cmpint (fwupd_remote_get_keyring_kind (remote), ==, FWUPD_KEYRING_KIND_GPG);
140136 g_assert_cmpint (fwupd_remote_get_priority (remote), ==, 0);
141137 g_assert (fwupd_remote_get_enabled (remote));
138 g_assert_cmpstr (fwupd_remote_get_checksum (remote), ==, NULL);
142139 g_assert_cmpstr (fwupd_remote_get_metadata_uri (remote), ==,
143140 "https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz");
144141 g_assert_cmpstr (fwupd_remote_get_metadata_uri_sig (remote), ==,
166163 g_assert (fwupd_remote_get_enabled (remote));
167164 g_assert (fwupd_remote_get_metadata_uri (remote) == NULL);
168165 g_assert (fwupd_remote_get_metadata_uri_sig (remote) == NULL);
169 g_assert_cmpstr (fwupd_remote_get_filename (remote), ==, NULL);
170 g_assert_cmpstr (fwupd_remote_get_filename_asc (remote), ==, NULL);
166 g_assert_cmpstr (fwupd_remote_get_title (remote), ==, "Core");
171167 g_assert_cmpstr (fwupd_remote_get_filename_cache (remote), ==, "@datadir@/fwupd/remotes.d/fwupd/metadata.xml");
172168 g_assert_cmpstr (fwupd_remote_get_filename_cache_sig (remote), ==, NULL);
173 }
174
175 static void
176 fwupd_result_func (void)
177 {
178 FwupdDevice *dev;
179 FwupdRelease *rel;
169 g_assert_cmpstr (fwupd_remote_get_checksum (remote), ==, NULL);
170 }
171
172 static void
173 fwupd_device_func (void)
174 {
180175 gboolean ret;
181176 g_autofree gchar *str = NULL;
182 g_autoptr(FwupdResult) result = NULL;
177 g_autoptr(FwupdDevice) dev = NULL;
178 g_autoptr(FwupdRelease) rel = NULL;
183179 g_autoptr(GError) error = NULL;
184180
185181 /* create dummy object */
186 result = fwupd_result_new ();
187 dev = fwupd_result_get_device (result);
182 dev = fwupd_device_new ();
188183 fwupd_device_add_checksum (dev, "beefdead");
189184 fwupd_device_set_created (dev, 1);
190185 fwupd_device_set_flags (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
193188 fwupd_device_set_name (dev, "ColorHug2");
194189 fwupd_device_add_guid (dev, "2082b5e0-7a64-478a-b1b2-e3404fab6dad");
195190 fwupd_device_add_guid (dev, "00000000-0000-0000-0000-000000000000");
191 fwupd_device_add_icon (dev, "input-gaming");
192 fwupd_device_add_icon (dev, "input-mouse");
196193 fwupd_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
197 fwupd_result_set_update_trust_flags (result, FWUPD_TRUST_FLAG_PAYLOAD);
198
199 rel = fwupd_result_get_release (result);
194 rel = fwupd_release_new ();
195 fwupd_release_set_trust_flags (rel, FWUPD_TRUST_FLAG_PAYLOAD);
200196 fwupd_release_add_checksum (rel, "deadbeef");
201197 fwupd_release_set_description (rel, "<p>Hi there!</p>");
202198 fwupd_release_set_filename (rel, "firmware.bin");
204200 fwupd_release_set_size (rel, 1024);
205201 fwupd_release_set_uri (rel, "http://foo.com");
206202 fwupd_release_set_version (rel, "1.2.3");
207 str = fwupd_result_to_string (result);
203 fwupd_device_add_release (dev, rel);
204 str = fwupd_device_to_string (dev);
208205 g_print ("\n%s", str);
209206
210207 /* check GUIDs */
214211
215212 ret = as_test_compare_lines (str,
216213 "ColorHug2\n"
217 " DeviceID: USB:foo\n"
214 " DeviceId: USB:foo\n"
218215 " Guid: 2082b5e0-7a64-478a-b1b2-e3404fab6dad\n"
219216 " Guid: 00000000-0000-0000-0000-000000000000\n"
220217 " Flags: updatable|require-ac\n"
221 " FirmwareHash: SHA1(beefdead)\n"
218 " Checksum: SHA1(beefdead)\n"
219 " Icon: input-gaming,input-mouse\n"
222220 " Created: 1970-01-01\n"
223221 " Modified: 1970-01-02\n"
222 " \n"
223 " [Release]\n"
224224 " AppstreamId: org.dave.ColorHug.firmware\n"
225 " UpdateDescription: <p>Hi there!</p>\n"
226 " UpdateVersion: 1.2.3\n"
227 " FilenameCab: firmware.bin\n"
228 " UpdateHash: SHA1(deadbeef)\n"
225 " Description: <p>Hi there!</p>\n"
226 " Version: 1.2.3\n"
227 " Filename: firmware.bin\n"
228 " Checksum: SHA1(deadbeef)\n"
229229 " Size: 1.0 kB\n"
230 " UpdateUri: http://foo.com\n"
231 " Trusted: payload\n", &error);
230 " Uri: http://foo.com\n"
231 " TrustFlags: payload\n", &error);
232232 g_assert_no_error (error);
233233 g_assert (ret);
234234 }
237237 fwupd_client_devices_func (void)
238238 {
239239 FwupdDevice *dev;
240 gboolean ret;
240241 g_autoptr(FwupdClient) client = NULL;
241242 g_autoptr(GPtrArray) array = NULL;
242243 g_autoptr(GError) error = NULL;
243244
244245 client = fwupd_client_new ();
245 array = fwupd_client_get_devices_simple (client, NULL, &error);
246
247 /* only run if running fwupd is new enough */
248 ret = fwupd_client_connect (client, NULL, &error);
249 g_assert_no_error (error);
250 g_assert_true (ret);
251 if (as_utils_vercmp (fwupd_client_get_daemon_version (client), "1.0.0") < 0) {
252 g_test_skip ("running fwupd is too old");
253 return;
254 }
255
256 array = fwupd_client_get_devices (client, NULL, &error);
246257 if (array == NULL &&
247258 g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO))
248259 return;
263274 static void
264275 fwupd_client_remotes_func (void)
265276 {
277 gboolean ret;
266278 g_autoptr(FwupdClient) client = NULL;
267279 g_autoptr(FwupdRemote) remote2 = NULL;
268280 g_autoptr(FwupdRemote) remote3 = NULL;
272284 g_setenv ("FU_SELF_TEST_REMOTES_DIR", FU_SELF_TEST_REMOTES_DIR, TRUE);
273285
274286 client = fwupd_client_new ();
287
288 /* only run if running fwupd is new enough */
289 ret = fwupd_client_connect (client, NULL, &error);
290 g_assert_no_error (error);
291 g_assert_true (ret);
292 if (as_utils_vercmp (fwupd_client_get_daemon_version (client), "1.0.0") < 0) {
293 g_test_skip ("running fwupd is too old");
294 return;
295 }
296
275297 array = fwupd_client_get_remotes (client, NULL, &error);
276298 g_assert_no_error (error);
277299 g_assert (array != NULL);
289311 remote3 = fwupd_client_get_remote_by_id (client, "XXXX", NULL, &error);
290312 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
291313 g_assert (remote3 == NULL);
292 }
293
294 static void
295 fwupd_client_updates_func (void)
296 {
297 FwupdDevice *dev;
298 FwupdResult *res;
299 g_autoptr(FwupdClient) client = NULL;
300 g_autoptr(GPtrArray) array = NULL;
301 g_autoptr(GError) error = NULL;
302
303 client = fwupd_client_new ();
304 array = fwupd_client_get_updates (client, NULL, &error);
305 if (array == NULL &&
306 g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO))
307 return;
308 if (array == NULL &&
309 g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED))
310 return;
311 g_assert_no_error (error);
312 g_assert (array != NULL);
313 g_assert_cmpint (array->len, >, 0);
314
315 /* check device */
316 res = g_ptr_array_index (array, 0);
317 g_assert (FWUPD_IS_RESULT (res));
318 dev = fwupd_result_get_device (res);
319 g_assert_cmpstr (fwupd_device_get_guid_default (dev), !=, NULL);
320 g_assert_cmpstr (fwupd_device_get_id (dev), !=, NULL);
321314 }
322315
323316 static gboolean
342335
343336 /* tests go here */
344337 g_test_add_func ("/fwupd/enums", fwupd_enums_func);
345 g_test_add_func ("/fwupd/result", fwupd_result_func);
338 g_test_add_func ("/fwupd/device", fwupd_device_func);
346339 g_test_add_func ("/fwupd/remote{download}", fwupd_remote_download_func);
347340 g_test_add_func ("/fwupd/remote{base-uri}", fwupd_remote_baseuri_func);
348341 g_test_add_func ("/fwupd/remote{local}", fwupd_remote_local_func);
349342 if (fwupd_has_system_bus ()) {
350343 g_test_add_func ("/fwupd/client{remotes}", fwupd_client_remotes_func);
351344 g_test_add_func ("/fwupd/client{devices}", fwupd_client_devices_func);
352 g_test_add_func ("/fwupd/client{updates}", fwupd_client_updates_func);
353345 }
354346 return g_test_run ();
355347 }
3535 #include <libfwupd/fwupd-error.h>
3636 #include <libfwupd/fwupd-release.h>
3737 #include <libfwupd/fwupd-remote.h>
38 #include <libfwupd/fwupd-result.h>
3938 #include <libfwupd/fwupd-version.h>
39
40 #ifndef FWUPD_DISABLE_DEPRECATED
41 #include <libfwupd/fwupd-deprecated.h>
42 #endif
4043
4144 #undef __FWUPD_H_INSIDE__
4245
0 {
1 global:
2 fwupd_*;
3 local:
4 *;
0 # generated automatically, do not edit!
1
2 LIBFWUPD_0.1.1 {
3 global:
4 fwupd_error_quark;
5 fwupd_status_from_string;
6 fwupd_status_to_string;
7 local: *;
58 };
9
10 LIBFWUPD_0.7.0 {
11 global:
12 fwupd_client_clear_results;
13 fwupd_client_get_results;
14 fwupd_client_get_type;
15 fwupd_client_install;
16 fwupd_client_new;
17 fwupd_client_unlock;
18 fwupd_client_verify;
19 fwupd_device_flag_from_string;
20 fwupd_device_flag_to_string;
21 fwupd_error_from_string;
22 fwupd_error_to_string;
23 fwupd_trust_flag_from_string;
24 fwupd_trust_flag_to_string;
25 fwupd_update_state_from_string;
26 fwupd_update_state_to_string;
27 local: *;
28 } LIBFWUPD_0.1.1;
29
30 LIBFWUPD_0.7.1 {
31 global:
32 fwupd_client_connect;
33 local: *;
34 } LIBFWUPD_0.7.0;
35
36 LIBFWUPD_0.7.3 {
37 global:
38 fwupd_client_get_percentage;
39 fwupd_client_get_status;
40 local: *;
41 } LIBFWUPD_0.7.1;
42
43 LIBFWUPD_0.8.0 {
44 global:
45 fwupd_client_verify_update;
46 local: *;
47 } LIBFWUPD_0.7.3;
48
49 LIBFWUPD_0.9.2 {
50 global:
51 fwupd_client_get_devices;
52 local: *;
53 } LIBFWUPD_0.8.0;
54
55 LIBFWUPD_0.9.3 {
56 global:
57 fwupd_checksum_format_for_display;
58 fwupd_checksum_guess_kind;
59 fwupd_client_get_device_by_id;
60 fwupd_client_get_releases;
61 fwupd_client_get_remote_by_id;
62 fwupd_client_get_remotes;
63 fwupd_device_add_checksum;
64 fwupd_device_add_flag;
65 fwupd_device_add_guid;
66 fwupd_device_get_checksums;
67 fwupd_device_get_created;
68 fwupd_device_get_description;
69 fwupd_device_get_flags;
70 fwupd_device_get_flashes_left;
71 fwupd_device_get_guid_default;
72 fwupd_device_get_guids;
73 fwupd_device_get_id;
74 fwupd_device_get_modified;
75 fwupd_device_get_name;
76 fwupd_device_get_summary;
77 fwupd_device_get_type;
78 fwupd_device_get_vendor;
79 fwupd_device_get_version;
80 fwupd_device_get_version_bootloader;
81 fwupd_device_get_version_lowest;
82 fwupd_device_has_flag;
83 fwupd_device_has_guid;
84 fwupd_device_new;
85 fwupd_device_remove_flag;
86 fwupd_device_set_created;
87 fwupd_device_set_description;
88 fwupd_device_set_flags;
89 fwupd_device_set_flashes_left;
90 fwupd_device_set_id;
91 fwupd_device_set_modified;
92 fwupd_device_set_name;
93 fwupd_device_set_summary;
94 fwupd_device_set_vendor;
95 fwupd_device_set_version;
96 fwupd_device_set_version_bootloader;
97 fwupd_device_set_version_lowest;
98 fwupd_device_to_string;
99 fwupd_release_add_checksum;
100 fwupd_release_get_appstream_id;
101 fwupd_release_get_checksums;
102 fwupd_release_get_description;
103 fwupd_release_get_filename;
104 fwupd_release_get_homepage;
105 fwupd_release_get_license;
106 fwupd_release_get_name;
107 fwupd_release_get_remote_id;
108 fwupd_release_get_size;
109 fwupd_release_get_summary;
110 fwupd_release_get_type;
111 fwupd_release_get_uri;
112 fwupd_release_get_vendor;
113 fwupd_release_get_version;
114 fwupd_release_new;
115 fwupd_release_set_appstream_id;
116 fwupd_release_set_description;
117 fwupd_release_set_filename;
118 fwupd_release_set_homepage;
119 fwupd_release_set_license;
120 fwupd_release_set_name;
121 fwupd_release_set_remote_id;
122 fwupd_release_set_size;
123 fwupd_release_set_summary;
124 fwupd_release_set_uri;
125 fwupd_release_set_vendor;
126 fwupd_release_set_version;
127 fwupd_release_to_string;
128 fwupd_remote_get_enabled;
129 fwupd_remote_get_id;
130 fwupd_remote_get_type;
131 fwupd_remote_load_from_filename;
132 fwupd_remote_new;
133 local: *;
134 } LIBFWUPD_0.9.2;
135
136 LIBFWUPD_0.9.4 {
137 global:
138 fwupd_checksum_get_best;
139 fwupd_checksum_get_by_kind;
140 fwupd_device_get_vendor_id;
141 fwupd_device_set_vendor_id;
142 local: *;
143 } LIBFWUPD_0.9.3;
144
145 LIBFWUPD_0.9.5 {
146 global:
147 fwupd_remote_get_age;
148 fwupd_remote_get_order_after;
149 fwupd_remote_get_order_before;
150 fwupd_remote_get_password;
151 fwupd_remote_get_priority;
152 fwupd_remote_get_username;
153 fwupd_remote_set_mtime;
154 fwupd_remote_set_priority;
155 local: *;
156 } LIBFWUPD_0.9.4;
157
158 LIBFWUPD_0.9.6 {
159 global:
160 fwupd_client_get_daemon_version;
161 fwupd_remote_get_filename_cache;
162 fwupd_remote_get_kind;
163 fwupd_remote_kind_from_string;
164 fwupd_remote_kind_to_string;
165 local: *;
166 } LIBFWUPD_0.9.5;
167
168 LIBFWUPD_0.9.7 {
169 global:
170 fwupd_keyring_kind_from_string;
171 fwupd_keyring_kind_to_string;
172 fwupd_remote_build_firmware_uri;
173 fwupd_remote_get_filename_cache_sig;
174 fwupd_remote_get_firmware_base_uri;
175 fwupd_remote_get_keyring_kind;
176 fwupd_remote_get_metadata_uri;
177 fwupd_remote_get_metadata_uri_sig;
178 local: *;
179 } LIBFWUPD_0.9.6;
180
181 LIBFWUPD_0.9.8 {
182 global:
183 fwupd_client_get_downgrades;
184 fwupd_client_get_upgrades;
185 fwupd_client_modify_remote;
186 fwupd_device_add_icon;
187 fwupd_device_add_release;
188 fwupd_device_get_icons;
189 fwupd_device_get_release_default;
190 fwupd_device_get_releases;
191 fwupd_device_get_update_error;
192 fwupd_device_get_update_state;
193 fwupd_device_set_update_error;
194 fwupd_device_set_update_state;
195 fwupd_release_get_trust_flags;
196 fwupd_release_set_trust_flags;
197 fwupd_remote_get_filename_source;
198 fwupd_remote_get_title;
199 local: *;
200 } LIBFWUPD_0.9.7;
201
202 LIBFWUPD_1.0.0 {
203 global:
204 fwupd_client_get_details;
205 fwupd_client_update_metadata;
206 fwupd_device_from_variant;
207 fwupd_device_get_plugin;
208 fwupd_device_set_plugin;
209 fwupd_device_to_variant;
210 fwupd_release_from_variant;
211 fwupd_release_to_variant;
212 fwupd_remote_from_variant;
213 fwupd_remote_get_checksum;
214 fwupd_remote_to_variant;
215 local: *;
216 } LIBFWUPD_0.9.8;
0 #!/usr/bin/env python3
1 # pylint: disable=invalid-name,missing-docstring
2 #
3 # Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
4 #
5 # Licensed under the GNU General Public License Version 2
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, see <http://www.gnu.org/licenses/>.
19
20 import sys
21 import xml.etree.ElementTree as ET
22
23 XMLNS = '{http://www.gtk.org/introspection/core/1.0}'
24 XMLNS_C = '{http://www.gtk.org/introspection/c/1.0}'
25
26 def usage(return_code):
27 """ print usage and exit with the supplied return code """
28 if return_code == 0:
29 out = sys.stdout
30 else:
31 out = sys.stderr
32 out.write("usage: %s <NAME> <INPUT> <OUTPUT>\n" % sys.argv[0])
33 sys.exit(return_code)
34
35 class LdVersionScript:
36 """ Rasterize some text """
37
38 def __init__(self, library_name):
39 self.library_name = library_name
40 self.releases = {}
41
42 def _add_node(self, node):
43 identifier = node.attrib[XMLNS_C + 'identifier']
44 if 'version' not in node.attrib:
45 print('No version for', identifier)
46 sys.exit(1)
47 return
48 version = node.attrib['version']
49 if version not in self.releases:
50 self.releases[version] = []
51 release = self.releases[version]
52 release.append(identifier)
53 return version
54
55 def import_gir(self, filename):
56 tree = ET.parse(filename)
57 root = tree.getroot()
58 for ns in root.findall(XMLNS + 'namespace'):
59 for node in ns.findall(XMLNS + 'function'):
60 self._add_node(node)
61 for cls in ns.findall(XMLNS + 'class'):
62
63 # add all class functions
64 for node in cls.findall(XMLNS + 'function'):
65 self._add_node(node)
66
67 # add the constructor
68 for node in cls.findall(XMLNS + 'constructor'):
69 self._add_node(node)
70
71 # choose the lowest version method for the _get_type symbol
72 version_lowest = None
73 type_name = cls.attrib['{http://www.gtk.org/introspection/glib/1.0}get-type']
74
75 # add all class methods
76 for node in cls.findall(XMLNS + 'method'):
77 version_tmp = self._add_node(node)
78 if version_tmp:
79 if not version_lowest or version_tmp < version_lowest:
80 version_lowest = version_tmp
81
82 # finally add the get_type symbol
83 if version_lowest:
84 self.releases[version_lowest].append(type_name)
85
86 def render(self):
87
88 # get a sorted list of all the versions
89 versions = []
90 for version in self.releases:
91 versions.append(version)
92
93 # output the version data to a file
94 verout = '# generated automatically, do not edit!\n'
95 oldversion = None
96 for version in sorted(versions):
97 symbols = sorted(self.releases[version])
98 verout += '\n%s_%s {\n' % (self.library_name, version)
99 verout += ' global:\n'
100 for symbol in symbols:
101 verout += ' %s;\n' % symbol
102 verout += ' local: *;\n'
103 if oldversion:
104 verout += '} %s_%s;\n' % (self.library_name, oldversion)
105 else:
106 verout += '};\n'
107 oldversion = version
108 return verout
109
110 if __name__ == '__main__':
111 if {'-?', '--help', '--usage'}.intersection(set(sys.argv)):
112 usage(0)
113 if len(sys.argv) != 4:
114 usage(1)
115
116 ld = LdVersionScript(library_name=sys.argv[1])
117 ld.import_gir(sys.argv[2])
118 open(sys.argv[3], 'w').write(ld.render())
1515 install_headers([
1616 'fwupd-client.h',
1717 'fwupd-common.h',
18 'fwupd-deprecated.h',
1819 'fwupd-device.h',
1920 'fwupd-enums.h',
2021 'fwupd-error.h',
2122 'fwupd-remote.h',
2223 'fwupd-release.h',
23 'fwupd-result.h',
2424 fwupd_version_h,
2525 ],
2626 subdir : 'fwupd-1/libfwupd',
3838 'fwupd-error.c',
3939 'fwupd-release.c',
4040 'fwupd-remote.c',
41 'fwupd-result.c',
4241 ],
4342 soversion : lt_current,
4443 version : lt_version,
5958 pkgg = import('pkgconfig')
6059 pkgg.generate(
6160 libraries : fwupd,
62 requires : [ 'gio-2.0', 'libsoup-2.4' ],
61 requires : [ 'gio-2.0' ],
6362 subdirs : 'fwupd-1',
6463 version : meson.project_version(),
6564 name : 'fwupd',
6867 )
6968
7069 if get_option('enable-introspection')
71 gnome.generate_gir(fwupd,
70 gir = gnome.generate_gir(fwupd,
7271 sources : [
7372 'fwupd-client.c',
7473 'fwupd-client.h',
74 'fwupd-common.c',
75 'fwupd-common.h',
76 'fwupd-common-private.h',
7577 'fwupd-device.c',
7678 'fwupd-device.h',
79 'fwupd-device-private.h',
7780 'fwupd-enums.c',
7881 'fwupd-enums.h',
82 'fwupd-enums-private.h',
7983 'fwupd-error.c',
8084 'fwupd-error.h',
8185 'fwupd-release.c',
8286 'fwupd-release.h',
87 'fwupd-release-private.h',
8388 'fwupd-remote.c',
8489 'fwupd-remote.h',
85 'fwupd-result.c',
86 'fwupd-result.h',
90 'fwupd-remote-private.h',
8791 ],
88 nsversion : '1.0',
92 nsversion : '2.0',
8993 namespace : 'Fwupd',
9094 symbol_prefix : 'fwupd',
9195 identifier_prefix : 'Fwupd',
101105 ],
102106 install : true
103107 )
108
109 # Verify the map file is correct -- note we can't actually use the generated
110 # file for two reasons:
111 #
112 # 1. We don't hard depend on GObject Introspection
113 # 2. The map file is required to build the lib that the GIR is built from
114 #
115 # To avoid the circular dep, and to ensure we don't change exported API
116 # accidentaly actually check in a version of the version script to git.
117 mapfile_target = custom_target('mapfile',
118 input: gir[0],
119 output: 'fwupd.map',
120 command: [
121 join_paths(meson.current_source_dir(), 'generate-version-script.py'),
122 'LIBFWUPD',
123 '@INPUT@',
124 '@OUTPUT@',
125 ],
126 )
127 diffcmd = find_program('diff')
128 test('fwupd-exported-api', diffcmd,
129 args : [
130 '-urNp',
131 join_paths(meson.current_source_dir(), 'fwupd.map'),
132 mapfile_target,
133 ],
134 )
104135 endif
105136
106137 if get_option('enable-tests')
114145 include_directories('..'),
115146 ],
116147 dependencies : [
148 appstream_glib,
117149 gio,
118150 soup,
119151 ],
00 project('fwupd', 'c',
1 version : '0.9.7',
1 version : '1.0.0',
22 license : 'LGPL-2.1+',
33 meson_version : '>=0.37.0',
44 default_options : ['warning_level=2', 'c_std=c99'],
4242 # - If the interface is the same as the previous version, but bugs are
4343 # fixed, change:
4444 # REVISION += 1
45 lt_current = '1'
46 lt_revision = '1'
45 lt_current = '2'
46 lt_revision = '0'
4747 lt_age = '0'
4848 lt_version = '@0@.@1@.@2@'.format(lt_current, lt_age, lt_revision)
4949
5656 '-Wcast-align',
5757 '-Wclobbered',
5858 '-Wdeclaration-after-statement',
59 '-Wduplicated-branches',
60 '-Wduplicated-cond',
5961 '-Wempty-body',
6062 '-Wformat=2',
6163 '-Wformat-nonliteral',
6466 '-Wignored-qualifiers',
6567 '-Wimplicit-function-declaration',
6668 '-Winit-self',
69 '-Wlogical-op',
6770 '-Wmissing-declarations',
6871 '-Wmissing-format-attribute',
6972 '-Wmissing-include-dirs',
7679 '-Wno-strict-aliasing',
7780 '-Wno-suggest-attribute=format',
7881 '-Wno-unused-parameter',
82 '-Wnull-dereference',
7983 '-Wold-style-definition',
8084 '-Woverride-init',
8185 '-Wpointer-arith',
9094 '-Wundef',
9195 '-Wuninitialized',
9296 '-Wunused-but-set-variable',
97 '-Wunused-variable',
9398 '-Wwrite-strings'
9499 ]
95100 cc = meson.get_compiler('c')
116121 language: 'c'
117122 )
118123
124 # ONLY for CI and only when using gcc, do not enable this for distro builds
125 if get_option('enable-werror') and meson.get_compiler('c').get_id() == 'gcc'
126 add_project_arguments('-Werror', language : 'c')
127 add_project_arguments('-Wno-error=cpp', language : 'c')
128 endif
129
119130 # Needed for realpath(), syscall(), cfmakeraw(), etc.
120131 add_project_arguments('-D_DEFAULT_SOURCE', language : 'c')
132
133 # do not use deprecated symbols or defines internally
134 add_project_arguments('-DFWUPD_DISABLE_DEPRECATED', language : 'c')
121135
122136 gio = dependency('gio-2.0', version : '>= 2.45.8')
123137 gmodule = dependency('gmodule-2.0')
172186 conf.set('HAVE_COLORHUG', '1')
173187 endif
174188
175 if get_option('enable-libelf')
189 if get_option('enable-altos')
176190 libelf = dependency('libelf')
177 conf.set('HAVE_LIBELF', '1')
178191 endif
179192
180193 if get_option('enable-uefi')
181194 fwup = dependency('fwup', version : '>= 5')
182 conf.set('HAVE_UEFI', '1')
183 conf.set('HAVE_UEFI_UNLOCK', '1')
184 conf.set('HAVE_UEFI_GUID', '1')
195 if fwup.version().version_compare('>= 10')
196 conf.set('HAVE_FWUP_GET_BGRT_INFO', '1')
197 endif
185198 endif
186199
187200 if get_option('enable-dell')
228241
229242 plugin_dir = join_paths(get_option('prefix'),
230243 get_option('libdir'),
231 'fwupd-plugins-2')
232 conf.set_quoted('PLUGINDIR', plugin_dir)
233
234 conf.set_quoted('SYSCONFDIR', get_option('sysconfdir'))
244 'fwupd-plugins-3')
245
235246 conf.set_quoted('BINDIR',
236247 join_paths(get_option('prefix'),
237248 get_option('bindir')))
248259 configuration : conf
249260 )
250261
262 default_sysconfdir = get_option('sysconfdir')
263 if default_sysconfdir == 'etc'
264 message('sysconfdir of etc makes no sense, using /etc')
265 default_sysconfdir = '/etc'
266 endif
267
251268 localstatedir = join_paths(get_option('prefix'),
252269 get_option('localstatedir'))
253270
262279
263280 subdir('data')
264281 subdir('docs')
265 subdir('libdfu')
266282 subdir('libfwupd')
267283 subdir('po')
268284 subdir('policy')
33 option('enable-tests', type : 'boolean', value : true, description : 'enable tests')
44 option('enable-lvfs', type : 'boolean', value : true, description : 'enable LVFS remotes')
55 option('enable-colorhug', type : 'boolean', value : true, description : 'enable ColorHug support')
6 option('enable-libelf', type : 'boolean', value : true, description : 'enable libelf support')
6 option('enable-altos', type : 'boolean', value : true, description : 'enable altos support')
7 option('enable-usb-fallback', type : 'boolean', value : false, description : 'enable USB fallback support')
78 option('enable-uefi', type : 'boolean', value : true, description : 'enable UEFI support')
89 option('enable-uefi-labels', type : 'boolean', value : true, description : 'enable UEFI labels support')
910 option('enable-dell', type : 'boolean', value : true, description : 'enable Dell-specific support')
1516 option('enable-dummy', type : 'boolean', value : false, description : 'enable the dummy device')
1617 option('enable-gpg', type : 'boolean', value : true, description : 'enable the GPG verification support')
1718 option('enable-pkcs7', type : 'boolean', value : true, description : 'enable the PKCS7 verification support')
19 option('enable-werror', type : 'boolean', value : true, description : 'build with -Werror (only for CI!)')
1820 option('with-bootdir', type : 'string', value : '/boot/efi', description : 'Directory for EFI system partition')
1921 option('with-systemdunitdir', type: 'string', value: '', description: 'Directory for systemd units')
2022 option('with-udevdir', type: 'string', value: '', description: 'Directory for udev rules')
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <gio/gio.h>
24 #include <gelf.h>
25 #include <libelf.h>
26
27 #include "fu-altos-firmware.h"
28 #include "fwupd-error.h"
29
30 struct _FuAltosFirmware {
31 GObject parent_instance;
32 GBytes *data;
33 guint64 address;
34 };
35
36 G_DEFINE_TYPE (FuAltosFirmware, fu_altos_firmware, G_TYPE_OBJECT)
37
38 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Elf, elf_end);
39
40 GBytes *
41 fu_altos_firmware_get_data (FuAltosFirmware *self)
42 {
43 return self->data;
44 }
45
46 guint64
47 fu_altos_firmware_get_address (FuAltosFirmware *self)
48 {
49 return self->address;
50 }
51
52 gboolean
53 fu_altos_firmware_parse (FuAltosFirmware *self, GBytes *blob, GError **error)
54 {
55 const gchar *name;
56 Elf_Scn *scn = NULL;
57 GElf_Shdr shdr;
58 size_t shstrndx;
59 g_autoptr(Elf) e = NULL;
60
61 /* load library */
62 if (elf_version (EV_CURRENT) == EV_NONE) {
63 g_set_error (error,
64 FWUPD_ERROR,
65 FWUPD_ERROR_INTERNAL,
66 "ELF library init failed: %s",
67 elf_errmsg (-1));
68 return FALSE;
69 }
70
71 /* parse data */
72 e = elf_memory ((gchar *) g_bytes_get_data (blob, NULL),
73 g_bytes_get_size (blob));
74 if (e == NULL) {
75 g_set_error (error,
76 FWUPD_ERROR,
77 FWUPD_ERROR_INTERNAL,
78 "failed to load data as ELF: %s",
79 elf_errmsg (-1));
80 return FALSE;
81 }
82 if (elf_kind (e) != ELF_K_ELF) {
83 g_set_error (error,
84 FWUPD_ERROR,
85 FWUPD_ERROR_INTERNAL,
86 "not a supported ELF format: %s",
87 elf_errmsg (-1));
88 return FALSE;
89 }
90
91 /* add interesting section */
92 if (elf_getshdrstrndx (e, &shstrndx) != 0) {
93 g_set_error (error,
94 FWUPD_ERROR,
95 FWUPD_ERROR_INTERNAL,
96 "invalid ELF file: %s",
97 elf_errmsg (-1));
98 return FALSE;
99 }
100 while ((scn = elf_nextscn (e, scn)) != NULL ) {
101 if (gelf_getshdr (scn, &shdr) != & shdr)
102 continue;
103
104 /* not program data with the same section name */
105 if (shdr.sh_type != SHT_PROGBITS)
106 continue;
107 if ((name = elf_strptr (e, shstrndx, shdr.sh_name)) == NULL)
108 continue;
109
110 if (g_strcmp0 (name, ".text") == 0) {
111 Elf_Data *data = elf_getdata (scn, NULL);
112 if (data != NULL && data->d_buf != NULL) {
113 self->data = g_bytes_new (data->d_buf, data->d_size);
114 self->address = shdr.sh_addr;
115 }
116 return TRUE;
117 }
118 }
119 g_set_error_literal (error,
120 FWUPD_ERROR,
121 FWUPD_ERROR_INTERNAL,
122 "no firmware found in ELF file");
123 return FALSE;
124 }
125
126 static void
127 fu_altos_firmware_finalize (GObject *object)
128 {
129 FuAltosFirmware *self = FU_ALTOS_FIRMWARE (object);
130
131 if (self->data != NULL)
132 g_bytes_unref (self->data);
133
134 G_OBJECT_CLASS (fu_altos_firmware_parent_class)->finalize (object);
135 }
136
137 static void
138 fu_altos_firmware_class_init (FuAltosFirmwareClass *klass)
139 {
140 GObjectClass *object_class = G_OBJECT_CLASS (klass);
141 object_class->finalize = fu_altos_firmware_finalize;
142 }
143
144 static void
145 fu_altos_firmware_init (FuAltosFirmware *self)
146 {
147 }
148
149 FuAltosFirmware *
150 fu_altos_firmware_new (void)
151 {
152 FuAltosFirmware *self;
153 self = g_object_new (FU_TYPE_ALTOS_FIRMWARE, NULL);
154 return FU_ALTOS_FIRMWARE (self);
155 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __FU_ALTOS_FIRMWARE_H
22 #define __FU_ALTOS_FIRMWARE_H
23
24 #include <glib-object.h>
25
26 G_BEGIN_DECLS
27
28 #define FU_TYPE_ALTOS_FIRMWARE (fu_altos_firmware_get_type ())
29
30 G_DECLARE_FINAL_TYPE (FuAltosFirmware, fu_altos_firmware, FU, ALTOS_FIRMWARE, GObject)
31
32 FuAltosFirmware *fu_altos_firmware_new (void);
33 GBytes *fu_altos_firmware_get_data (FuAltosFirmware *self);
34 guint64 fu_altos_firmware_get_address (FuAltosFirmware *self);
35 gboolean fu_altos_firmware_parse (FuAltosFirmware *self,
36 GBytes *blob,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __FU_ALTOS_FIRMWARE_H */
3535 int
3636 main (int argc, char **argv)
3737 {
38
3938 gsize len;
40 guint i;
4139 g_autofree guint8 *data = NULL;
4240 g_autoptr(FuDeviceAltos) dev = NULL;
4341 g_autoptr(GBytes) fw = NULL;
6159 }
6260 g_usb_context_enumerate (usb_ctx);
6361 devices = g_usb_context_get_devices (usb_ctx);
64 for (i = 0; i < devices->len; i++) {
62 for (guint i = 0; i < devices->len; i++) {
6563 GUsbDevice *usb_dev_tmp = g_ptr_array_index (devices, i);
6664 g_autoptr(FuDeviceAltos) dev_tmp = fu_device_altos_new (usb_dev_tmp);
6765 if (dev_tmp == NULL)
2828 #include <termios.h>
2929 #include <errno.h>
3030
31 #include <libdfu/dfu.h>
32
31 #include "fu-altos-firmware.h"
3332 #include "fu-device-altos.h"
3433
3534 typedef struct
431430 return TRUE;
432431 }
433432
434 static gboolean
435 fu_device_check_firmware (FuDeviceAltos *device, DfuFirmware *firmware, GError **error)
436 {
437 FuDeviceAltosPrivate *priv = GET_PRIVATE (device);
438 DfuElement *dfu_element;
439 DfuImage *dfu_image;
440
441 /* get default image */
442 dfu_image = dfu_firmware_get_image_default (firmware);
443 if (dfu_image == NULL) {
444 g_set_error_literal (error,
445 FWUPD_ERROR,
446 FWUPD_ERROR_INVALID_FILE,
447 "no firmware image");
448 return FALSE;
449 }
450
451 /* get default element */
452 dfu_element = dfu_image_get_element_default (dfu_image);
453 if (dfu_element == NULL) {
454 g_set_error_literal (error,
455 FWUPD_ERROR,
456 FWUPD_ERROR_INVALID_FILE,
457 "no firmware element");
458 return FALSE;
459 }
460
461 /* check the start address */
462 if (dfu_element_get_address (dfu_element) != priv->addr_base) {
463 g_set_error (error,
464 FWUPD_ERROR,
465 FWUPD_ERROR_INVALID_FILE,
466 "start address not correct %" G_GUINT32_FORMAT ":"
467 "%" G_GUINT64_FORMAT,
468 dfu_element_get_address (dfu_element),
469 priv->addr_base);
470 return FALSE;
471 }
472
473 /* success */
474 return TRUE;
475 }
476
477433 gboolean
478434 fu_device_altos_write_firmware (FuDeviceAltos *device,
479435 GBytes *fw,
483439 GError **error)
484440 {
485441 FuDeviceAltosPrivate *priv = GET_PRIVATE (device);
442 GBytes *fw_blob;
486443 const gchar *data;
487444 const gsize data_len;
488445 guint flash_len;
489 g_autoptr(DfuFirmware) firmware = NULL;
490 g_autoptr(GBytes) fw_blob = NULL;
446 g_autoptr(FuAltosFirmware) altos_firmware = NULL;
447 g_autoptr(FuDeviceLocker) locker = NULL;
491448 g_autoptr(GString) buf = g_string_new (NULL);
492449
493450 /* check kind */
519476 }
520477
521478 /* load ihex blob */
522 firmware = dfu_firmware_new ();
523 if (!dfu_firmware_parse_data (firmware, fw,
524 DFU_FIRMWARE_PARSE_FLAG_NONE,
525 error)) {
526 return FALSE;
527 }
528 if (!fu_device_check_firmware (device, firmware, error))
529 return FALSE;
530
531 /* convert from ihex to a blob */
532 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
533 fw_blob = dfu_firmware_write_data (firmware, error);
534 if (fw_blob == NULL)
535 return FALSE;
479 altos_firmware = fu_altos_firmware_new ();
480 if (!fu_altos_firmware_parse (altos_firmware, fw, error))
481 return FALSE;
482
483 /* check the start address */
484 if (fu_altos_firmware_get_address (altos_firmware) != priv->addr_base) {
485 g_set_error (error,
486 FWUPD_ERROR,
487 FWUPD_ERROR_INVALID_FILE,
488 "start address not correct %" G_GUINT64_FORMAT ":"
489 "%" G_GUINT64_FORMAT,
490 fu_altos_firmware_get_address (altos_firmware),
491 priv->addr_base);
492 return FALSE;
493 }
536494
537495 /* check firmware will fit */
496 fw_blob = fu_altos_firmware_get_data (altos_firmware);
538497 data = g_bytes_get_data (fw_blob, (gsize *) &data_len);
539498 if (data_len > flash_len) {
540499 g_set_error (error,
546505 }
547506
548507 /* open tty for download */
549 if (!fu_device_altos_tty_open (device, error))
508 locker = fu_device_locker_new_full (device,
509 (FuDeviceLockerFunc) fu_device_altos_tty_open,
510 (FuDeviceLockerFunc) fu_device_altos_tty_close,
511 error);
512 if (locker == NULL)
550513 return FALSE;
551514 for (guint i = 0; i < flash_len; i+= 0x100) {
552515 g_autoptr(GString) str = NULL;
615578 progress_data);
616579 }
617580
618 /* done */
619 if (!fu_device_altos_tty_close (device, error))
620 return FALSE;
621
622581 /* success */
623582 return TRUE;
624583 }
631590 {
632591 FuDeviceAltosPrivate *priv = GET_PRIVATE (device);
633592 guint flash_len;
593 g_autoptr(FuDeviceLocker) locker = NULL;
634594 g_autoptr(GString) buf = g_string_new (NULL);
635595
636596 /* check kind */
662622 }
663623
664624 /* open tty for download */
665 if (!fu_device_altos_tty_open (device, error))
625 locker = fu_device_locker_new_full (device,
626 (FuDeviceLockerFunc) fu_device_altos_tty_open,
627 (FuDeviceLockerFunc) fu_device_altos_tty_close,
628 error);
629 if (locker == NULL)
666630 return NULL;
667631 for (guint i = priv->addr_base; i < priv->addr_bound; i+= 0x100) {
668632 g_autoptr(GString) str = NULL;
681645 g_string_append_len (buf, str->str, str->len);
682646 }
683647
684 /* done */
685 if (!fu_device_altos_tty_close (device, error))
686 return NULL;
687
688648 /* success */
689649 return g_bytes_new (buf->str, buf->len);
690650 }
693653 fu_device_altos_probe_bootloader (FuDeviceAltos *device, GError **error)
694654 {
695655 FuDeviceAltosPrivate *priv = GET_PRIVATE (device);
656 g_autoptr(FuDeviceLocker) locker = NULL;
696657 g_auto(GStrv) lines = NULL;
697658 g_autoptr(GString) str = NULL;
698659
699660 /* get tty for upload */
700661 if (!fu_device_altos_find_tty (device, error))
701662 return FALSE;
702 if (!fu_device_altos_tty_open (device, error))
663 locker = fu_device_locker_new_full (device,
664 (FuDeviceLockerFunc) fu_device_altos_tty_open,
665 (FuDeviceLockerFunc) fu_device_altos_tty_close,
666 error);
667 if (locker == NULL)
703668 return FALSE;
704669
705670 /* get the version information */
706671 if (!fu_device_altos_tty_write (device, "v\n", -1, error))
707672 return FALSE;
708673 str = fu_device_altos_tty_read (device, 100, -1, error);
709 if (str == NULL) {
710 fu_device_altos_tty_close (device, NULL);
711 return FALSE;
712 }
674 if (str == NULL)
675 return FALSE;
713676
714677 /* parse each line */
715678 lines = g_strsplit_set (str->str, "\n\r", -1);
751714 g_debug ("unknown data: '%s'", lines[i]);
752715 }
753716
754 /* done */
755 if (!fu_device_altos_tty_close (device, error))
756 return FALSE;
757
758717 return TRUE;
759718 }
760719
772731 const gchar *version_prefix = "ChaosKey-hw-1.0-sw-";
773732 guint8 version_idx;
774733 g_autofree gchar *version = NULL;
734 g_autoptr(FuDeviceLocker) locker = NULL;
775735
776736 /* open */
777 if (!g_usb_device_open (priv->usb_device, error))
737 locker = fu_device_locker_new (priv->usb_device, error);
738 if (locker == NULL)
778739 return FALSE;
779740
780741 /* get string */
782743 version = g_usb_device_get_string_descriptor (priv->usb_device,
783744 version_idx,
784745 error);
785 if (version == NULL) {
786 g_usb_device_close (priv->usb_device, NULL);
746 if (version == NULL)
787747 return FALSE;
788 }
789748 if (!g_str_has_prefix (version, version_prefix)) {
790749 g_set_error (error,
791750 FWUPD_ERROR,
792751 FWUPD_ERROR_NOT_SUPPORTED,
793752 "not a ChaosKey v1.0 device: %s",
794753 version);
795 g_usb_device_close (priv->usb_device, NULL);
796754 return FALSE;
797755 }
798756 fu_device_set_version (FU_DEVICE (device), version + 19);
799 if (!g_usb_device_close (priv->usb_device, error))
800 return FALSE;
801757 }
802758
803759 /* success */
836792 break;
837793 }
838794
795 /* set one line summary */
796 fu_device_set_summary (FU_DEVICE (device),
797 "A USB hardware random number generator");
798
839799 /* add USB\VID_0000&PID_0000 */
840800 devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X",
841801 g_usb_device_get_vid (priv->usb_device),
11
22 shared_module('fu_plugin_altos',
33 sources : [
4 'fu-altos-firmware.c',
45 'fu-plugin-altos.c',
56 'fu-device-altos.c',
67 ],
1314 install_dir: plugin_dir,
1415 c_args : cargs,
1516 dependencies : [
17 gudev,
18 libelf,
1619 plugin_deps,
17 gudev,
18 ],
19 link_with : [
20 dfu,
2120 ],
2221 )
2322
2423 executable(
2524 'fu-altos-tool',
2625 sources : [
26 'fu-altos-firmware.c',
2727 'fu-altos-tool.c',
2828 'fu-device-altos.c',
2929 ],
3333 include_directories('../../src'),
3434 ],
3535 dependencies : [
36 gudev,
37 libelf,
3638 plugin_deps,
37 gudev,
3839 ],
3940 link_with : [
40 dfu,
4141 fwupd,
4242 libfwupdprivate,
4343 ],
427427
428428 dev = fu_device_new ();
429429 fu_device_set_id (dev, "/dev/mei");
430 fu_device_set_vendor (dev, "Intel Corporation");
430431 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
432 fu_device_add_icon (dev, "computer");
431433 if (!amt_get_provisioning_state (ctx, &state, error))
432434 return NULL;
433435 switch (state) {
444446 fu_device_set_name (dev, "Intel AMT (unknown)");
445447 break;
446448 }
449 fu_device_set_summary (dev, "Hardware and firmware technology for remote "
450 "out-of-band management");
447451
448452 /* add guid */
449453 memcpy (&uu, &ctx->guid, 16);
109109 guint16 micro;
110110 guint16 minor;
111111 guint8 idx;
112 g_autoptr(FuDeviceLocker) locker = NULL;
112113 g_autoptr(GError) error = NULL;
113114 g_autofree gchar *version = NULL;
114115
115116 /* try to get the version without claiming interface */
116 if (!g_usb_device_open (item->usb_device, &error)) {
117 locker = fu_device_locker_new (item->usb_device, &error);
118 if (locker == NULL) {
117119 g_debug ("Failed to open, polling: %s", error->message);
118120 return;
119121 }
128130 item->got_version = TRUE;
129131 g_debug ("obtained fwver using extension '%s'", tmp);
130132 fu_device_set_version (item->device, tmp);
131 goto out;
133 return;
132134 }
133135 }
134 g_usb_device_close (item->usb_device, NULL);
135136
136137 /* attempt to open the device and get the serial number */
137138 if (!ch_device_open (item->usb_device, &error)) {
144145 CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE,
145146 NULL, &error)) {
146147 g_warning ("Failed to get serial: %s", error->message);
147 goto out;
148 return;
148149 }
149150
150151 /* got things the old fashioned way */
152153 version = g_strdup_printf ("%i.%i.%i", major, minor, micro);
153154 g_debug ("obtained fwver using API '%s'", version);
154155 fu_device_set_version (item->device, version);
155
156 out:
157 /* we're done here */
158 g_clear_error (&error);
159 if (!g_usb_device_close (item->usb_device, &error))
160 g_debug ("Failed to close: %s", error->message);
161156 }
162157
163158 gboolean
440435 item->usb_device = g_object_ref (device);
441436 item->device = fu_device_new ();
442437 fu_device_set_id (item->device, device_key);
438 fu_device_set_vendor (item->device, "Hughski Limited");
439 fu_device_set_vendor_id (item->device, "USB:0x273F");
443440 fu_device_set_equivalent_id (item->device,
444441 g_usb_device_get_platform_id (device));
445442 fu_device_add_guid (item->device, ch_device_get_guid (device));
443 fu_device_add_icon (item->device, "colorimeter-colorhug");
446444 fu_device_add_flag (item->device, FWUPD_DEVICE_FLAG_UPDATABLE);
447445
448446 /* try to get the serial number -- if opening failed then
467465 case CH_DEVICE_MODE_FIRMWARE:
468466 case CH_DEVICE_MODE_LEGACY:
469467 fu_device_set_name (item->device, "ColorHug");
468 fu_device_set_summary (item->device,
469 "An open source display colorimeter");
470470 break;
471471 case CH_DEVICE_MODE_BOOTLOADER2:
472472 case CH_DEVICE_MODE_FIRMWARE2:
473473 fu_device_set_name (item->device, "ColorHug2");
474 fu_device_set_summary (item->device,
475 "An open source display colorimeter");
474476 break;
475477 case CH_DEVICE_MODE_BOOTLOADER_PLUS:
476478 case CH_DEVICE_MODE_FIRMWARE_PLUS:
477479 fu_device_set_name (item->device, "ColorHug+");
480 fu_device_set_summary (item->device,
481 "An open source spectrophotometer");
478482 break;
479483 case CH_DEVICE_MODE_BOOTLOADER_ALS:
480484 case CH_DEVICE_MODE_FIRMWARE_ALS:
481485 fu_device_set_name (item->device, "ColorHugALS");
486 fu_device_set_summary (item->device,
487 "An open source ambient light sensor");
482488 break;
483489 default:
484490 fu_device_set_name (item->device, "ColorHug??");
4545 } ADDR_UNION;
4646 #pragma pack()
4747
48 /* supported host related GUIDs */
49 #define TBT_GPIO_GUID EFI_GUID (0x2EFD333F, 0x65EC, 0x41D3, 0x86D3, 0x08, 0xF0, 0x9F, 0x4F, 0xB1, 0x14)
50 #define MST_GPIO_GUID EFI_GUID (0xF24F9bE4, 0x2a13, 0x4344, 0xBC05, 0x01, 0xCE, 0xF7, 0xDA, 0xEF, 0x92)
51
5248 static void
5349 _dell_smi_obj_free (FuDellSmiObj *obj)
5450 {
5753 }
5854
5955 G_DEFINE_AUTOPTR_CLEANUP_FUNC (FuDellSmiObj, _dell_smi_obj_free);
60
61 gboolean
62 fu_dell_supported (void)
63 {
64 guint8 dell_supported = 0;
65 struct smbios_struct *de_table;
66
67 de_table = smbios_get_next_struct_by_handle (0, 0xDE00);
68 if (!de_table)
69 return FALSE;
70 smbios_struct_get_data (de_table, &(dell_supported), 0x00, sizeof(guint8));
71 if (dell_supported != 0xDE)
72 return FALSE;
73 return TRUE;
74 }
7556
7657 /* don't actually clear if we're testing */
7758 gboolean
8667 }
8768 return TRUE;
8869 }
89
9070
9171 gboolean
9272 fu_dell_execute_smi (FuDellSmiObj *obj)
255235 return type;
256236 }
257237
258 static gboolean
238 gboolean
259239 fu_dell_toggle_dock_mode (FuDellSmiObj *smi_obj, guint32 new_mode,
260240 guint32 dock_location, GError **error)
261241 {
280260 return TRUE;
281261 }
282262
283 static gboolean
263 gboolean
284264 fu_dell_toggle_host_mode (FuDellSmiObj *smi_obj, const efi_guid_t guid, int mode)
285265 {
286266 gint ret;
311291 return FALSE;
312292 }
313293 return TRUE;
314 }
315
316
317 gboolean
318 fu_dell_toggle_flash (FuDevice *device, GError **error, gboolean enable)
319 {
320 guint32 dock_location;
321 const gchar *tmp;
322 g_autoptr (FuDellSmiObj) smi_obj = NULL;
323
324 if (device) {
325 if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE))
326 return TRUE;
327 tmp = fu_device_get_plugin (device);
328 if (!((g_strcmp0 (tmp, "thunderbolt") == 0) ||
329 (g_strcmp0 (tmp, "synapticsmst") == 0)))
330 return TRUE;
331 g_debug ("preparing/cleaning update for %s", tmp);
332 }
333
334 /* Dock MST Hub / TBT Controller */
335 smi_obj = g_malloc0 (sizeof(FuDellSmiObj));
336 smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS);
337
338 if (fu_dell_detect_dock (smi_obj, &dock_location)) {
339 if (!fu_dell_toggle_dock_mode (smi_obj, enable, dock_location,
340 error))
341 g_debug ("unable to change dock to %d", enable);
342 else
343 g_debug ("Toggled dock mode to %d", enable);
344 }
345
346 /* System MST hub / TBT controller */
347 if (!fu_dell_toggle_host_mode (smi_obj, TBT_GPIO_GUID, enable))
348 g_debug ("Unable to toggle TBT GPIO to %d", enable);
349 else
350 g_debug ("Toggled TBT GPIO to %d", enable);
351 if (!fu_dell_toggle_host_mode (smi_obj, MST_GPIO_GUID, enable))
352 g_debug("Unable to toggle MST hub GPIO to %d", enable);
353 else
354 g_debug("Toggled MST hub GPIO to %d", enable);
355
356 return TRUE;
357 }
294 }
2222 #define __FU_DELL_COMMON_H
2323
2424 #include "fu-device.h"
25 #include <smbios_c/smbios.h>
2625 #include <smbios_c/smi.h>
2726 #include <smbios_c/obj/smi.h>
2827 #include <efivar.h>
8786 } CABLE_TYPE;
8887
8988 gboolean
90 fu_dell_supported (void);
91
92 gboolean
9389 fu_dell_clear_smi (FuDellSmiObj *obj);
9490
9591 guint32
114110 fu_dell_get_cable_type (guint8 type);
115111
116112 gboolean
117 fu_dell_toggle_flash (FuDevice *device, GError **error, gboolean enable);
113 fu_dell_toggle_dock_mode (FuDellSmiObj *smi_obj, guint32 new_mode,
114 guint32 dock_location, GError **error);
115
116 gboolean
117 fu_dell_toggle_host_mode (FuDellSmiObj *smi_obj, const efi_guid_t guid, int mode);
118118
119119 /* SMI return values used */
120120 #define SMI_SUCCESS 0
+0
-55
plugins/dell/fu-dell-tool.c less more
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Mario Limonciello <mario_limonciello@dell.com>
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "config.h"
22
23 #include "fu-dell-common.h"
24 #include <glib/gstdio.h>
25
26 static void usage(void) {
27 g_print ("This application forces TBT/MST controllers to flashing mode on Dell systems\n\n");
28 g_print ("Call with an argument of '1' to force flashing mode\n");
29 g_print ("Call with an argument of '0' to return to normal mode\n");
30 }
31
32 int main(int argc, char *argv[]) {
33 int ret;
34 int mode;
35 if (argc == 2) {
36 if (strcmp(argv[1], "1") == 0)
37 mode = DACI_FLASH_MODE_FLASH;
38 else if (strcmp(argv[1], "0") == 0)
39 mode = DACI_FLASH_MODE_USER;
40 else {
41 usage();
42 return -1;
43 }
44 ret = fu_dell_toggle_flash(NULL, NULL, mode);
45 if (!ret) {
46 g_print("Failed to set device to %d (ret %d)\n", mode, ret);
47 return -1;
48 }
49 g_print("Turned device to %d\n", mode);
50 }
51 else
52 usage();
53 return 0;
54 }
2525 #include <appstream-glib.h>
2626 #include <glib/gstdio.h>
2727 #include <smbios_c/system_info.h>
28 #include <smbios_c/smbios.h>
29 #include <smbios_c/smi.h>
30 #include <smbios_c/obj/smi.h>
3128 #include <string.h>
3229 #include <unistd.h>
3330 #include <fcntl.h>
9289 #define UNIV_CBL_DESC "Universal Cable"
9390 #define TBT_CBL_DESC "Thunderbolt Cable"
9491
92 /* supported host related GUIDs */
93 #define MST_GPIO_GUID EFI_GUID (0xF24F9bE4, 0x2a13, 0x4344, 0xBC05, 0x01, 0xCE, 0xF7, 0xDA, 0xEF, 0x92)
94
9595 /**
9696 * Devices that should allow modeswitching
9797 */
105105 0x07B0, 0x07B1, 0x07B2, 0x07B4, 0x07B7,
106106 0x07B8, 0x07B9, 0x07BE, 0x07BF, 0x077A,
107107 0x07CF};
108 /**
109 * Dell device types to run
110 */
111 static guint8 enclosure_whitelist [] = { 0x03, /* desktop */
112 0x04, /* low profile desktop */
113 0x06, /* mini tower */
114 0x07, /* tower */
115 0x08, /* portable */
116 0x09, /* laptop */
117 0x0A, /* notebook */
118 0x0D, /* AIO */
119 0x1E, /* tablet */
120 0x1F, /* convertible */
121 0x21, /* IoT gateway */
122 0x22, /* embedded PC */};
123
124 /**
125 * System blacklist
126 */
127 static guint16 system_blacklist [] = { 0x071E, /* latitude 5414 */
128 0x077A, /* xps 9365 */ };
129
130 /**
131 * Systems containing host MST device
132 */
133 static guint16 systems_host_mst [] = { 0x062d, /* Latitude E7250 */
134 0x062e, /* Latitude E7450 */
135 0x062a, /* Latitude E5250 */
136 0x062b, /* Latitude E5450 */
137 0x062c, /* Latitude E5550 */
138 0x06db, /* Latitude E7270 */
139 0x06dc, /* Latitude E7470 */
140 0x06dd, /* Latitude E5270 */
141 0x06de, /* Latitude E5470 */
142 0x06df, /* Latitude E5570 */
143 0x06e0, /* Precision 3510 */
144 0x071d, /* Latitude Rugged 7214 */
145 0x071e, /* Latitude Rugged 5414 */
146 0x071c, /* Latitude Rugged 7414 */};
147
108148 static void
109149 _fwup_resource_iter_free (fwup_resource_iter *iter)
110150 {
112152 }
113153
114154 G_DEFINE_AUTOPTR_CLEANUP_FUNC (fwup_resource_iter, _fwup_resource_iter_free);
155
156 static guint16
157 fu_dell_get_system_id (FuPlugin *plugin)
158 {
159 const gchar *system_id_str = NULL;
160 guint16 system_id = 0;
161 gchar *endptr = NULL;
162
163 system_id_str = fu_plugin_get_dmi_value (plugin,
164 FU_HWIDS_KEY_PRODUCT_SKU);
165 if (system_id_str != NULL)
166 system_id = g_ascii_strtoull (system_id_str, &endptr, 16);
167 if (system_id == 0 || endptr == system_id_str)
168 system_id = (guint16) sysinfo_get_dell_system_id ();
169
170 return system_id;
171 }
172
173 static gboolean
174 fu_dell_host_mst_supported (FuPlugin *plugin)
175 {
176 guint16 system_id = fu_dell_get_system_id (plugin);
177
178 system_id = fu_dell_get_system_id (plugin);
179 if (system_id == 0)
180 return FALSE;
181 for (guint i = 0; i < G_N_ELEMENTS (systems_host_mst); i++)
182 if (systems_host_mst[i] == system_id)
183 return TRUE;
184 return FALSE;
185 }
186
187 static gboolean
188 fu_dell_supported (FuPlugin *plugin)
189 {
190 GBytes *de_table = NULL;
191 GBytes *enclosure = NULL;
192 guint16 system_id = 0;
193 const guint8 *value;
194 gsize len;
195
196 /* make sure that Dell SMBIOS methods are available */
197 de_table = fu_plugin_get_smbios_data (plugin, 0xDE);
198 if (de_table == NULL)
199 return FALSE;
200 value = g_bytes_get_data (de_table, &len);
201 if (len == 0)
202 return FALSE;
203 if (*value != 0xDE)
204 return FALSE;
205
206 /* skip blacklisted hw */
207 system_id = fu_dell_get_system_id (plugin);
208 if (system_id == 0)
209 return FALSE;
210 for (guint i = 0; i < G_N_ELEMENTS (system_blacklist); i++) {
211 if (system_blacklist[i] == system_id)
212 return FALSE;
213 }
214
215 /* only run on intended Dell hw types */
216 enclosure = fu_plugin_get_smbios_data (plugin,
217 FU_SMBIOS_STRUCTURE_TYPE_CHASSIS);
218 if (enclosure == NULL)
219 return FALSE;
220 value = g_bytes_get_data (enclosure, &len);
221 if (len == 0)
222 return FALSE;
223 for (guint i = 0; i < G_N_ELEMENTS (enclosure_whitelist); i++) {
224 if (enclosure_whitelist[i] == value[0])
225 return TRUE;
226 }
227
228 return FALSE;
229 }
115230
116231 static gboolean
117232 fu_plugin_dell_match_dock_component (const gchar *query_str,
158273 }
159274
160275 static AsVersionParseFlag
161 fu_plugin_dell_get_version_format (void)
162 {
163 g_autofree gchar *content = NULL;
276 fu_plugin_dell_get_version_format (FuPlugin *plugin)
277 {
278 const gchar *content = NULL;
279
280 content = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER);
281 if (content == NULL)
282 return AS_VERSION_PARSE_FLAG_USE_TRIPLET;
164283
165284 /* any vendors match */
166 if (!g_file_get_contents ("/sys/class/dmi/id/sys_vendor",
167 &content, NULL, NULL))
168 return AS_VERSION_PARSE_FLAG_USE_TRIPLET;
169 g_strchomp (content);
170285 for (guint i = 0; quirk_table[i].sys_vendor != NULL; i++) {
171286 if (g_strcmp0 (content, quirk_table[i].sys_vendor) == 0)
172287 return quirk_table[i].flags;
251366 dock_name = g_strdup_printf ("Dell %s %s", dock_type,
252367 component_desc);
253368 fu_device_set_id (dev, dock_id);
369 fu_device_set_vendor (dev, "Dell Inc.");
254370 fu_device_set_name (dev, dock_name);
371 if (type == DOCK_TYPE_TB16) {
372 fu_device_set_summary (dev, "A Thunderbolt™ 3 docking station");
373 } else if (type == DOCK_TYPE_WD15) {
374 fu_device_set_summary (dev, "A USB type-C docking station");
375 }
376 fu_device_add_icon (dev, "computer");
255377 fu_device_add_guid (dev, guid_str);
256378 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
257379 if (version != NULL) {
320442 g_debug ("Dock cable type: %" G_GUINT32_FORMAT, dock_info->cable_type);
321443 g_debug ("Dock location: %d", dock_info->location);
322444 g_debug ("Dock component count: %d", dock_info->component_count);
323 parse_flags = fu_plugin_dell_get_version_format ();
445 parse_flags = fu_plugin_dell_get_version_format (plugin);
324446
325447 for (guint i = 0; i < dock_info->component_count; i++) {
326448 g_autofree gchar *fw_str = NULL;
432554 gboolean
433555 fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error)
434556 {
435 struct smbios_struct *de_table;
436 guint16 completion_code = 0xFFFF;
557 GBytes *de_table = NULL;
437558 const gchar *tmp = NULL;
438
439 /* look at offset 0x06 for identifier meaning completion code */
440 de_table = smbios_get_next_struct_by_type (0, 0xDE);
441 smbios_struct_get_data (de_table, &completion_code, 0x06, sizeof (guint16));
442
443 if (completion_code == DELL_SUCCESS) {
559 const guint16 *completion_code;
560 gsize len;
561
562 de_table = fu_plugin_get_smbios_data (plugin, 0xDE);
563 completion_code = g_bytes_get_data (de_table, &len);
564 if (len < 8) {
565 g_set_error (error,
566 FWUPD_ERROR,
567 FWUPD_ERROR_INTERNAL,
568 "ERROR: Unable to read results of %s: %" G_GSIZE_FORMAT " < 8",
569 fu_device_get_name (device), len);
570 return FALSE;
571 }
572
573 /* look at byte offset 0x06 for identifier meaning completion code */
574 if (completion_code[3] == DELL_SUCCESS) {
444575 fu_device_set_update_state (device, FWUPD_UPDATE_STATE_SUCCESS);
445576 } else {
446577 fu_device_set_update_state (device, FWUPD_UPDATE_STATE_FAILED);
447 switch (completion_code) {
578 switch (completion_code[3]) {
448579 case DELL_CONSISTENCY_FAIL:
449580 tmp = "The image failed one or more consistency checks.";
450581 break;
507638 gboolean can_switch_modes = FALSE;
508639 g_autofree gchar *pretty_tpm_name_alt = NULL;
509640 g_autofree gchar *pretty_tpm_name = NULL;
510 g_autofree gchar *product_name = NULL;
511641 g_autofree gchar *tpm_guid_raw_alt = NULL;
512642 g_autofree gchar *tpm_guid_alt = NULL;
513643 g_autofree gchar *tpm_guid = NULL;
518648 struct tpm_status *out = NULL;
519649 g_autoptr (FuDevice) dev_alt = NULL;
520650 g_autoptr (FuDevice) dev = NULL;
651 const gchar *product_name = NULL;
521652
522653 fu_dell_clear_smi (data->smi_obj);
523654 out = (struct tpm_status *) data->smi_obj->output;
558689 return FALSE;
559690 }
560691
561 if (!data->smi_obj->fake_smbios)
562 system_id = (guint16) sysinfo_get_dell_system_id ();
563 else
692 system_id = fu_dell_get_system_id (plugin);
693 if (data->smi_obj->fake_smbios)
564694 can_switch_modes = data->can_switch_modes;
695 else if (system_id == 0)
696 return FALSE;
565697
566698 for (guint i = 0; i < G_N_ELEMENTS (tpm_switch_whitelist); i++) {
567699 if (tpm_switch_whitelist[i] == system_id) {
584716
585717 /* make it clear that the TPM is a discrete device of the product */
586718 if (!data->smi_obj->fake_smbios) {
587 if (!g_file_get_contents ("/sys/class/dmi/id/product_name",
588 &product_name,NULL, NULL)) {
589 g_set_error_literal (error,
590 FWUPD_ERROR,
591 FWUPD_ERROR_NOT_SUPPORTED,
592 "Unable to read product information");
593 return FALSE;
594 }
595 g_strchomp (product_name);
719 product_name = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME);
596720 }
597721 pretty_tpm_name = g_strdup_printf ("%s TPM %s", product_name, tpm_mode);
598722 pretty_tpm_name_alt = g_strdup_printf ("%s TPM %s", product_name, tpm_mode_alt);
601725 dev = fu_device_new ();
602726 fu_device_set_id (dev, tpm_id);
603727 fu_device_add_guid (dev, tpm_guid);
728 fu_device_set_vendor (dev, "Dell Inc.");
604729 fu_device_set_name (dev, pretty_tpm_name);
730 fu_device_set_summary (dev, "Platform TPM device");
605731 fu_device_set_version (dev, version_str);
606732 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
607733 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
734 fu_device_add_icon (dev, "computer");
608735 if (out->flashes_left > 0) {
609736 if (fu_plugin_dell_capsule_supported (plugin)) {
610737 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
619746 dev_alt = fu_device_new ();
620747 fu_device_set_id (dev_alt, tpm_id_alt);
621748 fu_device_add_guid (dev_alt, tpm_guid_alt);
749 fu_device_set_vendor (dev, "Dell Inc.");
622750 fu_device_set_name (dev_alt, pretty_tpm_name_alt);
751 fu_device_set_summary (dev_alt, "Alternate mode for platform TPM device");
623752 fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_INTERNAL);
624753 fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_REQUIRE_AC);
625754 fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_LOCKED);
755 fu_device_add_icon (dev_alt, "computer");
626756 fu_device_set_alternate (dev_alt, dev);
627757
628758 /* If TPM is not owned and at least 1 flash left allow mode switching
711841 const gchar *name = NULL;
712842 gint rc;
713843 guint flashes_left;
714 #ifdef HAVE_UEFI_GUID
715844 const gchar *guidstr = NULL;
716845 efi_guid_t guid;
717 #endif
718846
719847 /* test the flash counter
720848 * - devices with 0 left at setup aren't allowed offline updates
751879 */
752880 fwup_resource_iter_create (&iter);
753881 fwup_resource_iter_next (iter, &re);
754 #ifdef HAVE_UEFI_GUID
755882 guidstr = fu_device_get_guid_default (device);
756883 rc = efi_str_to_guid (guidstr, &guid);
757884 if (rc < 0) {
770897 strerror (rc));
771898 return FALSE;
772899 }
773 #endif
900
774901 /* NOTE: if there are problems with this working, adjust the
775902 * GUID in the capsule header to match something in ESRT.
776903 * This won't actually cause any bad behavior because the real
781908 g_bytes_get_data (blob_fw, NULL),
782909 g_bytes_get_size (blob_fw));
783910 if (rc < 0) {
784 g_autoptr(GString) err_string = g_string_new ("Dell firmware update failed:\n");
785
786 rc = 1;
787 for (int i =0; rc > 0; i++) {
788 char *filename = NULL;
789 char *function = NULL;
790 char *message = NULL;
791 int line = 0;
792 int err = 0;
793
794 rc = efi_error_get (i, &filename, &function, &line, &message, &err);
795 if (rc <= 0)
796 break;
797 g_string_append_printf (err_string,
798 "{error #%d} %s:%d %s(): %s: %s \n",
799 i, filename, line, function, message, strerror(err));
800 }
801 g_set_error (error,
802 FWUPD_ERROR,
803 FWUPD_ERROR_NOT_SUPPORTED,
804 "%s",
805 err_string->str);
806 return FALSE;
807 }
911 g_autoptr(GString) err_string = g_string_new ("Dell firmware update failed:\n");
912
913 rc = 1;
914 for (int i = 0; rc > 0; i++) {
915 char *filename = NULL;
916 char *function = NULL;
917 char *message = NULL;
918 int line = 0;
919 int err = 0;
920
921 rc = efi_error_get (i, &filename, &function, &line, &message, &err);
922 if (rc <= 0)
923 break;
924 g_string_append_printf (err_string,
925 "{error #%d} %s:%d %s(): %s: %s \n",
926 i, filename, line, function, message, strerror(err));
927 }
928 g_set_error (error,
929 FWUPD_ERROR,
930 FWUPD_ERROR_NOT_SUPPORTED,
931 "%s",
932 err_string->str);
933 return FALSE;
934 }
808935 return TRUE;
809936 }
810937
814941 /* thunderbolt plugin */
815942 if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") == 0 &&
816943 fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) {
817 /* prevent thunderbolt controllers in the system from going away */
818 fu_device_set_metadata_boolean (device,
819 FU_DEVICE_METADATA_TBT_CAN_FORCE_POWER,
820 TRUE);
821944 /* fix VID/DID of safe mode devices */
822945 if (fu_device_get_metadata_boolean (device, FU_DEVICE_METADATA_TBT_IS_SAFE_MODE)) {
823946 g_autofree gchar *vendor_id = NULL;
824947 g_autofree gchar *device_id = NULL;
948 guint16 system_id = 0;
949
825950 vendor_id = g_strdup ("TBT:0x00D4");
951 system_id = fu_dell_get_system_id (plugin);
952 if (system_id == 0)
953 return;
826954 /* the kernel returns lowercase in sysfs, need to match it */
827955 device_id = g_strdup_printf ("TBT-%04x%04x", 0x00d4u,
828 (unsigned) sysinfo_get_dell_system_id ());
956 (unsigned) system_id);
829957 fu_device_set_vendor_id (device, vendor_id);
830958 fu_device_add_guid (device, device_id);
831959 fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
833961 }
834962 }
835963
964 static gboolean
965 fu_dell_toggle_flash (FuPlugin *plugin, FuDevice *device,
966 gboolean enable, GError **error)
967 {
968 FuPluginData *data = fu_plugin_get_data (plugin);
969 gboolean has_host = fu_dell_host_mst_supported (plugin);
970 gboolean has_dock;
971 guint32 dock_location;
972 const gchar *tmp;
973
974 if (device) {
975 if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE))
976 return TRUE;
977 tmp = fu_device_get_plugin (device);
978 if (g_strcmp0 (tmp, "synapticsmst") != 0)
979 return TRUE;
980 g_debug ("preparing/cleaning update for %s", tmp);
981 }
982
983 /* Dock MST Hub */
984 has_dock = fu_dell_detect_dock (data->smi_obj, &dock_location);
985 if (has_dock) {
986 if (!fu_dell_toggle_dock_mode (data->smi_obj, enable,
987 dock_location, error))
988 g_debug ("unable to change dock to %d", enable);
989 else
990 g_debug ("Toggled dock mode to %d", enable);
991 }
992
993 /* System MST hub */
994 if (has_host) {
995 if (!fu_dell_toggle_host_mode (data->smi_obj, MST_GPIO_GUID, enable))
996 g_debug ("Unable to toggle MST hub GPIO to %d", enable);
997 else
998 g_debug ("Toggled MST hub GPIO to %d", enable);
999 }
1000
1001 #if defined (HAVE_SYNAPTICS)
1002 /* set a delay to allow OS response to settling the GPIO change */
1003 if (enable && device == NULL && (has_dock || has_host))
1004 fu_plugin_set_coldplug_delay (plugin, DELL_FLASH_MODE_DELAY * 1000);
1005 #endif
1006 return TRUE;
1007 }
1008
8361009 gboolean
8371010 fu_plugin_update_prepare (FuPlugin *plugin,
838 FuDevice *device,
839 GError **error)
840 {
841 return fu_dell_toggle_flash (device, error, TRUE);
1011 FuDevice *device,
1012 GError **error)
1013 {
1014
1015 return fu_dell_toggle_flash (plugin, device, TRUE, error);
8421016 }
8431017
8441018 gboolean
8451019 fu_plugin_update_cleanup (FuPlugin *plugin,
846 FuDevice *device,
847 GError **error)
848 {
849 return fu_dell_toggle_flash (device, error, FALSE);
1020 FuDevice *device,
1021 GError **error)
1022 {
1023 return fu_dell_toggle_flash (plugin, device , FALSE, error);
8501024 }
8511025
8521026 gboolean
8531027 fu_plugin_coldplug_prepare (FuPlugin *plugin, GError **error)
8541028 {
855 return fu_dell_toggle_flash (NULL, error, TRUE);
1029 return fu_dell_toggle_flash (plugin, NULL, TRUE, error);
8561030 }
8571031
8581032 gboolean
8591033 fu_plugin_coldplug_cleanup (FuPlugin *plugin, GError **error)
8601034 {
861 return fu_dell_toggle_flash (NULL, error, FALSE);
1035 return fu_dell_toggle_flash (plugin, NULL, FALSE, error);
8621036 }
8631037
8641038 void
8671041 FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
8681042
8691043 data->smi_obj = g_malloc0 (sizeof (FuDellSmiObj));
870 if (fu_dell_supported ())
1044 if (fu_dell_supported (plugin))
8711045 data->smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS);
8721046 data->smi_obj->fake_smbios = FALSE;
8731047 if (g_getenv ("FWUPD_DELL_FAKE_SMBIOS") != NULL)
8961070 return TRUE;
8971071 }
8981072
899 if (!fu_dell_supported ()) {
1073 if (!fu_dell_supported (plugin)) {
9001074 g_set_error (error,
9011075 FWUPD_ERROR,
9021076 FWUPD_ERROR_NOT_SUPPORTED,
9131087 plugin);
9141088 }
9151089
916 #if defined (HAVE_SYNAPTICS) || defined (HAVE_THUNDERBOLT)
917 /* set a delay to allow OS response to settling the GPIO change */
918 fu_plugin_set_coldplug_delay (plugin, DELL_FLASH_MODE_DELAY * 1000);
919 #endif
920
9211090 return TRUE;
9221091 }
9231092
2121 libsmbios_c,
2222 fwup,
2323 ],
24 )
25
26 executable(
27 'fu-dell-tool',
28 sources : [
29 'fu-dell-tool.c',
30 'fu-dell-common.c',
31 ],
32 include_directories : [
33 include_directories('../..'),
34 include_directories('../../src'),
35 include_directories('../../libfwupd'),
36 ],
37 dependencies : [
38 plugin_deps,
39 efivar,
40 libsmbios_c,
41 ],
42 link_with : [
43 fwupd,
44 ],
45 c_args : cargs,
4624 )
4725
4826 if get_option('enable-tests')
55
66 Device Firmware Update is a standard that allows USB devices to be easily and
77 safely updated by any operating system.
8
9 DFU support is supported directly by this project with the embedded libdfu
10 library.
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-cipher-xtea.h"
26
27 #include "fwupd-error.h"
28
29 #define XTEA_DELTA 0x9e3779b9
30 #define XTEA_NUM_ROUNDS 32
31
32 static void
33 dfu_cipher_buf_to_uint32 (const guint8 *buf, guint buflen, guint32 *array)
34 {
35 guint32 tmp_le;
36 for (guint i = 0; i < buflen / 4; i++) {
37 memcpy (&tmp_le, &buf[i * 4], 4);
38 array[i] = GUINT32_FROM_LE (tmp_le);
39 }
40 }
41
42 static void
43 dfu_cipher_uint32_to_buf (guint8 *buf, guint buflen, const guint32 *array)
44 {
45 guint32 tmp_le;
46 for (guint i = 0; i < buflen / 4; i++) {
47 tmp_le = GUINT32_TO_LE (array[i]);
48 memcpy (&buf[i * 4], &tmp_le, 4);
49 }
50 }
51
52 static gboolean
53 dfu_tool_parse_xtea_key (const gchar *key, guint32 *keys, GError **error)
54 {
55 gsize key_len;
56
57 /* too long */
58 key_len = strlen (key);
59 if (key_len > 32) {
60 g_set_error (error,
61 FWUPD_ERROR,
62 FWUPD_ERROR_NOT_SUPPORTED,
63 "Key string too long at %" G_GSIZE_FORMAT " chars, max 16",
64 key_len);
65 return FALSE;
66 }
67
68 /* parse 4x32b values or generate a hash */
69 if (key_len == 32) {
70 for (guint8 i = 0; i < 4; i++) {
71 gchar buf[] = "xxxxxxxx";
72 gchar *endptr;
73 guint64 tmp;
74
75 /* copy to 4-char buf (with NUL) */
76 memcpy (buf, key + i*8, 8);
77 tmp = g_ascii_strtoull (buf, &endptr, 16);
78 if (endptr && endptr[0] != '\0') {
79 g_set_error (error,
80 FWUPD_ERROR,
81 FWUPD_ERROR_NOT_SUPPORTED,
82 "Failed to parse key '%s'", key);
83 return FALSE;
84 }
85 keys[3-i] = (guint32) tmp;
86 }
87 } else {
88 gsize buf_len = 16;
89 guint8 buf[16];
90 g_autoptr(GChecksum) csum = NULL;
91 csum = g_checksum_new (G_CHECKSUM_MD5);
92 g_checksum_update (csum, (const guchar *) key, (gssize) key_len);
93 g_checksum_get_digest (csum, buf, &buf_len);
94 g_assert (buf_len == 16);
95 dfu_cipher_buf_to_uint32 (buf, buf_len, keys);
96 }
97
98 /* success */
99 g_debug ("using XTEA key %04x%04x%04x%04x",
100 keys[3], keys[2], keys[1], keys[0]);
101 return TRUE;
102 }
103
104 /**
105 * dfu_cipher_decrypt_xtea: (skip)
106 * @key: a XTEA key
107 * @data: data to parse
108 * @length: length of @data
109 * @error: a #GError, or %NULL
110 *
111 * Decrypt a buffer using XTEA.
112 *
113 * Returns: %TRUE for success
114 **/
115 gboolean
116 dfu_cipher_decrypt_xtea (const gchar *key,
117 guint8 *data,
118 guint32 length,
119 GError **error)
120 {
121 guint32 sum;
122 guint32 v0;
123 guint32 v1;
124 guint32 chunks = length / 4;
125 guint32 keys[4];
126 g_autofree guint32 *tmp = NULL;
127
128 /* sanity check */
129 if (length < 8) {
130 g_set_error (error,
131 FWUPD_ERROR,
132 FWUPD_ERROR_NOT_SUPPORTED,
133 "8 bytes data required, got %" G_GUINT32_FORMAT,
134 length);
135 return FALSE;
136 }
137 if (length % 4 != 0) {
138 g_set_error (error,
139 FWUPD_ERROR,
140 FWUPD_ERROR_NOT_SUPPORTED,
141 "Multiples of 4 bytes required, got %" G_GUINT32_FORMAT,
142 length);
143 return FALSE;
144 }
145
146 /* parse key */
147 if (!dfu_tool_parse_xtea_key (key, keys, error))
148 return FALSE;
149
150 /* allocate a buffer that can be addressed in 4-byte chunks */
151 tmp = g_new0 (guint32, chunks);
152 dfu_cipher_buf_to_uint32 (data, length, tmp);
153
154 /* process buffer using XTEA keys */
155 for (guint j = 0; j < chunks; j += 2) {
156 v0 = tmp[j];
157 v1 = tmp[j+1];
158 sum = XTEA_DELTA * XTEA_NUM_ROUNDS;
159 for (guint8 i = 0; i < XTEA_NUM_ROUNDS; i++) {
160 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keys[(sum >> 11) & 3]);
161 sum -= XTEA_DELTA;
162 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keys[sum & 3]);
163 }
164 tmp[j] = v0;
165 tmp[j+1] = v1;
166 }
167
168 /* copy the temp buffer back to data */
169 dfu_cipher_uint32_to_buf (data, length, tmp);
170 return TRUE;
171 }
172
173 /**
174 * dfu_cipher_encrypt_xtea: (skip)
175 * @key: a XTEA key
176 * @data: data to parse
177 * @length: length of @data
178 * @error: a #GError, or %NULL
179 *
180 * Encrypt a buffer using XTEA.
181 *
182 * Returns: %TRUE for success
183 **/
184 gboolean
185 dfu_cipher_encrypt_xtea (const gchar *key,
186 guint8 *data,
187 guint32 length,
188 GError **error)
189 {
190 guint32 sum;
191 guint32 v0;
192 guint32 v1;
193 guint32 chunks = length / 4;
194 guint32 keys[4];
195 g_autofree guint32 *tmp = NULL;
196
197 /* sanity check */
198 if (length < 8) {
199 g_set_error (error,
200 FWUPD_ERROR,
201 FWUPD_ERROR_NOT_SUPPORTED,
202 "8 bytes data required, got %" G_GUINT32_FORMAT,
203 length);
204 return FALSE;
205 }
206 if (length % 4 != 0) {
207 g_set_error (error,
208 FWUPD_ERROR,
209 FWUPD_ERROR_NOT_SUPPORTED,
210 "Multiples of 4 bytes required, got %" G_GUINT32_FORMAT,
211 length);
212 return FALSE;
213 }
214
215 /* parse key */
216 if (!dfu_tool_parse_xtea_key (key, keys, error))
217 return FALSE;
218
219 /* allocate a buffer that can be addressed in 4-byte chunks */
220 tmp = g_new0 (guint32, chunks);
221 dfu_cipher_buf_to_uint32 (data, length, tmp);
222
223 /* process buffer using XTEA keys */
224 for (guint j = 0; j < chunks; j += 2) {
225 sum = 0;
226 v0 = tmp[j];
227 v1 = tmp[j+1];
228 for (guint8 i = 0; i < XTEA_NUM_ROUNDS; i++) {
229 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keys[sum & 3]);
230 sum += XTEA_DELTA;
231 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keys[(sum >> 11) & 3]);
232 }
233 tmp[j] = v0;
234 tmp[j+1] = v1;
235 }
236
237 /* copy the temp buffer back to data */
238 dfu_cipher_uint32_to_buf (data, length, tmp);
239 return TRUE;
240 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_XTEA_H
22 #define __DFU_FORMAT_XTEA_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 gboolean dfu_cipher_encrypt_xtea (const gchar *key,
30 guint8 *data,
31 guint32 length,
32 GError **error);
33 gboolean dfu_cipher_decrypt_xtea (const gchar *key,
34 guint8 *data,
35 guint32 length,
36 GError **error);
37
38 G_END_DECLS
39
40 #endif /* __DFU_FORMAT_XTEA_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-common
23 * @short_description: Common functions for DFU
24 *
25 * These helper objects allow converting from enum values to strings.
26 */
27
28 #include "config.h"
29
30 #include "dfu-common.h"
31
32 /**
33 * dfu_state_to_string:
34 * @state: a #DfuState, e.g. %DFU_STATE_DFU_MANIFEST
35 *
36 * Converts an enumerated value to a string.
37 *
38 * Return value: a string
39 **/
40 const gchar *
41 dfu_state_to_string (DfuState state)
42 {
43 if (state == DFU_STATE_APP_IDLE)
44 return "appIDLE";
45 if (state == DFU_STATE_APP_DETACH)
46 return "appDETACH";
47 if (state == DFU_STATE_DFU_IDLE)
48 return "dfuIDLE";
49 if (state == DFU_STATE_DFU_DNLOAD_SYNC)
50 return "dfuDNLOAD-SYNC";
51 if (state == DFU_STATE_DFU_DNBUSY)
52 return "dfuDNBUSY";
53 if (state == DFU_STATE_DFU_DNLOAD_IDLE)
54 return "dfuDNLOAD-IDLE";
55 if (state == DFU_STATE_DFU_MANIFEST_SYNC)
56 return "dfuMANIFEST-SYNC";
57 if (state == DFU_STATE_DFU_MANIFEST)
58 return "dfuMANIFEST";
59 if (state == DFU_STATE_DFU_MANIFEST_WAIT_RESET)
60 return "dfuMANIFEST-WAIT-RESET";
61 if (state == DFU_STATE_DFU_UPLOAD_IDLE)
62 return "dfuUPLOAD-IDLE";
63 if (state == DFU_STATE_DFU_ERROR)
64 return "dfuERROR";
65 return NULL;
66 }
67
68 /**
69 * dfu_status_to_string:
70 * @status: a #DfuStatus, e.g. %DFU_STATUS_ERR_ERASE
71 *
72 * Converts an enumerated value to a string.
73 *
74 * Return value: a string
75 **/
76 const gchar *
77 dfu_status_to_string (DfuStatus status)
78 {
79 if (status == DFU_STATUS_OK)
80 return "OK";
81 if (status == DFU_STATUS_ERR_TARGET)
82 return "errTARGET";
83 if (status == DFU_STATUS_ERR_FILE)
84 return "errFILE";
85 if (status == DFU_STATUS_ERR_WRITE)
86 return "errwrite";
87 if (status == DFU_STATUS_ERR_ERASE)
88 return "errERASE";
89 if (status == DFU_STATUS_ERR_CHECK_ERASED)
90 return "errCHECK_ERASED";
91 if (status == DFU_STATUS_ERR_PROG)
92 return "errPROG";
93 if (status == DFU_STATUS_ERR_VERIFY)
94 return "errVERIFY";
95 if (status == DFU_STATUS_ERR_ADDRESS)
96 return "errADDRESS";
97 if (status == DFU_STATUS_ERR_NOTDONE)
98 return "errNOTDONE";
99 if (status == DFU_STATUS_ERR_FIRMWARE)
100 return "errFIRMWARE";
101 if (status == DFU_STATUS_ERR_VENDOR)
102 return "errVENDOR";
103 if (status == DFU_STATUS_ERR_USBR)
104 return "errUSBR";
105 if (status == DFU_STATUS_ERR_POR)
106 return "errPOR";
107 if (status == DFU_STATUS_ERR_UNKNOWN)
108 return "errUNKNOWN";
109 if (status == DFU_STATUS_ERR_STALLDPKT)
110 return "errSTALLDPKT";
111 return NULL;
112 }
113
114 /**
115 * dfu_mode_to_string:
116 * @mode: a #DfuMode, e.g. %DFU_MODE_RUNTIME
117 *
118 * Converts an enumerated value to a string.
119 *
120 * Return value: a string
121 **/
122 const gchar *
123 dfu_mode_to_string (DfuMode mode)
124 {
125 if (mode == DFU_MODE_RUNTIME)
126 return "runtime";
127 if (mode == DFU_MODE_DFU)
128 return "DFU";
129 return NULL;
130 }
131
132 /**
133 * dfu_cipher_kind_to_string:
134 * @cipher_kind: a #DfuCipherKind, e.g. %DFU_CIPHER_KIND_XTEA
135 *
136 * Converts an enumerated value to a string.
137 *
138 * Return value: a string
139 **/
140 const gchar *
141 dfu_cipher_kind_to_string (DfuCipherKind cipher_kind)
142 {
143 if (cipher_kind == DFU_CIPHER_KIND_NONE)
144 return "none";
145 if (cipher_kind == DFU_CIPHER_KIND_XTEA)
146 return "xtea";
147 if (cipher_kind == DFU_CIPHER_KIND_RSA)
148 return "rsa";
149 return NULL;
150 }
151
152 /**
153 * dfu_version_to_string:
154 * @version: a #DfuVersion, e.g. %DFU_VERSION_DFU_1_1
155 *
156 * Converts an enumerated value to a string.
157 *
158 * Return value: a string
159 **/
160 const gchar *
161 dfu_version_to_string (DfuVersion version)
162 {
163 if (version == DFU_VERSION_DFU_1_0)
164 return "1.0";
165 if (version == DFU_VERSION_DFU_1_1)
166 return "1.1";
167 if (version == DFU_VERSION_DFUSE)
168 return "DfuSe";
169 return NULL;
170 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_COMMON_H
22 #define __DFU_COMMON_H
23
24 #include <glib.h>
25 #include <gusb.h>
26
27 G_BEGIN_DECLS
28
29 /**
30 * DfuRequest:
31 * @DFU_REQUEST_DETACH: Detach
32 * @DFU_REQUEST_DNLOAD: Download host-to-device
33 * @DFU_REQUEST_UPLOAD: Upload device-to-host
34 * @DFU_REQUEST_GETSTATUS: Get the device status
35 * @DFU_REQUEST_CLRSTATUS: Clear the device status
36 * @DFU_REQUEST_GETSTATE: Get the last set state
37 * @DFU_REQUEST_ABORT: Abort the current transfer
38 *
39 * The DFU request kinds.
40 **/
41 typedef enum {
42 DFU_REQUEST_DETACH = 0x00,
43 DFU_REQUEST_DNLOAD = 0x01,
44 DFU_REQUEST_UPLOAD = 0x02,
45 DFU_REQUEST_GETSTATUS = 0x03,
46 DFU_REQUEST_CLRSTATUS = 0x04,
47 DFU_REQUEST_GETSTATE = 0x05,
48 DFU_REQUEST_ABORT = 0x06,
49 /*< private >*/
50 DFU_REQUEST_LAST
51 } DfuRequest;
52
53 /**
54 * DfuStatus:
55 * @DFU_STATUS_OK: No error condition is present
56 * @DFU_STATUS_ERR_TARGET: File is not targeted for use by this device
57 * @DFU_STATUS_ERR_FILE: File is for this device but fails a verification test
58 * @DFU_STATUS_ERR_WRITE: Device is unable to write memory
59 * @DFU_STATUS_ERR_ERASE: Memory erase function failed
60 * @DFU_STATUS_ERR_CHECK_ERASED: Memory erase check failed
61 * @DFU_STATUS_ERR_PROG: Program memory function failed
62 * @DFU_STATUS_ERR_VERIFY: Programmed memory failed verification
63 * @DFU_STATUS_ERR_ADDRESS: Cannot program memory due to received address that isout of range
64 * @DFU_STATUS_ERR_NOTDONE: Received DFU_DNLOAD with wLength = 0 but data is incomplete
65 * @DFU_STATUS_ERR_FIRMWARE: Device firmware is corrupt
66 * @DFU_STATUS_ERR_VENDOR: iString indicates a vendor-specific error
67 * @DFU_STATUS_ERR_USBR: Device detected unexpected USB reset signaling
68 * @DFU_STATUS_ERR_POR: Device detected unexpected power on reset
69 * @DFU_STATUS_ERR_UNKNOWN: Something unexpected went wrong
70 * @DFU_STATUS_ERR_STALLDPKT: Device stalled an unexpected request
71 *
72 * The status enumerated kind.
73 **/
74 typedef enum {
75 DFU_STATUS_OK = 0x00,
76 DFU_STATUS_ERR_TARGET = 0x01,
77 DFU_STATUS_ERR_FILE = 0x02,
78 DFU_STATUS_ERR_WRITE = 0x03,
79 DFU_STATUS_ERR_ERASE = 0x04,
80 DFU_STATUS_ERR_CHECK_ERASED = 0x05,
81 DFU_STATUS_ERR_PROG = 0x06,
82 DFU_STATUS_ERR_VERIFY = 0x07,
83 DFU_STATUS_ERR_ADDRESS = 0x08,
84 DFU_STATUS_ERR_NOTDONE = 0x09,
85 DFU_STATUS_ERR_FIRMWARE = 0x0a,
86 DFU_STATUS_ERR_VENDOR = 0x0b,
87 DFU_STATUS_ERR_USBR = 0x0c,
88 DFU_STATUS_ERR_POR = 0x0d,
89 DFU_STATUS_ERR_UNKNOWN = 0x0e,
90 DFU_STATUS_ERR_STALLDPKT = 0x0f,
91 /*< private >*/
92 DFU_STATUS_LAST
93 } DfuStatus;
94
95 /**
96 * DfuState:
97 * @DFU_STATE_APP_IDLE: State 0
98 * @DFU_STATE_APP_DETACH: State 1
99 * @DFU_STATE_DFU_IDLE: State 2
100 * @DFU_STATE_DFU_DNLOAD_SYNC: State 3
101 * @DFU_STATE_DFU_DNBUSY: State 4
102 * @DFU_STATE_DFU_DNLOAD_IDLE: State 5
103 * @DFU_STATE_DFU_MANIFEST_SYNC: State 6
104 * @DFU_STATE_DFU_MANIFEST: State 7
105 * @DFU_STATE_DFU_MANIFEST_WAIT_RESET: State 8
106 * @DFU_STATE_DFU_UPLOAD_IDLE: State 9
107 * @DFU_STATE_DFU_ERROR: State 10
108 *
109 * The state enumerated kind.
110 **/
111 typedef enum {
112 DFU_STATE_APP_IDLE = 0x00,
113 DFU_STATE_APP_DETACH = 0x01,
114 DFU_STATE_DFU_IDLE = 0x02,
115 DFU_STATE_DFU_DNLOAD_SYNC = 0x03,
116 DFU_STATE_DFU_DNBUSY = 0x04,
117 DFU_STATE_DFU_DNLOAD_IDLE = 0x05,
118 DFU_STATE_DFU_MANIFEST_SYNC = 0x06,
119 DFU_STATE_DFU_MANIFEST = 0x07,
120 DFU_STATE_DFU_MANIFEST_WAIT_RESET = 0x08,
121 DFU_STATE_DFU_UPLOAD_IDLE = 0x09,
122 DFU_STATE_DFU_ERROR = 0x0a,
123 /*< private >*/
124 DFU_STATE_LAST
125 } DfuState;
126
127 /**
128 * DfuMode:
129 * @DFU_MODE_UNKNOWN: Unknown mode
130 * @DFU_MODE_RUNTIME: Runtime mode
131 * @DFU_MODE_DFU: Bootloader mode
132 *
133 * The mode enumerated kind.
134 **/
135 typedef enum {
136 DFU_MODE_UNKNOWN,
137 DFU_MODE_RUNTIME,
138 DFU_MODE_DFU,
139 /*< private >*/
140 DFU_MODE_LAST
141 } DfuMode;
142
143 /**
144 * DfuCipherKind:
145 * @DFU_CIPHER_KIND_NONE: No cipher detected
146 * @DFU_CIPHER_KIND_XTEA: XTEA cipher detected
147 * @DFU_CIPHER_KIND_RSA: RSA cipher detected
148 *
149 * The type of cipher used for transfering the firmware.
150 **/
151 typedef enum {
152 DFU_CIPHER_KIND_NONE,
153 DFU_CIPHER_KIND_XTEA,
154 DFU_CIPHER_KIND_RSA,
155 /*< private >*/
156 DFU_CIPHER_KIND_LAST
157 } DfuCipherKind;
158
159 /**
160 * DfuVersion:
161 * @DFU_VERSION_UNKNOWN: Format unknown
162 * @DFU_VERSION_DFU_1_0: DFU 1.0
163 * @DFU_VERSION_DFU_1_1: DFU 1.1
164 * @DFU_VERSION_DFUSE: DfuSe
165 *
166 * The known versions of the DFU standard in BCD format.
167 **/
168 typedef enum {
169 DFU_VERSION_UNKNOWN = 0,
170 DFU_VERSION_DFU_1_0 = 0x0100,
171 DFU_VERSION_DFU_1_1 = 0x0110,
172 DFU_VERSION_DFUSE = 0x011a,
173 /*< private >*/
174 DFU_VERSION_LAST
175 } DfuVersion;
176
177 #define DFU_METADATA_KEY_LICENSE "License"
178 #define DFU_METADATA_KEY_COPYRIGHT "Copyright"
179 #define DFU_METADATA_KEY_CIPHER_KIND "CipherKind"
180
181 const gchar *dfu_state_to_string (DfuState state);
182 const gchar *dfu_status_to_string (DfuStatus status);
183 const gchar *dfu_mode_to_string (DfuMode mode);
184 const gchar *dfu_cipher_kind_to_string (DfuCipherKind cipher_kind);
185 const gchar *dfu_version_to_string (DfuVersion version);
186
187 G_END_DECLS
188
189 #endif /* __DFU_COMMON_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-context
23 * @short_description: A system context for managing DFU-capable devices
24 *
25 * This object allows discovering and monitoring hotpluggable DFU devices.
26 *
27 * When using #DfuContext the device is given some time to re-enumerate after a
28 * detach or reset. This allows client programs to continue using the #DfuDevice
29 * without dealing with the device hotplug and the #GUsbDevice changing.
30 * Using this object may be easier than using GUsbContext directly.
31 *
32 * Please be aware that after device detach or reset the number of #DfuTarget
33 * objects may be different and so need to be re-requested.
34 *
35 * See also: #DfuDevice, #DfuTarget
36 */
37
38 #include "config.h"
39
40 #include "dfu-device-private.h"
41 #include "dfu-context.h"
42
43 #include "fwupd-error.h"
44
45 static void dfu_context_finalize (GObject *object);
46
47 typedef struct {
48 GUsbContext *usb_ctx;
49 GPtrArray *devices; /* of DfuContextItem */
50 guint timeout; /* in ms */
51 } DfuContextPrivate;
52
53 typedef struct {
54 DfuContext *context; /* not refcounted */
55 DfuDevice *device; /* not refcounted */
56 guint timeout_id;
57 gulong state_change_id;
58 } DfuContextItem;
59
60 enum {
61 SIGNAL_DEVICE_ADDED,
62 SIGNAL_DEVICE_REMOVED,
63 SIGNAL_DEVICE_CHANGED,
64 SIGNAL_LAST
65 };
66
67 static guint signals [SIGNAL_LAST] = { 0 };
68
69 G_DEFINE_TYPE_WITH_PRIVATE (DfuContext, dfu_context, G_TYPE_OBJECT)
70 #define GET_PRIVATE(o) (dfu_context_get_instance_private (o))
71
72 static void
73 dfu_context_device_free (DfuContextItem *item)
74 {
75 if (item->timeout_id > 0)
76 g_source_remove (item->timeout_id);
77 if (item->timeout_id > 0) {
78 g_signal_handler_disconnect (item->device,
79 item->state_change_id);
80 }
81 g_object_unref (item->device);
82 g_free (item);
83 }
84
85 static void
86 dfu_context_class_init (DfuContextClass *klass)
87 {
88 GObjectClass *object_class = G_OBJECT_CLASS (klass);
89
90 /**
91 * DfuContext::device-added:
92 * @context: the #DfuContext instance that emitted the signal
93 * @device: the #DfuDevice
94 *
95 * The ::device-added signal is emitted when a new DFU device is connected.
96 **/
97 signals [SIGNAL_DEVICE_ADDED] =
98 g_signal_new ("device-added",
99 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
100 G_STRUCT_OFFSET (DfuContextClass, device_added),
101 NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
102 G_TYPE_NONE, 1, DFU_TYPE_DEVICE);
103
104 /**
105 * DfuContext::device-removed:
106 * @context: the #DfuContext instance that emitted the signal
107 * @device: the #DfuDevice
108 *
109 * The ::device-removed signal is emitted when a DFU device is removed.
110 **/
111 signals [SIGNAL_DEVICE_REMOVED] =
112 g_signal_new ("device-removed",
113 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
114 G_STRUCT_OFFSET (DfuContextClass, device_removed),
115 NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
116 G_TYPE_NONE, 1, DFU_TYPE_DEVICE);
117
118 /**
119 * DfuContext::device-changed:
120 * @context: the #DfuContext instance that emitted the signal
121 * @device: the #DfuDevice
122 *
123 * The ::device-changed signal is emitted when a DFU device is changed,
124 * typically when it has detached or been reset.
125 **/
126 signals [SIGNAL_DEVICE_CHANGED] =
127 g_signal_new ("device-changed",
128 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
129 G_STRUCT_OFFSET (DfuContextClass, device_changed),
130 NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
131 G_TYPE_NONE, 1, DFU_TYPE_DEVICE);
132
133 object_class->finalize = dfu_context_finalize;
134 }
135
136 static gchar *
137 dfu_context_get_device_id (DfuDevice *device)
138 {
139 GUsbDevice *dev;
140 dev = dfu_device_get_usb_dev (device);
141 if (dev == NULL)
142 return g_strdup (dfu_device_get_platform_id (device));
143 return g_strdup_printf ("%04x:%04x [%s]",
144 g_usb_device_get_vid (dev),
145 g_usb_device_get_pid (dev),
146 g_usb_device_get_platform_id (dev));
147 }
148
149 static DfuContextItem *
150 dfu_context_find_item_by_platform_id (DfuContext *context, const gchar *platform_id)
151 {
152 DfuContextPrivate *priv = GET_PRIVATE (context);
153
154 /* do we have this device */
155 for (guint i = 0; i < priv->devices->len; i++) {
156 DfuContextItem *item = g_ptr_array_index (priv->devices, i);
157 if (g_strcmp0 (dfu_device_get_platform_id (item->device), platform_id) == 0)
158 return item;
159 }
160 return NULL;
161 }
162
163 static void
164 dfu_context_remove_item (DfuContextItem *item)
165 {
166 DfuContextPrivate *priv = GET_PRIVATE (item->context);
167 g_autofree gchar *device_id = NULL;
168
169 /* log something */
170 device_id = dfu_context_get_device_id (item->device);
171 g_debug ("%s was removed", device_id);
172
173 g_signal_emit (item->context, signals[SIGNAL_DEVICE_REMOVED], 0, item->device);
174 g_ptr_array_remove (priv->devices, item);
175 }
176
177 static gboolean
178 dfu_context_device_timeout_cb (gpointer user_data)
179 {
180 DfuContextItem *item = (DfuContextItem *) user_data;
181 g_autofree gchar *device_id = NULL;
182
183 /* bad firmware? */
184 device_id = dfu_context_get_device_id (item->device);
185 g_debug ("%s did not come back as a DFU capable device", device_id);
186 dfu_context_remove_item (item);
187 return FALSE;
188 }
189
190 static void
191 dfu_context_device_state_cb (DfuDevice *device, DfuState state, DfuContext *context)
192 {
193 g_autofree gchar *device_id = NULL;
194 device_id = dfu_context_get_device_id (device);
195 g_debug ("%s state now: %s", device_id, dfu_state_to_string (state));
196 g_signal_emit (context, signals[SIGNAL_DEVICE_CHANGED], 0, device);
197 }
198
199 static void
200 dfu_context_device_added_cb (GUsbContext *usb_context,
201 GUsbDevice *usb_device,
202 DfuContext *context)
203 {
204 DfuContextPrivate *priv = GET_PRIVATE (context);
205 DfuDevice *device;
206 DfuContextItem *item;
207 const gchar *platform_id;
208 g_autofree gchar *device_id = NULL;
209 g_autoptr(GError) error = NULL;
210
211 /* are we waiting for this device to come back? */
212 platform_id = g_usb_device_get_platform_id (usb_device);
213 item = dfu_context_find_item_by_platform_id (context, platform_id);
214 if (item != NULL) {
215 device_id = dfu_context_get_device_id (item->device);
216 if (item->timeout_id > 0) {
217 g_debug ("cancelling the remove timeout");
218 g_source_remove (item->timeout_id);
219 item->timeout_id = 0;
220 }
221
222 /* try and be helpful; we may be a daemon like fwupd watching a
223 * DFU device after dfu-tool or dfu-util has detached the
224 * device on th command line */
225 if (!dfu_device_set_new_usb_dev (item->device, usb_device, NULL, &error))
226 g_warning ("Failed to set new device: %s", error->message);
227
228 /* inform the UI */
229 g_signal_emit (context, signals[SIGNAL_DEVICE_CHANGED], 0, item->device);
230 g_debug ("device %s came back", device_id);
231 return;
232 }
233
234 /* is this a DFU-capable device */
235 device = dfu_device_new (usb_device);
236 if (device == NULL) {
237 g_debug ("device was not DFU capable");
238 return;
239 }
240
241 /* add */
242 item = g_new0 (DfuContextItem, 1);
243 item->context = context;
244 item->device = device;
245 item->state_change_id =
246 g_signal_connect (item->device, "state-changed",
247 G_CALLBACK (dfu_context_device_state_cb), context);
248 g_ptr_array_add (priv->devices, item);
249 g_signal_emit (context, signals[SIGNAL_DEVICE_ADDED], 0, device);
250 device_id = dfu_context_get_device_id (item->device);
251 g_debug ("device %s was added", device_id);
252 }
253
254 static void
255 dfu_context_device_removed_cb (GUsbContext *usb_context,
256 GUsbDevice *usb_device,
257 DfuContext *context)
258 {
259 DfuContextPrivate *priv = GET_PRIVATE (context);
260 DfuContextItem *item;
261 const gchar *platform_id;
262
263 /* find the item */
264 platform_id = g_usb_device_get_platform_id (usb_device);
265 item = dfu_context_find_item_by_platform_id (context, platform_id);
266 if (item == NULL)
267 return;
268
269 /* mark the backing USB device as invalid */
270 dfu_device_set_new_usb_dev (item->device, NULL, NULL, NULL);
271
272 /* this item has just detached */
273 if (item->timeout_id > 0)
274 g_source_remove (item->timeout_id);
275 item->timeout_id =
276 g_timeout_add (priv->timeout, dfu_context_device_timeout_cb, item);
277 }
278
279 static void
280 dfu_context_set_usb_context (DfuContext *context, GUsbContext *usb_ctx)
281 {
282 DfuContextPrivate *priv = GET_PRIVATE (context);
283 priv->usb_ctx = g_object_ref (usb_ctx);
284 g_signal_connect (priv->usb_ctx, "device-added",
285 G_CALLBACK (dfu_context_device_added_cb), context);
286 g_signal_connect (priv->usb_ctx, "device-removed",
287 G_CALLBACK (dfu_context_device_removed_cb), context);
288 }
289
290 static void
291 dfu_context_init (DfuContext *context)
292 {
293 DfuContextPrivate *priv = GET_PRIVATE (context);
294 priv->timeout = 5000;
295 priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_context_device_free);
296 }
297
298 static void
299 dfu_context_finalize (GObject *object)
300 {
301 DfuContext *context = DFU_CONTEXT (object);
302 DfuContextPrivate *priv = GET_PRIVATE (context);
303
304 g_ptr_array_unref (priv->devices);
305 g_object_unref (priv->usb_ctx);
306
307 G_OBJECT_CLASS (dfu_context_parent_class)->finalize (object);
308 }
309
310 /**
311 * dfu_context_new:
312 *
313 * Creates a new DFU context object.
314 *
315 * Return value: a new #DfuContext
316 **/
317 DfuContext *
318 dfu_context_new (void)
319 {
320 DfuContext *context;
321 g_autoptr(GUsbContext) usb_ctx = g_usb_context_new (NULL);
322 context = g_object_new (DFU_TYPE_CONTEXT, NULL);
323 dfu_context_set_usb_context (context, usb_ctx);
324 return context;
325 }
326
327 /**
328 * dfu_context_new_with_context:
329 * @usb_ctx: a #DfuContext
330 *
331 * Creates a new DFU context object.
332 *
333 * Return value: a new #DfuContext
334 **/
335 DfuContext *
336 dfu_context_new_with_context (GUsbContext *usb_ctx)
337 {
338 DfuContext *context;
339 g_return_val_if_fail (G_USB_IS_CONTEXT (usb_ctx), NULL);
340 context = g_object_new (DFU_TYPE_CONTEXT, NULL);
341 dfu_context_set_usb_context (context, usb_ctx);
342 return context;
343 }
344
345 /**
346 * dfu_context_get_timeout:
347 * @context: a #DfuContext
348 *
349 * Gets the wait-for-replug timeout.
350 *
351 * Return value: value in milliseconds
352 **/
353 guint
354 dfu_context_get_timeout (DfuContext *context)
355 {
356 DfuContextPrivate *priv = GET_PRIVATE (context);
357 g_return_val_if_fail (DFU_IS_CONTEXT (context), 0);
358 return priv->timeout;
359 }
360
361
362 /**
363 * dfu_context_set_timeout:
364 * @context: a #DfuContext
365 * @timeout: a timeout in milliseconds
366 *
367 * Sets the wait-for-replug timeout.
368 * This is the longest we will wait for a device to re-enumerate after
369 * disconnecting. Using longer values will result in any UI not updating in a
370 * good time, but using too short values will result in devices being removed
371 * and re-added as different #DfuDevice's.
372 **/
373 void
374 dfu_context_set_timeout (DfuContext *context, guint timeout)
375 {
376 DfuContextPrivate *priv = GET_PRIVATE (context);
377 g_return_if_fail (DFU_IS_CONTEXT (context));
378 priv->timeout = timeout;
379 }
380
381
382 /**
383 * dfu_context_enumerate:
384 * @context: a #DfuContext
385 * @error: a #GError, or %NULL
386 *
387 * Opens a DFU-capable context.
388 *
389 * Return value: %TRUE for success
390 **/
391 gboolean
392 dfu_context_enumerate (DfuContext *context, GError **error)
393 {
394 DfuContextPrivate *priv = GET_PRIVATE (context);
395 g_return_val_if_fail (DFU_IS_CONTEXT (context), FALSE);
396 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
397 g_usb_context_enumerate (priv->usb_ctx);
398 return TRUE;
399 }
400
401 /**
402 * dfu_context_get_devices:
403 * @context: a #DfuContext
404 *
405 * Gets all the DFU-capable devices on the system.
406 *
407 * Return value: (element-type DfuDevice) (transfer container): array of devices
408 **/
409 GPtrArray *
410 dfu_context_get_devices (DfuContext *context)
411 {
412 DfuContextPrivate *priv = GET_PRIVATE (context);
413 GPtrArray *devices;
414
415 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
416
417 devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
418 for (guint i = 0; i < priv->devices->len; i++) {
419 DfuContextItem *item = g_ptr_array_index (priv->devices, i);
420 g_ptr_array_add (devices, g_object_ref (item->device));
421 }
422 return devices;
423 }
424
425 /**
426 * dfu_context_get_device_by_vid_pid:
427 * @context: a #DfuContext
428 * @vid: a vendor ID
429 * @pid: a product ID
430 * @error: a #GError, or %NULL
431 *
432 * Finds a device in the context with a specific vendor:product ID.
433 * An error is returned if more than one device matches.
434 *
435 * Return value: (transfer full): a #DfuDevice for success, or %NULL for an error
436 **/
437 DfuDevice *
438 dfu_context_get_device_by_vid_pid (DfuContext *context,
439 guint16 vid, guint16 pid,
440 GError **error)
441 {
442 DfuContextPrivate *priv = GET_PRIVATE (context);
443 DfuDevice *device = NULL;
444
445 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
446 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
447
448 /* search all devices */
449 for (guint i = 0; i < priv->devices->len; i++) {
450
451 /* match */
452 DfuContextItem *item = g_ptr_array_index (priv->devices, i);
453 GUsbDevice *dev = dfu_device_get_usb_dev (item->device);
454 if (g_usb_device_get_vid (dev) == vid &&
455 g_usb_device_get_pid (dev) == pid) {
456 if (device != NULL) {
457 g_set_error (error,
458 FWUPD_ERROR,
459 FWUPD_ERROR_NOT_SUPPORTED,
460 "multiple device matches for %04x:%04x",
461 vid, pid);
462 return NULL;
463 }
464 device = item->device;
465 continue;
466 }
467 }
468 if (device == NULL) {
469 g_set_error (error,
470 FWUPD_ERROR,
471 FWUPD_ERROR_NOT_FOUND,
472 "no device matches for %04x:%04x",
473 vid, pid);
474 return NULL;
475 }
476 return g_object_ref (device);
477 }
478
479 /**
480 * dfu_context_get_device_by_platform_id:
481 * @context: a #DfuContext
482 * @platform_id: a platform ID
483 * @error: a #GError, or %NULL
484 *
485 * Finds a device in the context with a specific platform ID.
486 *
487 * Return value: (transfer full): a #DfuDevice for success, or %NULL for an error
488 **/
489 DfuDevice *
490 dfu_context_get_device_by_platform_id (DfuContext *context,
491 const gchar *platform_id,
492 GError **error)
493 {
494 DfuContextPrivate *priv = GET_PRIVATE (context);
495
496 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
497 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
498
499 /* search all devices */
500 for (guint i = 0; i < priv->devices->len; i++) {
501 DfuContextItem *item = g_ptr_array_index (priv->devices, i);
502 if (g_strcmp0 (dfu_device_get_platform_id (item->device),
503 platform_id) == 0) {
504 return g_object_ref (item->device);
505 }
506 }
507 g_set_error (error,
508 FWUPD_ERROR,
509 FWUPD_ERROR_NOT_FOUND,
510 "no device matches for %s",
511 platform_id);
512 return NULL;
513 }
514
515 /**
516 * dfu_context_get_device_default:
517 * @context: a #DfuContext
518 * @error: a #GError, or %NULL
519 *
520 * Gets the default device in the context.
521 * An error is returned if more than one device exists.
522 *
523 * Return value: (transfer full): a #DfuDevice for success, or %NULL for an error
524 **/
525 DfuDevice *
526 dfu_context_get_device_default (DfuContext *context, GError **error)
527 {
528 DfuContextPrivate *priv = GET_PRIVATE (context);
529 DfuContextItem *item;
530
531 g_return_val_if_fail (DFU_IS_CONTEXT (context), NULL);
532 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
533
534 /* none */
535 if (priv->devices->len == 0) {
536 g_set_error_literal (error,
537 FWUPD_ERROR,
538 FWUPD_ERROR_NOT_FOUND,
539 "no attached DFU device");
540 return NULL;
541 }
542
543 /* multiple */
544 if (priv->devices->len > 1) {
545 g_set_error_literal (error,
546 FWUPD_ERROR,
547 FWUPD_ERROR_NOT_SUPPORTED,
548 "more than one attached DFU device");
549 return NULL;
550 }
551 item = g_ptr_array_index (priv->devices, 0);
552 return g_object_ref (item->device);
553 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_CONTEXT_H
22 #define __DFU_CONTEXT_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-device.h"
29
30 G_BEGIN_DECLS
31
32 #define DFU_TYPE_CONTEXT (dfu_context_get_type ())
33 G_DECLARE_DERIVABLE_TYPE (DfuContext, dfu_context, DFU, CONTEXT, GObject)
34
35 struct _DfuContextClass
36 {
37 GObjectClass parent_class;
38 void (*device_added) (DfuContext *context,
39 DfuDevice *device);
40 void (*device_removed) (DfuContext *context,
41 DfuDevice *device);
42 void (*device_changed) (DfuContext *context,
43 DfuDevice *device);
44 /*< private >*/
45 /* Padding for future expansion */
46 void (*_dfu_context_reserved1) (void);
47 void (*_dfu_context_reserved2) (void);
48 void (*_dfu_context_reserved3) (void);
49 void (*_dfu_context_reserved4) (void);
50 void (*_dfu_context_reserved5) (void);
51 void (*_dfu_context_reserved6) (void);
52 void (*_dfu_context_reserved7) (void);
53 void (*_dfu_context_reserved8) (void);
54 void (*_dfu_context_reserved9) (void);
55 };
56
57 DfuContext *dfu_context_new (void);
58 DfuContext *dfu_context_new_with_context (GUsbContext *usb_ctx);
59 gboolean dfu_context_enumerate (DfuContext *context,
60 GError **error);
61 GPtrArray *dfu_context_get_devices (DfuContext *context);
62 guint dfu_context_get_timeout (DfuContext *context);
63 void dfu_context_set_timeout (DfuContext *context,
64 guint timeout);
65 DfuDevice *dfu_context_get_device_by_vid_pid (DfuContext *context,
66 guint16 vid,
67 guint16 pid,
68 GError **error);
69 DfuDevice *dfu_context_get_device_by_platform_id (DfuContext *context,
70 const gchar *platform_id,
71 GError **error);
72 DfuDevice *dfu_context_get_device_default (DfuContext *context,
73 GError **error);
74
75 G_END_DECLS
76
77 #endif /* __DFU_CONTEXT_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_DEVICE_PRIVATE_H
22 #define __DFU_DEVICE_PRIVATE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-device.h"
29
30 G_BEGIN_DECLS
31
32 #define DFU_DEVICE_REPLUG_TIMEOUT 5000 /* ms */
33
34 GUsbDevice *dfu_device_get_usb_dev (DfuDevice *device);
35
36 gboolean dfu_device_has_dfuse_support (DfuDevice *device);
37
38 void dfu_device_error_fixup (DfuDevice *device,
39 GCancellable *cancellable,
40 GError **error);
41 guint dfu_device_get_download_timeout (DfuDevice *device);
42 gchar *dfu_device_get_quirks_as_string (DfuDevice *device);
43 gboolean dfu_device_set_new_usb_dev (DfuDevice *device,
44 GUsbDevice *dev,
45 GCancellable *cancellable,
46 GError **error);
47 gboolean dfu_device_ensure_interface (DfuDevice *device,
48 GCancellable *cancellable,
49 GError **error);
50
51 G_END_DECLS
52
53 #endif /* __DFU_DEVICE_PRIVATE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-device
23 * @short_description: Object representing a DFU-capable device
24 *
25 * This object allows two things:
26 *
27 * - Downloading from the host to the device, optionally with
28 * verification using a DFU or DfuSe firmware file.
29 *
30 * - Uploading from the device to the host to a DFU or DfuSe firmware
31 * file. The file format is chosen automatically, with DfuSe being
32 * chosen if the device contains more than one target.
33 *
34 * See also: #DfuTarget, #DfuFirmware
35 */
36
37 #include "config.h"
38
39 #include <string.h>
40
41 #include "dfu-common.h"
42 #include "dfu-device-private.h"
43 #include "dfu-target-private.h"
44
45 #include "fu-device-locker.h"
46
47 #include "fwupd-error.h"
48
49 static void dfu_device_finalize (GObject *object);
50
51 typedef struct {
52 DfuDeviceAttributes attributes;
53 DfuDeviceQuirks quirks;
54 DfuMode mode;
55 DfuState state;
56 DfuStatus status;
57 FwupdStatus action_last;
58 GPtrArray *targets;
59 GUsbDevice *dev;
60 FuDeviceLocker *dev_locker;
61 gboolean open_new_dev; /* if set new GUsbDevice */
62 gboolean dfuse_supported;
63 gboolean done_upload_or_download;
64 gboolean claimed_interface;
65 gchar *display_name;
66 gchar *serial_number;
67 gchar *platform_id;
68 guint16 version;
69 guint16 runtime_pid;
70 guint16 runtime_vid;
71 guint16 runtime_release;
72 guint16 transfer_size;
73 guint8 iface_number;
74 guint dnload_timeout;
75 guint timeout_ms;
76 } DfuDevicePrivate;
77
78 enum {
79 SIGNAL_STATUS_CHANGED,
80 SIGNAL_STATE_CHANGED,
81 SIGNAL_PERCENTAGE_CHANGED,
82 SIGNAL_ACTION_CHANGED,
83 SIGNAL_LAST
84 };
85
86 static guint signals [SIGNAL_LAST] = { 0 };
87
88 G_DEFINE_TYPE_WITH_PRIVATE (DfuDevice, dfu_device, G_TYPE_OBJECT)
89 #define GET_PRIVATE(o) (dfu_device_get_instance_private (o))
90
91 static void
92 dfu_device_class_init (DfuDeviceClass *klass)
93 {
94 GObjectClass *object_class = G_OBJECT_CLASS (klass);
95
96 /**
97 * DfuDevice::status-changed:
98 * @device: the #DfuDevice instance that emitted the signal
99 * @status: the new #DfuStatus
100 *
101 * The ::status-changed signal is emitted when the status changes.
102 **/
103 signals [SIGNAL_STATUS_CHANGED] =
104 g_signal_new ("status-changed",
105 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
106 G_STRUCT_OFFSET (DfuDeviceClass, status_changed),
107 NULL, NULL, g_cclosure_marshal_VOID__UINT,
108 G_TYPE_NONE, 1, G_TYPE_UINT);
109
110 /**
111 * DfuDevice::state-changed:
112 * @device: the #DfuDevice instance that emitted the signal
113 * @state: the new #DfuState
114 *
115 * The ::state-changed signal is emitted when the state changes.
116 **/
117 signals [SIGNAL_STATE_CHANGED] =
118 g_signal_new ("state-changed",
119 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
120 G_STRUCT_OFFSET (DfuDeviceClass, state_changed),
121 NULL, NULL, g_cclosure_marshal_VOID__UINT,
122 G_TYPE_NONE, 1, G_TYPE_UINT);
123
124 /**
125 * DfuDevice::percentage-changed:
126 * @device: the #DfuDevice instance that emitted the signal
127 * @percentage: the new percentage
128 *
129 * The ::percentage-changed signal is emitted when the percentage changes.
130 **/
131 signals [SIGNAL_PERCENTAGE_CHANGED] =
132 g_signal_new ("percentage-changed",
133 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
134 G_STRUCT_OFFSET (DfuDeviceClass, percentage_changed),
135 NULL, NULL, g_cclosure_marshal_VOID__UINT,
136 G_TYPE_NONE, 1, G_TYPE_UINT);
137
138 /**
139 * DfuDevice::action-changed:
140 * @device: the #DfuDevice instance that emitted the signal
141 * @action: the new #FwupdStatus
142 *
143 * The ::action-changed signal is emitted when the high level action changes.
144 **/
145 signals [SIGNAL_ACTION_CHANGED] =
146 g_signal_new ("action-changed",
147 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
148 G_STRUCT_OFFSET (DfuDeviceClass, action_changed),
149 NULL, NULL, g_cclosure_marshal_VOID__UINT,
150 G_TYPE_NONE, 1, G_TYPE_UINT);
151
152 object_class->finalize = dfu_device_finalize;
153 }
154
155 static void
156 dfu_device_init (DfuDevice *device)
157 {
158 DfuDevicePrivate *priv = GET_PRIVATE (device);
159 priv->iface_number = 0xff;
160 priv->runtime_pid = 0xffff;
161 priv->runtime_vid = 0xffff;
162 priv->runtime_release = 0xffff;
163 priv->state = DFU_STATE_APP_IDLE;
164 priv->status = DFU_STATUS_OK;
165 priv->targets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
166 priv->timeout_ms = 1500;
167 priv->transfer_size = 64;
168 }
169
170 static void
171 dfu_device_set_action (DfuDevice *device, FwupdStatus action)
172 {
173 DfuDevicePrivate *priv = GET_PRIVATE (device);
174 if (action == priv->action_last)
175 return;
176 g_signal_emit (device, signals[SIGNAL_ACTION_CHANGED], 0, action);
177 priv->action_last = action;
178 }
179
180 /**
181 * dfu_device_get_transfer_size:
182 * @device: a #GUsbDevice
183 *
184 * Gets the transfer size in bytes.
185 *
186 * Return value: packet size, or 0 for unknown
187 **/
188 guint16
189 dfu_device_get_transfer_size (DfuDevice *device)
190 {
191 DfuDevicePrivate *priv = GET_PRIVATE (device);
192 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
193 return priv->transfer_size;
194 }
195
196 /**
197 * dfu_device_get_version:
198 * @device: a #GUsbDevice
199 *
200 * Gets the DFU specification version supported by the device.
201 *
202 * Return value: integer, or 0 for unknown, e.g. %DFU_VERSION_DFU_1_1
203 **/
204 guint16
205 dfu_device_get_version (DfuDevice *device)
206 {
207 DfuDevicePrivate *priv = GET_PRIVATE (device);
208 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
209 return priv->version;
210 }
211
212 /**
213 * dfu_device_get_download_timeout:
214 * @device: a #GUsbDevice
215 *
216 * Gets the download timeout in ms.
217 *
218 * Return value: delay, or 0 for unknown
219 **/
220 guint
221 dfu_device_get_download_timeout (DfuDevice *device)
222 {
223 DfuDevicePrivate *priv = GET_PRIVATE (device);
224 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
225 return priv->dnload_timeout;
226 }
227
228 /**
229 * dfu_device_set_transfer_size:
230 * @device: a #GUsbDevice
231 * @transfer_size: maximum packet size
232 *
233 * Sets the transfer size in bytes.
234 **/
235 void
236 dfu_device_set_transfer_size (DfuDevice *device, guint16 transfer_size)
237 {
238 DfuDevicePrivate *priv = GET_PRIVATE (device);
239 g_return_if_fail (DFU_IS_DEVICE (device));
240 priv->transfer_size = transfer_size;
241 }
242
243 static void
244 dfu_device_finalize (GObject *object)
245 {
246 DfuDevice *device = DFU_DEVICE (object);
247 DfuDevicePrivate *priv = GET_PRIVATE (device);
248
249 if (priv->dev_locker != NULL)
250 g_object_unref (priv->dev_locker);
251 if (priv->dev != NULL)
252 g_object_unref (priv->dev);
253 g_free (priv->display_name);
254 g_free (priv->serial_number);
255 g_free (priv->platform_id);
256 g_ptr_array_unref (priv->targets);
257
258 G_OBJECT_CLASS (dfu_device_parent_class)->finalize (object);
259 }
260
261 typedef struct __attribute__((packed)) {
262 guint8 bLength;
263 guint8 bDescriptorType;
264 guint8 bmAttributes;
265 guint16 wDetachTimeOut;
266 guint16 wTransferSize;
267 guint16 bcdDFUVersion;
268 } DfuFuncDescriptor;
269
270 static void
271 dfu_device_parse_iface_data (DfuDevice *device, GBytes *iface_data)
272 {
273 DfuDevicePrivate *priv = GET_PRIVATE (device);
274 const DfuFuncDescriptor *desc;
275 gsize iface_data_length;
276
277 /* parse the functional descriptor */
278 desc = g_bytes_get_data (iface_data, &iface_data_length);
279 if (iface_data_length != 0x09) {
280 g_warning ("interface found, but not the correct length for "
281 "functional data: %" G_GSIZE_FORMAT " bytes",
282 iface_data_length);
283 return;
284 }
285
286 /* check sanity */
287 if (desc->bLength != 0x09) {
288 g_warning ("DFU interface data has incorrect length: 0x%02x",
289 desc->bLength);
290 }
291
292 /* check transfer size */
293 priv->transfer_size = desc->wTransferSize;
294 if (priv->transfer_size == 0x0000) {
295 g_warning ("DFU transfer size invalid, using default: 0x%04x",
296 desc->wTransferSize);
297 priv->transfer_size = 64;
298 }
299
300 /* check DFU version */
301 priv->version = GUINT16_FROM_LE (desc->bcdDFUVersion);
302 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION) {
303 g_debug ("ignoring quirked DFU version");
304 } else {
305 if (priv->version == DFU_VERSION_DFU_1_0 ||
306 priv->version == DFU_VERSION_DFU_1_1) {
307 g_debug ("basic DFU, no DfuSe support");
308 priv->dfuse_supported = FALSE;
309 } else if (priv->version == DFU_VERSION_DFUSE) {
310 g_debug ("DfuSe support");
311 priv->dfuse_supported = TRUE;
312 } else {
313 g_warning ("DFU version is invalid: 0x%04x",
314 priv->version);
315 }
316 }
317
318 /* ST-specific */
319 if (priv->dfuse_supported &&
320 desc->bmAttributes & DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE)
321 priv->transfer_size = 0x1000;
322
323 /* get attributes about the DFU operation */
324 priv->attributes = desc->bmAttributes;
325 }
326
327 static gboolean
328 dfu_device_update_from_iface (DfuDevice *device, GUsbInterface *iface)
329 {
330 DfuMode target_mode = DFU_MODE_UNKNOWN;
331 DfuDevicePrivate *priv = GET_PRIVATE (device);
332
333 /* runtime */
334 if (g_usb_interface_get_protocol (iface) == 0x01)
335 target_mode = DFU_MODE_RUNTIME;
336
337 /* DFU */
338 if (g_usb_interface_get_protocol (iface) == 0x02)
339 target_mode = DFU_MODE_DFU;
340
341 /* the DSO Nano has uses 0 instead of 2 when in DFU target_mode */
342 if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO) &&
343 g_usb_interface_get_protocol (iface) == 0x00)
344 target_mode = DFU_MODE_DFU;
345
346 /* nothing found */
347 if (target_mode == DFU_MODE_UNKNOWN)
348 return FALSE;
349
350 /* in DFU mode, the interface is supposed to be 0 */
351 if (target_mode == DFU_MODE_DFU && g_usb_interface_get_number (iface) != 0)
352 g_warning ("iface has to be 0 in DFU mode, got 0x%02i",
353 g_usb_interface_get_number (iface));
354
355 /* some devices set the wrong mode */
356 if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_FORCE_DFU_MODE))
357 target_mode = DFU_MODE_DFU;
358
359 /* save for reset */
360 if (target_mode == DFU_MODE_RUNTIME ||
361 (priv->quirks & DFU_DEVICE_QUIRK_NO_PID_CHANGE)) {
362 priv->runtime_vid = g_usb_device_get_vid (priv->dev);
363 priv->runtime_pid = g_usb_device_get_pid (priv->dev);
364 priv->runtime_release = g_usb_device_get_release (priv->dev);
365 }
366
367 priv->mode = target_mode;
368 return TRUE;
369 }
370
371 static gboolean
372 dfu_device_add_targets (DfuDevice *device)
373 {
374 DfuDevicePrivate *priv = GET_PRIVATE (device);
375 g_autoptr(GPtrArray) ifaces = NULL;
376
377 /* add all DFU-capable targets */
378 ifaces = g_usb_device_get_interfaces (priv->dev, NULL);
379 if (ifaces == NULL)
380 return FALSE;
381 g_ptr_array_set_size (priv->targets, 0);
382 for (guint i = 0; i < ifaces->len; i++) {
383 GBytes *iface_data = NULL;
384 DfuTarget *target;
385 GUsbInterface *iface = g_ptr_array_index (ifaces, i);
386 if (g_usb_interface_get_class (iface) != G_USB_DEVICE_CLASS_APPLICATION_SPECIFIC)
387 continue;
388 if (g_usb_interface_get_subclass (iface) != 0x01)
389 continue;
390 target = dfu_target_new (device, iface);
391 if (target == NULL)
392 continue;
393
394 /* add target */
395 priv->iface_number = g_usb_interface_get_number (iface);
396 g_ptr_array_add (priv->targets, target);
397 dfu_device_update_from_iface (device, iface);
398
399 /* parse any interface data */
400 iface_data = g_usb_interface_get_extra (iface);
401 if (g_bytes_get_size (iface_data) > 0)
402 dfu_device_parse_iface_data (device, iface_data);
403 }
404
405 /* the device has no DFU runtime, so cheat */
406 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
407 if (priv->targets->len == 0) {
408 g_debug ("no DFU runtime, so faking device");
409 priv->iface_number = 0xff;
410 priv->runtime_vid = g_usb_device_get_vid (priv->dev);
411 priv->runtime_pid = g_usb_device_get_pid (priv->dev);
412 priv->runtime_release = g_usb_device_get_release (priv->dev);
413 priv->attributes = DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD |
414 DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD;
415 }
416 return TRUE;
417 }
418
419 return priv->targets->len > 0;
420 }
421
422 /**
423 * dfu_device_has_quirk: (skip)
424 * @device: A #DfuDevice
425 * @quirk: A #DfuDeviceQuirks
426 *
427 * Returns if a device has a specific quirk
428 *
429 * Return value: %TRUE if the device has this quirk
430 **/
431 gboolean
432 dfu_device_has_quirk (DfuDevice *device, DfuDeviceQuirks quirk)
433 {
434 DfuDevicePrivate *priv = GET_PRIVATE (device);
435 g_return_val_if_fail (DFU_IS_DEVICE (device), 0x0);
436 return (priv->quirks & quirk) > 0;
437 }
438
439 /**
440 * dfu_device_can_upload:
441 * @device: a #GUsbDevice
442 *
443 * Gets if the device can upload.
444 *
445 * Return value: %TRUE if the device can upload from device to host
446 **/
447 gboolean
448 dfu_device_can_upload (DfuDevice *device)
449 {
450 DfuDevicePrivate *priv = GET_PRIVATE (device);
451 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
452 return (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD) > 0;
453 }
454
455 /**
456 * dfu_device_can_download:
457 * @device: a #GUsbDevice
458 *
459 * Gets if the device can download.
460 *
461 * Return value: %TRUE if the device can download from host to device
462 **/
463 gboolean
464 dfu_device_can_download (DfuDevice *device)
465 {
466 DfuDevicePrivate *priv = GET_PRIVATE (device);
467 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
468 return (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD) > 0;
469 }
470
471 /**
472 * dfu_device_is_open:
473 * @device: a #GUsbDevice
474 *
475 * Gets if the device is currently open.
476 *
477 * Return value: %TRUE if the device is open
478 **/
479 gboolean
480 dfu_device_is_open (DfuDevice *device)
481 {
482 DfuDevicePrivate *priv = GET_PRIVATE (device);
483 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
484 return priv->dev_locker != NULL;
485 }
486
487 /**
488 * dfu_device_set_timeout:
489 * @device: a #DfuDevice
490 * @timeout_ms: the timeout in ms
491 *
492 * Sets the USB timeout to use when contacting the USB device.
493 **/
494 void
495 dfu_device_set_timeout (DfuDevice *device, guint timeout_ms)
496 {
497 DfuDevicePrivate *priv = GET_PRIVATE (device);
498 g_return_if_fail (DFU_IS_DEVICE (device));
499 priv->timeout_ms = timeout_ms;
500 }
501
502 /**
503 * dfu_device_get_mode:
504 * @device: a #GUsbDevice
505 *
506 * Gets the device mode.
507 *
508 * Return value: enumerated mode, e.g. %DFU_MODE_RUNTIME
509 **/
510 DfuMode
511 dfu_device_get_mode (DfuDevice *device)
512 {
513 DfuDevicePrivate *priv = GET_PRIVATE (device);
514 g_return_val_if_fail (DFU_IS_DEVICE (device), DFU_MODE_UNKNOWN);
515 return priv->mode;
516 }
517
518 /**
519 * dfu_device_get_timeout:
520 * @device: a #GUsbDevice
521 *
522 * Gets the device timeout.
523 *
524 * Return value: enumerated timeout in ms
525 **/
526 guint
527 dfu_device_get_timeout (DfuDevice *device)
528 {
529 DfuDevicePrivate *priv = GET_PRIVATE (device);
530 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
531 return priv->timeout_ms;
532 }
533
534 /**
535 * dfu_device_get_state:
536 * @device: a #GUsbDevice
537 *
538 * Gets the device state.
539 *
540 * Return value: enumerated state, e.g. %DFU_STATE_DFU_UPLOAD_IDLE
541 **/
542 DfuState
543 dfu_device_get_state (DfuDevice *device)
544 {
545 DfuDevicePrivate *priv = GET_PRIVATE (device);
546 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
547 return priv->state;
548 }
549
550 /**
551 * dfu_device_get_status:
552 * @device: a #GUsbDevice
553 *
554 * Gets the device status.
555 *
556 * Return value: enumerated status, e.g. %DFU_STATUS_ERR_ADDRESS
557 **/
558 DfuStatus
559 dfu_device_get_status (DfuDevice *device)
560 {
561 DfuDevicePrivate *priv = GET_PRIVATE (device);
562 g_return_val_if_fail (DFU_IS_DEVICE (device), 0);
563 return priv->status;
564 }
565
566 /**
567 * dfu_device_has_attribute: (skip)
568 * @device: A #DfuDevice
569 * @attribute: A #DfuDeviceAttributes, e.g. %DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD
570 *
571 * Returns if an attribute set for the device.
572 *
573 * Return value: %TRUE if the attribute is set
574 **/
575 gboolean
576 dfu_device_has_attribute (DfuDevice *device, DfuDeviceAttributes attribute)
577 {
578 DfuDevicePrivate *priv = GET_PRIVATE (device);
579 g_return_val_if_fail (DFU_IS_DEVICE (device), 0x0);
580 return (priv->attributes & attribute) > 0;
581 }
582
583 /**
584 * dfu_device_has_dfuse_support:
585 * @device: A #DfuDevice
586 *
587 * Returns is DfuSe is supported on a device.
588 *
589 * Return value: %TRUE for DfuSe
590 **/
591 gboolean
592 dfu_device_has_dfuse_support (DfuDevice *device)
593 {
594 DfuDevicePrivate *priv = GET_PRIVATE (device);
595 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
596 return priv->dfuse_supported;
597 }
598
599 static void
600 dfu_device_set_quirks (DfuDevice *device)
601 {
602 DfuDevicePrivate *priv = GET_PRIVATE (device);
603 guint16 vid, pid, release;
604
605 vid = g_usb_device_get_vid (priv->dev);
606 pid = g_usb_device_get_pid (priv->dev);
607 release = g_usb_device_get_release (priv->dev);
608
609 /* on PC platforms the DW1820A firmware is loaded at runtime and can't
610 * be stored on the device itself as the flash chip is unpopulated */
611 if (vid == 0x0a5c && pid == 0x6412)
612 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_RUNTIME;
613
614 /* Openmoko Freerunner / GTA02 */
615 if ((vid == 0x1d50 || vid == 0x1457) &&
616 pid >= 0x5117 && pid <= 0x5126)
617 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT |
618 DFU_DEVICE_QUIRK_NO_PID_CHANGE |
619 DFU_DEVICE_QUIRK_NO_DFU_RUNTIME |
620 DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD;
621
622 /* OpenPCD Reader */
623 if (vid == 0x16c0 && pid == 0x076b)
624 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
625
626 /* SIMtrace */
627 if (vid == 0x16c0 && pid == 0x0762)
628 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
629
630 /* OpenPICC */
631 if (vid == 0x16c0 && pid == 0x076c)
632 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
633
634 /* Siemens AG, PXM 40 & PXM 50 */
635 if (vid == 0x0908 && (pid == 0x02c4 || pid == 0x02c5) && release == 0x0)
636 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
637
638 /* Midiman M-Audio Transit */
639 if (vid == 0x0763 && pid == 0x2806)
640 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT;
641
642 /* the LPC DFU bootloader uses the wrong mode */
643 if (vid == 0x1fc9 && pid == 0x000c)
644 priv->quirks |= DFU_DEVICE_QUIRK_FORCE_DFU_MODE;
645
646 /* the Leaflabs Maple3 is known broken */
647 if (vid == 0x1eaf && pid == 0x0003 && release == 0x0200)
648 priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION;
649
650 /* m-stack DFU implementation */
651 if (vid == 0x273f && (pid == 0x1003 || pid == 0x100a))
652 priv->quirks |= DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD;
653
654 /* HydraBus */
655 if (vid == 0x1d50 && pid == 0x60a7)
656 priv->quirks |= DFU_DEVICE_QUIRK_NO_DFU_RUNTIME;
657
658 /* the DSO Nano has uses 0 instead of 2 when in DFU mode */
659 // quirks |= DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO;
660 }
661
662 /**
663 * dfu_device_new:
664 * @dev: A #GUsbDevice
665 *
666 * Creates a new DFU device object.
667 *
668 * Return value: a new #DfuDevice, or %NULL if @dev was not DFU-capable
669 **/
670 DfuDevice *
671 dfu_device_new (GUsbDevice *dev)
672 {
673 DfuDevicePrivate *priv;
674 DfuDevice *device;
675 device = g_object_new (DFU_TYPE_DEVICE, NULL);
676 priv = GET_PRIVATE (device);
677 priv->dev = g_object_ref (dev);
678 priv->platform_id = g_strdup (g_usb_device_get_platform_id (dev));
679
680 /* set any quirks on the device before adding targets */
681 dfu_device_set_quirks (device);
682
683 /* add each alternate interface, although typically there will
684 * be only one */
685 if (!dfu_device_add_targets (device)) {
686 g_object_unref (device);
687 return NULL;
688 }
689
690 return device;
691 }
692
693 /**
694 * dfu_device_get_targets:
695 * @device: a #DfuDevice
696 *
697 * Gets all the targets for this device.
698 *
699 * Return value: (transfer none) (element-type DfuTarget): #DfuTarget, or %NULL
700 **/
701 GPtrArray *
702 dfu_device_get_targets (DfuDevice *device)
703 {
704 DfuDevicePrivate *priv = GET_PRIVATE (device);
705 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
706 return priv->targets;
707 }
708
709 /**
710 * dfu_device_get_target_by_alt_setting:
711 * @device: a #DfuDevice
712 * @alt_setting: the setting used to find
713 * @error: a #GError, or %NULL
714 *
715 * Gets a target with a specific alternative setting.
716 *
717 * Return value: (transfer full): a #DfuTarget, or %NULL
718 **/
719 DfuTarget *
720 dfu_device_get_target_by_alt_setting (DfuDevice *device,
721 guint8 alt_setting,
722 GError **error)
723 {
724 DfuDevicePrivate *priv = GET_PRIVATE (device);
725
726 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
727 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
728
729 /* find by ID */
730 for (guint i = 0; i < priv->targets->len; i++) {
731 DfuTarget *target = g_ptr_array_index (priv->targets, i);
732 if (dfu_target_get_alt_setting (target) == alt_setting)
733 return g_object_ref (target);
734 }
735
736 /* failed */
737 g_set_error (error,
738 FWUPD_ERROR,
739 FWUPD_ERROR_NOT_FOUND,
740 "No target with alt-setting %i",
741 alt_setting);
742 return NULL;
743 }
744
745 /**
746 * dfu_device_get_target_by_alt_name:
747 * @device: a #DfuDevice
748 * @alt_name: the name used to find
749 * @error: a #GError, or %NULL
750 *
751 * Gets a target with a specific alternative name.
752 *
753 * Return value: (transfer full): a #DfuTarget, or %NULL
754 **/
755 DfuTarget *
756 dfu_device_get_target_by_alt_name (DfuDevice *device,
757 const gchar *alt_name,
758 GError **error)
759 {
760 DfuDevicePrivate *priv = GET_PRIVATE (device);
761
762 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
763 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
764
765 /* find by ID */
766 for (guint i = 0; i < priv->targets->len; i++) {
767 DfuTarget *target = g_ptr_array_index (priv->targets, i);
768 if (g_strcmp0 (dfu_target_get_alt_name (target, NULL), alt_name) == 0)
769 return g_object_ref (target);
770 }
771
772 /* failed */
773 g_set_error (error,
774 FWUPD_ERROR,
775 FWUPD_ERROR_NOT_FOUND,
776 "No target with alt-name %s",
777 alt_name);
778 return NULL;
779 }
780
781 /**
782 * dfu_device_get_platform_id:
783 * @device: a #DfuDevice
784 *
785 * Gets the platform ID which normally corresponds to the port in some way.
786 *
787 * Return value: string or %NULL
788 **/
789 const gchar *
790 dfu_device_get_platform_id (DfuDevice *device)
791 {
792 DfuDevicePrivate *priv = GET_PRIVATE (device);
793 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
794 return priv->platform_id;
795 }
796
797 /**
798 * dfu_device_get_runtime_vid:
799 * @device: a #DfuDevice
800 *
801 * Gets the runtime vendor ID.
802 *
803 * Return value: vendor ID, or 0xffff for unknown
804 **/
805 guint16
806 dfu_device_get_runtime_vid (DfuDevice *device)
807 {
808 DfuDevicePrivate *priv = GET_PRIVATE (device);
809 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
810 return priv->runtime_vid;
811 }
812
813 /**
814 * dfu_device_get_runtime_pid:
815 * @device: a #DfuDevice
816 *
817 * Gets the runtime product ID.
818 *
819 * Return value: product ID, or 0xffff for unknown
820 **/
821 guint16
822 dfu_device_get_runtime_pid (DfuDevice *device)
823 {
824 DfuDevicePrivate *priv = GET_PRIVATE (device);
825 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
826 return priv->runtime_pid;
827 }
828
829 /**
830 * dfu_device_get_runtime_release:
831 * @device: a #DfuDevice
832 *
833 * Gets the runtime release number in BCD format.
834 *
835 * Return value: release number, or 0xffff for unknown
836 **/
837 guint16
838 dfu_device_get_runtime_release (DfuDevice *device)
839 {
840 DfuDevicePrivate *priv = GET_PRIVATE (device);
841 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff);
842 return priv->runtime_release;
843 }
844
845 /**
846 * dfu_device_get_usb_dev: (skip)
847 * @device: a #DfuDevice
848 *
849 * Gets the internal USB device for the #DfuDevice.
850 *
851 * NOTE: This may change at runtime if the device is replugged or
852 * reset.
853 *
854 * Returns: (transfer none): the internal USB device
855 **/
856 GUsbDevice *
857 dfu_device_get_usb_dev (DfuDevice *device)
858 {
859 DfuDevicePrivate *priv = GET_PRIVATE (device);
860 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
861 return priv->dev;
862 }
863
864 /**
865 * dfu_device_get_display_name:
866 * @device: a #DfuDevice
867 *
868 * Gets the display name to use for the device.
869 *
870 * Return value: string or %NULL for unset
871 **/
872 const gchar *
873 dfu_device_get_display_name (DfuDevice *device)
874 {
875 DfuDevicePrivate *priv = GET_PRIVATE (device);
876 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
877 return priv->display_name;
878 }
879
880 /**
881 * dfu_device_get_serial_number:
882 * @device: a #DfuDevice
883 *
884 * Gets the serial number for the device.
885 *
886 * Return value: string or %NULL for unset
887 **/
888 const gchar *
889 dfu_device_get_serial_number (DfuDevice *device)
890 {
891 DfuDevicePrivate *priv = GET_PRIVATE (device);
892 g_return_val_if_fail (DFU_IS_DEVICE (device), NULL);
893 return priv->serial_number;
894 }
895
896 static void
897 dfu_device_set_state (DfuDevice *device, DfuState state)
898 {
899 DfuDevicePrivate *priv = GET_PRIVATE (device);
900 if (priv->state == state)
901 return;
902 priv->state = state;
903 g_signal_emit (device, signals[SIGNAL_STATE_CHANGED], 0, state);
904 }
905
906 static void
907 dfu_device_set_status (DfuDevice *device, DfuStatus status)
908 {
909 DfuDevicePrivate *priv = GET_PRIVATE (device);
910 if (priv->status == status)
911 return;
912 priv->status = status;
913 g_signal_emit (device, signals[SIGNAL_STATUS_CHANGED], 0, status);
914 }
915
916 gboolean
917 dfu_device_ensure_interface (DfuDevice *device,
918 GCancellable *cancellable,
919 GError **error)
920 {
921 DfuDevicePrivate *priv = GET_PRIVATE (device);
922 g_autoptr(GError) error_local = NULL;
923
924 /* already done */
925 if (priv->claimed_interface)
926 return TRUE;
927
928 /* nothing set */
929 if (priv->iface_number == 0xff)
930 return TRUE;
931
932 /* claim, without detaching kernel driver */
933 if (!g_usb_device_claim_interface (priv->dev,
934 (gint) priv->iface_number,
935 0, &error_local)) {
936 g_set_error (error,
937 FWUPD_ERROR,
938 FWUPD_ERROR_NOT_SUPPORTED,
939 "cannot claim interface %i: %s",
940 priv->iface_number, error_local->message);
941 return FALSE;
942 }
943
944 /* success */
945 priv->claimed_interface = TRUE;
946 return TRUE;
947 }
948
949 /**
950 * dfu_device_refresh:
951 * @device: a #DfuDevice
952 * @cancellable: a #GCancellable, or %NULL
953 * @error: a #GError, or %NULL
954 *
955 * Refreshes the cached properties on the DFU device.
956 *
957 * Return value: %TRUE for success
958 **/
959 gboolean
960 dfu_device_refresh (DfuDevice *device, GCancellable *cancellable, GError **error)
961 {
962 DfuDevicePrivate *priv = GET_PRIVATE (device);
963 gsize actual_length = 0;
964 guint8 buf[6];
965 g_autoptr(GError) error_local = NULL;
966
967 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
968 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
969
970 /* no backing USB device */
971 if (priv->dev == NULL) {
972 g_set_error (error,
973 FWUPD_ERROR,
974 FWUPD_ERROR_INTERNAL,
975 "failed to refresh: no GUsbDevice for %s",
976 priv->platform_id);
977 return FALSE;
978 }
979
980 /* the device has no DFU runtime, so cheat */
981 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
982 g_set_error_literal (error,
983 FWUPD_ERROR,
984 FWUPD_ERROR_NOT_SUPPORTED,
985 "not supported as no DFU runtime");
986 return FALSE;
987 }
988
989 /* ensure interface is claimed */
990 if (!dfu_device_ensure_interface (device, cancellable, error))
991 return FALSE;
992
993 if (!g_usb_device_control_transfer (priv->dev,
994 G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
995 G_USB_DEVICE_REQUEST_TYPE_CLASS,
996 G_USB_DEVICE_RECIPIENT_INTERFACE,
997 DFU_REQUEST_GETSTATUS,
998 0,
999 priv->iface_number,
1000 buf, sizeof(buf), &actual_length,
1001 priv->timeout_ms,
1002 cancellable,
1003 &error_local)) {
1004 g_set_error (error,
1005 FWUPD_ERROR,
1006 FWUPD_ERROR_NOT_SUPPORTED,
1007 "cannot get device state: %s",
1008 error_local->message);
1009 return FALSE;
1010 }
1011 if (actual_length != 6) {
1012 g_set_error (error,
1013 FWUPD_ERROR,
1014 FWUPD_ERROR_INTERNAL,
1015 "cannot get device status, invalid size: %04x",
1016 (guint) actual_length);
1017 }
1018
1019 /* status or state changed */
1020 dfu_device_set_status (device, buf[0]);
1021 dfu_device_set_state (device, buf[4]);
1022 if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT)) {
1023 priv->dnload_timeout = 5;
1024 } else {
1025 priv->dnload_timeout = buf[1] +
1026 (((guint32) buf[2]) << 8) +
1027 (((guint32) buf[3]) << 16);
1028 }
1029 g_debug ("refreshed status=%s and state=%s (dnload=%u)",
1030 dfu_status_to_string (priv->status),
1031 dfu_state_to_string (priv->state),
1032 priv->dnload_timeout);
1033 return TRUE;
1034 }
1035
1036 /**
1037 * dfu_device_detach:
1038 * @device: a #DfuDevice
1039 * @cancellable: a #GCancellable, or %NULL
1040 * @error: a #GError, or %NULL
1041 *
1042 * Detaches the device putting it into DFU-mode.
1043 *
1044 * Return value: %TRUE for success
1045 **/
1046 gboolean
1047 dfu_device_detach (DfuDevice *device, GCancellable *cancellable, GError **error)
1048 {
1049 DfuDevicePrivate *priv = GET_PRIVATE (device);
1050 g_autoptr(GError) error_local = NULL;
1051
1052 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1053 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1054
1055 /* already in DFU mode */
1056 switch (priv->state) {
1057 case DFU_STATE_APP_IDLE:
1058 case DFU_STATE_APP_DETACH:
1059 break;
1060 default:
1061 g_set_error (error,
1062 FWUPD_ERROR,
1063 FWUPD_ERROR_NOT_SUPPORTED,
1064 "Already in DFU mode");
1065 return FALSE;
1066 }
1067
1068 /* no backing USB device */
1069 if (priv->dev == NULL) {
1070 g_set_error (error,
1071 FWUPD_ERROR,
1072 FWUPD_ERROR_INTERNAL,
1073 "failed to detach: no GUsbDevice for %s",
1074 priv->platform_id);
1075 return FALSE;
1076 }
1077
1078 /* the device has no DFU runtime, so cheat */
1079 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1080 g_set_error_literal (error,
1081 FWUPD_ERROR,
1082 FWUPD_ERROR_NOT_SUPPORTED,
1083 "not supported as no DFU runtime");
1084 return FALSE;
1085 }
1086
1087 /* ensure interface is claimed */
1088 if (!dfu_device_ensure_interface (device, cancellable, error))
1089 return FALSE;
1090
1091 /* inform UI there's going to be a detach:attach */
1092 dfu_device_set_action (device, FWUPD_STATUS_DEVICE_RESTART);
1093
1094 if (!g_usb_device_control_transfer (priv->dev,
1095 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
1096 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1097 G_USB_DEVICE_RECIPIENT_INTERFACE,
1098 DFU_REQUEST_DETACH,
1099 0,
1100 priv->iface_number,
1101 NULL, 0, NULL,
1102 priv->timeout_ms,
1103 cancellable,
1104 &error_local)) {
1105 /* refresh the error code */
1106 dfu_device_error_fixup (device, cancellable, &error_local);
1107 g_set_error (error,
1108 FWUPD_ERROR,
1109 FWUPD_ERROR_NOT_SUPPORTED,
1110 "cannot detach device: %s",
1111 error_local->message);
1112 return FALSE;
1113 }
1114
1115 /* do a host reset */
1116 if ((priv->attributes & DFU_DEVICE_ATTRIBUTE_WILL_DETACH) == 0) {
1117 g_debug ("doing device reset as host will not self-reset");
1118 if (!dfu_device_reset (device, error))
1119 return FALSE;
1120 }
1121
1122 /* success */
1123 dfu_device_set_action (device, FWUPD_STATUS_IDLE);
1124 return TRUE;
1125 }
1126
1127 /**
1128 * dfu_device_abort:
1129 * @device: a #DfuDevice
1130 * @cancellable: a #GCancellable, or %NULL
1131 * @error: a #GError, or %NULL
1132 *
1133 * Aborts any upload or download in progress.
1134 *
1135 * Return value: %TRUE for success
1136 **/
1137 gboolean
1138 dfu_device_abort (DfuDevice *device, GCancellable *cancellable, GError **error)
1139 {
1140 DfuDevicePrivate *priv = GET_PRIVATE (device);
1141 g_autoptr(GError) error_local = NULL;
1142
1143 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1144 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1145
1146 /* no backing USB device */
1147 if (priv->dev == NULL) {
1148 g_set_error (error,
1149 FWUPD_ERROR,
1150 FWUPD_ERROR_INTERNAL,
1151 "failed to abort: no GUsbDevice for %s",
1152 priv->platform_id);
1153 return FALSE;
1154 }
1155
1156 /* the device has no DFU runtime, so cheat */
1157 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1158 g_set_error_literal (error,
1159 FWUPD_ERROR,
1160 FWUPD_ERROR_NOT_SUPPORTED,
1161 "not supported as no DFU runtime");
1162 return FALSE;
1163 }
1164
1165 /* ensure interface is claimed */
1166 if (!dfu_device_ensure_interface (device, cancellable, error))
1167 return FALSE;
1168
1169 if (!g_usb_device_control_transfer (priv->dev,
1170 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
1171 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1172 G_USB_DEVICE_RECIPIENT_INTERFACE,
1173 DFU_REQUEST_ABORT,
1174 0,
1175 priv->iface_number,
1176 NULL, 0, NULL,
1177 priv->timeout_ms,
1178 cancellable,
1179 &error_local)) {
1180 /* refresh the error code */
1181 dfu_device_error_fixup (device, cancellable, &error_local);
1182 g_set_error (error,
1183 FWUPD_ERROR,
1184 FWUPD_ERROR_NOT_SUPPORTED,
1185 "cannot abort device: %s",
1186 error_local->message);
1187 return FALSE;
1188 }
1189
1190 return TRUE;
1191 }
1192
1193 /**
1194 * dfu_device_clear_status:
1195 * @device: a #DfuDevice
1196 * @cancellable: a #GCancellable, or %NULL
1197 * @error: a #GError, or %NULL
1198 *
1199 * Clears any error status on the DFU device.
1200 *
1201 * Return value: %TRUE for success
1202 **/
1203 gboolean
1204 dfu_device_clear_status (DfuDevice *device, GCancellable *cancellable, GError **error)
1205 {
1206 DfuDevicePrivate *priv = GET_PRIVATE (device);
1207 g_autoptr(GError) error_local = NULL;
1208
1209 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1210 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1211
1212 /* no backing USB device */
1213 if (priv->dev == NULL) {
1214 g_set_error (error,
1215 FWUPD_ERROR,
1216 FWUPD_ERROR_INTERNAL,
1217 "failed to clear status: no GUsbDevice for %s",
1218 priv->platform_id);
1219 return FALSE;
1220 }
1221
1222 /* the device has no DFU runtime, so cheat */
1223 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1224 g_set_error_literal (error,
1225 FWUPD_ERROR,
1226 FWUPD_ERROR_NOT_SUPPORTED,
1227 "not supported as no DFU runtime");
1228 return FALSE;
1229 }
1230
1231 /* ensure interface is claimed */
1232 if (!dfu_device_ensure_interface (device, cancellable, error))
1233 return FALSE;
1234
1235 if (!g_usb_device_control_transfer (priv->dev,
1236 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
1237 G_USB_DEVICE_REQUEST_TYPE_CLASS,
1238 G_USB_DEVICE_RECIPIENT_INTERFACE,
1239 DFU_REQUEST_CLRSTATUS,
1240 0,
1241 priv->iface_number,
1242 NULL, 0, NULL,
1243 priv->timeout_ms,
1244 cancellable,
1245 &error_local)) {
1246 /* refresh the error code */
1247 dfu_device_error_fixup (device, cancellable, &error_local);
1248 g_set_error (error,
1249 FWUPD_ERROR,
1250 FWUPD_ERROR_NOT_SUPPORTED,
1251 "cannot clear status on the device: %s",
1252 error_local->message);
1253 return FALSE;
1254 }
1255 return TRUE;
1256 }
1257
1258 /**
1259 * dfu_device_get_interface:
1260 * @device: a #DfuDevice
1261 *
1262 * Gets the interface number.
1263 **/
1264 guint8
1265 dfu_device_get_interface (DfuDevice *device)
1266 {
1267 DfuDevicePrivate *priv = GET_PRIVATE (device);
1268 g_return_val_if_fail (DFU_IS_DEVICE (device), 0xff);
1269 return priv->iface_number;
1270 }
1271
1272 /**
1273 * dfu_device_open_full:
1274 * @device: a #DfuDevice
1275 * @flags: #DfuDeviceOpenFlags, e.g. %DFU_DEVICE_OPEN_FLAG_NONE
1276 * @cancellable: a #GCancellable, or %NULL
1277 * @error: a #GError, or %NULL
1278 *
1279 * Opens a DFU-capable device.
1280 *
1281 * Return value: %TRUE for success
1282 **/
1283 gboolean
1284 dfu_device_open_full (DfuDevice *device, DfuDeviceOpenFlags flags,
1285 GCancellable *cancellable, GError **error)
1286 {
1287 DfuDevicePrivate *priv = GET_PRIVATE (device);
1288 guint8 idx;
1289 g_autoptr(GError) error_local = NULL;
1290 g_autoptr(FuDeviceLocker) locker = NULL;
1291
1292 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1293 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1294
1295 /* no backing USB device */
1296 if (priv->dev == NULL) {
1297 g_set_error (error,
1298 FWUPD_ERROR,
1299 FWUPD_ERROR_INTERNAL,
1300 "failed to open: no GUsbDevice for %s",
1301 priv->platform_id);
1302 return FALSE;
1303 }
1304
1305 /* already open */
1306 if (priv->dev_locker != NULL)
1307 return TRUE;
1308
1309 /* open */
1310 locker = fu_device_locker_new (priv->dev, &error_local);
1311 if (locker == NULL) {
1312 if (g_error_matches (error_local,
1313 G_USB_DEVICE_ERROR,
1314 G_USB_DEVICE_ERROR_PERMISSION_DENIED)) {
1315 g_set_error (error,
1316 FWUPD_ERROR,
1317 FWUPD_ERROR_PERMISSION_DENIED,
1318 "%s", error_local->message);
1319 return FALSE;
1320 }
1321 g_set_error (error,
1322 FWUPD_ERROR,
1323 FWUPD_ERROR_NOT_SUPPORTED,
1324 "cannot open device %s: %s",
1325 g_usb_device_get_platform_id (priv->dev),
1326 error_local->message);
1327 return FALSE;
1328 }
1329
1330 /* get product name if it exists */
1331 idx = g_usb_device_get_product_index (priv->dev);
1332 if (idx != 0x00)
1333 priv->display_name = g_usb_device_get_string_descriptor (priv->dev, idx, NULL);
1334
1335 /* get serial number if it exists */
1336 idx = g_usb_device_get_serial_number_index (priv->dev);
1337 if (idx != 0x00)
1338 priv->serial_number = g_usb_device_get_string_descriptor (priv->dev, idx, NULL);
1339
1340 /* the device has no DFU runtime, so cheat */
1341 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1342 priv->state = DFU_STATE_APP_IDLE;
1343 priv->status = DFU_STATUS_OK;
1344 priv->mode = DFU_MODE_RUNTIME;
1345 flags |= DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH;
1346 }
1347
1348 /* device locker is now valid */
1349 priv->dev_locker = g_steal_pointer (&locker);
1350
1351 /* automatically abort any uploads or downloads */
1352 if ((flags & DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH) == 0) {
1353 if (!dfu_device_refresh (device, cancellable, error))
1354 return FALSE;
1355 switch (priv->state) {
1356 case DFU_STATE_DFU_UPLOAD_IDLE:
1357 case DFU_STATE_DFU_DNLOAD_IDLE:
1358 case DFU_STATE_DFU_DNLOAD_SYNC:
1359 g_debug ("aborting transfer %s", dfu_status_to_string (priv->status));
1360 if (!dfu_device_abort (device, cancellable, error))
1361 return FALSE;
1362 break;
1363 case DFU_STATE_DFU_ERROR:
1364 g_debug ("clearing error %s", dfu_status_to_string (priv->status));
1365 if (!dfu_device_clear_status (device, cancellable, error))
1366 return FALSE;
1367 break;
1368 default:
1369 break;
1370 }
1371 }
1372
1373 /* success */
1374 priv->open_new_dev = TRUE;
1375 return TRUE;
1376 }
1377
1378 /**
1379 * dfu_device_open:
1380 * @device: a #DfuDevice
1381 * @flags: #DfuDeviceOpenFlags, e.g. %DFU_DEVICE_OPEN_FLAG_NONE
1382 * @error: a #GError, or %NULL
1383 *
1384 * Opens a DFU-capable device.
1385 *
1386 * Return value: %TRUE for success
1387 **/
1388 gboolean
1389 dfu_device_open (DfuDevice *device, GError **error)
1390 {
1391 return dfu_device_open_full (device, DFU_DEVICE_OPEN_FLAG_NONE, NULL, error);
1392 }
1393
1394 /**
1395 * dfu_device_close:
1396 * @device: a #DfuDevice
1397 * @error: a #GError, or %NULL
1398 *
1399 * Closes a DFU device.
1400 *
1401 * Return value: %TRUE for success
1402 **/
1403 gboolean
1404 dfu_device_close (DfuDevice *device, GError **error)
1405 {
1406 DfuDevicePrivate *priv = GET_PRIVATE (device);
1407
1408 /* no backing USB device */
1409 if (priv->dev == NULL)
1410 return TRUE;
1411
1412 /* just clear the locker */
1413 g_clear_object (&priv->dev_locker);
1414 priv->claimed_interface = FALSE;
1415 priv->open_new_dev = FALSE;
1416 return TRUE;
1417 }
1418
1419 gboolean
1420 dfu_device_set_new_usb_dev (DfuDevice *device, GUsbDevice *dev,
1421 GCancellable *cancellable, GError **error)
1422 {
1423 DfuDevicePrivate *priv = GET_PRIVATE (device);
1424
1425 /* same */
1426 if (priv->dev == dev) {
1427 g_warning ("setting GUsbDevice with same dev?!");
1428 return TRUE;
1429 }
1430
1431 /* device removed */
1432 if (dev == NULL) {
1433 g_debug ("invalidating backing GUsbDevice");
1434 g_clear_object (&priv->dev_locker);
1435 g_clear_object (&priv->dev);
1436 g_ptr_array_set_size (priv->targets, 0);
1437 priv->claimed_interface = FALSE;
1438 return TRUE;
1439 }
1440
1441 /* close */
1442 if (priv->dev != NULL) {
1443 gboolean tmp = priv->open_new_dev;
1444 g_clear_object (&priv->dev_locker);
1445 priv->open_new_dev = tmp;
1446 }
1447
1448 /* set the new USB device */
1449 g_set_object (&priv->dev, dev);
1450
1451 /* should be the same */
1452 if (g_strcmp0 (priv->platform_id,
1453 g_usb_device_get_platform_id (dev)) != 0) {
1454 g_warning ("platform ID changed when setting new GUsbDevice?!");
1455 g_free (priv->platform_id);
1456 priv->platform_id = g_strdup (g_usb_device_get_platform_id (dev));
1457 }
1458
1459 /* re-get the quirks for this new device */
1460 priv->quirks = DFU_DEVICE_QUIRK_NONE;
1461 priv->attributes = DFU_DEVICE_ATTRIBUTE_NONE;
1462 dfu_device_set_quirks (device);
1463
1464 /* the device has no DFU runtime, so cheat */
1465 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) {
1466 g_debug ("ignoring fake device");
1467 return TRUE;
1468 }
1469
1470 /* update all the targets */
1471 if (!dfu_device_add_targets (device)) {
1472 g_set_error_literal (error,
1473 FWUPD_ERROR,
1474 FWUPD_ERROR_NOT_SUPPORTED,
1475 "replugged device is not DFU-capable");
1476 return FALSE;
1477 }
1478
1479 /* reclaim */
1480 if (priv->open_new_dev) {
1481 g_debug ("automatically reopening device");
1482 if (!dfu_device_open_full (device, DFU_DEVICE_OPEN_FLAG_NONE,
1483 cancellable, error))
1484 return FALSE;
1485 }
1486 return TRUE;
1487 }
1488
1489 typedef struct {
1490 DfuDevice *device;
1491 GError **error;
1492 GMainLoop *loop;
1493 GUsbDevice *dev;
1494 guint cnt;
1495 guint timeout;
1496 } DfuDeviceReplugHelper;
1497
1498 static void
1499 dfu_device_replug_helper_free (DfuDeviceReplugHelper *helper)
1500 {
1501 if (helper->dev != NULL)
1502 g_object_unref (helper->dev);
1503 g_object_unref (helper->device);
1504 g_main_loop_unref (helper->loop);
1505 g_free (helper);
1506 }
1507
1508 static gboolean
1509 dfu_device_replug_helper_cb (gpointer user_data)
1510 {
1511 DfuDeviceReplugHelper *helper = (DfuDeviceReplugHelper *) user_data;
1512 DfuDevicePrivate *priv = GET_PRIVATE (helper->device);
1513
1514 /* did the backing GUsbDevice change */
1515 if (helper->dev != priv->dev) {
1516 g_debug ("device changed GUsbDevice %p->%p",
1517 helper->dev, priv->dev);
1518 g_set_object (&helper->dev, priv->dev);
1519
1520 /* success */
1521 if (helper->dev != NULL) {
1522 g_main_loop_quit (helper->loop);
1523 return FALSE;
1524 }
1525 }
1526
1527 /* set a limit */
1528 if (helper->cnt++ * 100 > helper->timeout) {
1529 g_debug ("gave up waiting for device replug");
1530 if (helper->dev == NULL) {
1531 g_set_error_literal (helper->error,
1532 FWUPD_ERROR,
1533 FWUPD_ERROR_NOT_SUPPORTED,
1534 "target went away but did not come back");
1535 } else {
1536 g_set_error_literal (helper->error,
1537 FWUPD_ERROR,
1538 FWUPD_ERROR_NOT_SUPPORTED,
1539 "target did not disconnect");
1540 }
1541 g_main_loop_quit (helper->loop);
1542 return FALSE;
1543 }
1544
1545 /* continue waiting */
1546 g_debug ("waiting for device replug for %ums -- state is %s",
1547 helper->cnt * 100, dfu_state_to_string (priv->state));
1548 return TRUE;
1549 }
1550
1551 /**
1552 * dfu_device_wait_for_replug:
1553 * @device: a #DfuDevice
1554 * @timeout: the maximum amount of time to wait
1555 * @cancellable: a #GCancellable, or %NULL
1556 * @error: a #GError, or %NULL
1557 *
1558 * Waits for a DFU device to disconnect and reconnect.
1559 * This does rely on a #DfuContext being set up before this is called.
1560 *
1561 * Return value: %TRUE for success
1562 **/
1563 gboolean
1564 dfu_device_wait_for_replug (DfuDevice *device, guint timeout,
1565 GCancellable *cancellable, GError **error)
1566 {
1567 DfuDevicePrivate *priv = GET_PRIVATE (device);
1568 DfuDeviceReplugHelper *helper;
1569 GError *error_tmp = NULL;
1570 const guint replug_poll = 100; /* ms */
1571
1572 /* wait for replug */
1573 helper = g_new0 (DfuDeviceReplugHelper, 1);
1574 helper->loop = g_main_loop_new (NULL, FALSE);
1575 helper->device = g_object_ref (device);
1576 helper->dev = g_object_ref (priv->dev);
1577 helper->error = &error_tmp;
1578 helper->timeout = timeout;
1579 g_timeout_add_full (G_PRIORITY_DEFAULT, replug_poll,
1580 dfu_device_replug_helper_cb, helper,
1581 (GDestroyNotify) dfu_device_replug_helper_free);
1582 g_main_loop_run (helper->loop);
1583 if (error_tmp != NULL) {
1584 g_propagate_error (error, error_tmp);
1585 return FALSE;
1586 }
1587
1588 /* success */
1589 dfu_device_set_action (device, FWUPD_STATUS_IDLE);
1590 return TRUE;
1591 }
1592
1593 /**
1594 * dfu_device_reset:
1595 * @device: a #DfuDevice
1596 * @error: a #GError, or %NULL
1597 *
1598 * Resets the USB device.
1599 *
1600 * Return value: %TRUE for success
1601 **/
1602 gboolean
1603 dfu_device_reset (DfuDevice *device, GError **error)
1604 {
1605 DfuDevicePrivate *priv = GET_PRIVATE (device);
1606 g_autoptr(GError) error_local = NULL;
1607
1608 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1609 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1610
1611 /* no backing USB device */
1612 if (priv->dev == NULL) {
1613 g_set_error (error,
1614 FWUPD_ERROR,
1615 FWUPD_ERROR_INTERNAL,
1616 "failed to reset: no GUsbDevice for %s",
1617 priv->platform_id);
1618 return FALSE;
1619 }
1620
1621 if (!g_usb_device_reset (priv->dev, &error_local)) {
1622 g_set_error (error,
1623 FWUPD_ERROR,
1624 FWUPD_ERROR_NOT_SUPPORTED,
1625 "cannot reset USB device: %s [%i]",
1626 error_local->message,
1627 error_local->code);
1628 return FALSE;
1629 }
1630 return TRUE;
1631 }
1632
1633 /**
1634 * dfu_device_attach:
1635 * @device: a #DfuDevice
1636 * @error: a #GError, or %NULL
1637 *
1638 * Move device from DFU mode to runtime.
1639 *
1640 * Return value: %TRUE for success
1641 **/
1642 gboolean
1643 dfu_device_attach (DfuDevice *device, GError **error)
1644 {
1645 DfuDevicePrivate *priv = GET_PRIVATE (device);
1646
1647 g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE);
1648 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1649
1650 /* already in runtime mode */
1651 switch (priv->state) {
1652 case DFU_STATE_APP_IDLE:
1653 case DFU_STATE_APP_DETACH:
1654 g_set_error (error,
1655 FWUPD_ERROR,
1656 FWUPD_ERROR_NOT_SUPPORTED,
1657 "Already in application runtime mode");
1658 return FALSE;
1659 default:
1660 break;
1661 }
1662
1663 /* inform UI there's going to be a re-attach */
1664 dfu_device_set_action (device, FWUPD_STATUS_DEVICE_RESTART);
1665
1666 /* handle m-stack DFU bootloaders */
1667 if (!priv->done_upload_or_download &&
1668 (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD) > 0) {
1669 g_autoptr(GBytes) chunk = NULL;
1670 g_autoptr(DfuTarget) target = NULL;
1671 g_debug ("doing dummy upload to work around m-stack quirk");
1672 target = dfu_device_get_target_by_alt_setting (device, 0, error);
1673 if (target == NULL)
1674 return FALSE;
1675 chunk = dfu_target_upload_chunk (target, 0, NULL, error);
1676 if (chunk == NULL)
1677 return FALSE;
1678 }
1679
1680 /* there's a a special command for ST devices */
1681 if (priv->dfuse_supported) {
1682 g_autoptr(DfuTarget) target = NULL;
1683 g_autoptr(GBytes) bytes_tmp = NULL;
1684
1685 /* get default target */
1686 target = dfu_device_get_target_by_alt_setting (device, 0, error);
1687 if (target == NULL)
1688 return FALSE;
1689
1690 /* do zero byte download */
1691 bytes_tmp = g_bytes_new (NULL, 0);
1692 if (!dfu_target_download_chunk (target,
1693 0 + 2,
1694 bytes_tmp,
1695 NULL,
1696 error))
1697 return FALSE;
1698
1699 dfu_device_set_action (device, FWUPD_STATUS_IDLE);
1700 return TRUE;
1701 }
1702
1703 /* normal DFU mode just needs a bus reset */
1704 if (!dfu_device_reset (device, error))
1705 return FALSE;
1706
1707 /* success */
1708 dfu_device_set_action (device, FWUPD_STATUS_IDLE);
1709 return TRUE;
1710 }
1711
1712 static void
1713 dfu_device_percentage_cb (DfuTarget *target, guint percentage, DfuDevice *device)
1714 {
1715 /* FIXME: divide by number of targets? */
1716 g_signal_emit (device, signals[SIGNAL_PERCENTAGE_CHANGED], 0, percentage);
1717 }
1718
1719 static void
1720 dfu_device_action_cb (DfuTarget *target, FwupdStatus action, DfuDevice *device)
1721 {
1722 dfu_device_set_action (device, action);
1723 }
1724
1725 /**
1726 * dfu_device_upload:
1727 * @device: a #DfuDevice
1728 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1729 * @cancellable: a #GCancellable, or %NULL
1730 * @error: a #GError, or %NULL
1731 *
1732 * Uploads firmware from the target to the host.
1733 *
1734 * Return value: (transfer full): the uploaded firmware, or %NULL for error
1735 **/
1736 DfuFirmware *
1737 dfu_device_upload (DfuDevice *device,
1738 DfuTargetTransferFlags flags,
1739 GCancellable *cancellable,
1740 GError **error)
1741 {
1742 DfuDevicePrivate *priv = GET_PRIVATE (device);
1743 g_autoptr(DfuFirmware) firmware = NULL;
1744
1745 /* no backing USB device */
1746 if (priv->dev == NULL) {
1747 g_set_error (error,
1748 FWUPD_ERROR,
1749 FWUPD_ERROR_INTERNAL,
1750 "failed to upload: no GUsbDevice for %s",
1751 priv->platform_id);
1752 return NULL;
1753 }
1754
1755 /* ensure interface is claimed */
1756 if (!dfu_device_ensure_interface (device, cancellable, error))
1757 return NULL;
1758
1759 /* create ahead of time */
1760 firmware = dfu_firmware_new ();
1761 dfu_firmware_set_vid (firmware, priv->runtime_vid);
1762 dfu_firmware_set_pid (firmware, priv->runtime_pid);
1763 dfu_firmware_set_release (firmware, 0xffff);
1764
1765 /* APP -> DFU */
1766 if (priv->mode == DFU_MODE_RUNTIME) {
1767 if ((flags & DFU_TARGET_TRANSFER_FLAG_DETACH) == 0) {
1768 g_set_error (error,
1769 FWUPD_ERROR,
1770 FWUPD_ERROR_NOT_SUPPORTED,
1771 "device is not in DFU mode");
1772 return NULL;
1773 }
1774 g_debug ("detaching");
1775
1776 /* detach and USB reset */
1777 if (!dfu_device_detach (device, NULL, error))
1778 return NULL;
1779 if (!dfu_device_wait_for_replug (device,
1780 DFU_DEVICE_REPLUG_TIMEOUT,
1781 cancellable,
1782 error))
1783 return NULL;
1784 }
1785
1786 /* upload from each target */
1787 for (guint i = 0; i < priv->targets->len; i++) {
1788 DfuTarget *target;
1789 const gchar *alt_name;
1790 gulong id1;
1791 gulong id2;
1792 g_autoptr(DfuImage) image = NULL;
1793
1794 /* upload to target and proxy signals */
1795 target = g_ptr_array_index (priv->targets, i);
1796
1797 /* ignore some target types */
1798 alt_name = dfu_target_get_alt_name_for_display (target, NULL);
1799 if (g_strcmp0 (alt_name, "Option Bytes") == 0) {
1800 g_debug ("ignoring target %s", alt_name);
1801 continue;
1802 }
1803
1804 id1 = g_signal_connect (target, "percentage-changed",
1805 G_CALLBACK (dfu_device_percentage_cb), device);
1806 id2 = g_signal_connect (target, "action-changed",
1807 G_CALLBACK (dfu_device_action_cb), device);
1808 image = dfu_target_upload (target,
1809 DFU_TARGET_TRANSFER_FLAG_NONE,
1810 cancellable,
1811 error);
1812 g_signal_handler_disconnect (target, id1);
1813 g_signal_handler_disconnect (target, id2);
1814 if (image == NULL)
1815 return NULL;
1816 dfu_firmware_add_image (firmware, image);
1817 }
1818
1819 /* do not do the dummy upload for quirked devices */
1820 priv->done_upload_or_download = TRUE;
1821
1822 /* choose the most appropriate type */
1823 if (priv->targets->len > 1) {
1824 g_debug ("switching to DefuSe automatically");
1825 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFUSE);
1826 } else {
1827 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU);
1828 }
1829
1830 /* do host reset */
1831 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
1832 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
1833 if (!dfu_device_attach (device, error))
1834 return NULL;
1835 }
1836
1837 /* boot to runtime */
1838 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
1839 g_debug ("booting to runtime");
1840 if (!dfu_device_wait_for_replug (device,
1841 DFU_DEVICE_REPLUG_TIMEOUT,
1842 cancellable,
1843 error))
1844 return NULL;
1845 }
1846
1847 /* success */
1848 dfu_device_set_action (device, FWUPD_STATUS_IDLE);
1849 return g_object_ref (firmware);
1850 }
1851
1852 static gboolean
1853 dfu_device_id_compatible (guint16 id_file, guint16 id_runtime, guint16 id_dev)
1854 {
1855 /* file doesn't specify */
1856 if (id_file == 0xffff)
1857 return TRUE;
1858
1859 /* runtime matches */
1860 if (id_runtime != 0xffff && id_file == id_runtime)
1861 return TRUE;
1862
1863 /* bootloader matches */
1864 if (id_dev != 0xffff && id_file == id_dev)
1865 return TRUE;
1866
1867 /* nothing */
1868 return FALSE;
1869 }
1870
1871 /**
1872 * dfu_device_download:
1873 * @device: a #DfuDevice
1874 * @firmware: a #DfuFirmware
1875 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1876 * @cancellable: a #GCancellable, or %NULL
1877 * @error: a #GError, or %NULL
1878 *
1879 * Downloads firmware from the host to the target, optionally verifying
1880 * the transfer.
1881 *
1882 * Return value: %TRUE for success
1883 **/
1884 gboolean
1885 dfu_device_download (DfuDevice *device,
1886 DfuFirmware *firmware,
1887 DfuTargetTransferFlags flags,
1888 GCancellable *cancellable,
1889 GError **error)
1890 {
1891 DfuDevicePrivate *priv = GET_PRIVATE (device);
1892 GPtrArray *images;
1893 gboolean ret;
1894
1895 /* no backing USB device */
1896 if (priv->dev == NULL) {
1897 g_set_error (error,
1898 FWUPD_ERROR,
1899 FWUPD_ERROR_INTERNAL,
1900 "failed to download: no GUsbDevice for %s",
1901 priv->platform_id);
1902 return FALSE;
1903 }
1904
1905 /* ensure interface is claimed */
1906 if (!dfu_device_ensure_interface (device, cancellable, error))
1907 return FALSE;
1908
1909 /* do we allow wildcard VID:PID matches */
1910 if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID) == 0) {
1911 if (dfu_firmware_get_vid (firmware) == 0xffff) {
1912 g_set_error (error,
1913 FWUPD_ERROR,
1914 FWUPD_ERROR_NOT_SUPPORTED,
1915 "firmware vendor ID not specified");
1916 return FALSE;
1917 }
1918 }
1919 if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID) == 0) {
1920 if (dfu_firmware_get_pid (firmware) == 0xffff) {
1921 g_set_error (error,
1922 FWUPD_ERROR,
1923 FWUPD_ERROR_NOT_SUPPORTED,
1924 "firmware product ID not specified");
1925 return FALSE;
1926 }
1927 }
1928
1929 /* check vendor matches */
1930 if (priv->runtime_vid != 0xffff) {
1931 if (!dfu_device_id_compatible (dfu_firmware_get_vid (firmware),
1932 priv->runtime_vid,
1933 g_usb_device_get_vid (priv->dev))) {
1934 g_set_error (error,
1935 FWUPD_ERROR,
1936 FWUPD_ERROR_NOT_SUPPORTED,
1937 "vendor ID incorrect, expected 0x%04x "
1938 "got 0x%04x and 0x%04x\n",
1939 dfu_firmware_get_vid (firmware),
1940 priv->runtime_vid,
1941 g_usb_device_get_vid (priv->dev));
1942 return FALSE;
1943 }
1944 }
1945
1946 /* check product matches */
1947 if (priv->runtime_pid != 0xffff) {
1948 if (!dfu_device_id_compatible (dfu_firmware_get_pid (firmware),
1949 priv->runtime_pid,
1950 g_usb_device_get_pid (priv->dev))) {
1951 g_set_error (error,
1952 FWUPD_ERROR,
1953 FWUPD_ERROR_NOT_SUPPORTED,
1954 "product ID incorrect, expected 0x%04x "
1955 "got 0x%04x and 0x%04x",
1956 dfu_firmware_get_pid (firmware),
1957 priv->runtime_pid,
1958 g_usb_device_get_pid (priv->dev));
1959 return FALSE;
1960 }
1961 }
1962
1963 /* APP -> DFU */
1964 if (priv->mode == DFU_MODE_RUNTIME) {
1965 if ((flags & DFU_TARGET_TRANSFER_FLAG_DETACH) == 0) {
1966 g_set_error (error,
1967 FWUPD_ERROR,
1968 FWUPD_ERROR_NOT_SUPPORTED,
1969 "device is not in DFU mode");
1970 return FALSE;
1971 }
1972
1973 /* detach and USB reset */
1974 g_debug ("detaching");
1975 if (!dfu_device_detach (device, NULL, error))
1976 return FALSE;
1977 if (!dfu_device_wait_for_replug (device,
1978 DFU_DEVICE_REPLUG_TIMEOUT,
1979 NULL,
1980 error))
1981 return FALSE;
1982 }
1983
1984 /* download each target */
1985 images = dfu_firmware_get_images (firmware);
1986 if (images->len == 0) {
1987 g_set_error_literal (error,
1988 FWUPD_ERROR,
1989 FWUPD_ERROR_INVALID_FILE,
1990 "no images in firmware file");
1991 return FALSE;
1992 }
1993 for (guint i = 0; i < images->len; i++) {
1994 DfuCipherKind cipher_fw;
1995 DfuCipherKind cipher_target;
1996 DfuImage *image;
1997 DfuTargetTransferFlags flags_local = DFU_TARGET_TRANSFER_FLAG_NONE;
1998 const gchar *alt_name;
1999 gulong id1;
2000 gulong id2;
2001 g_autoptr(DfuTarget) target_tmp = NULL;
2002
2003 image = g_ptr_array_index (images, i);
2004 target_tmp = dfu_device_get_target_by_alt_setting (device,
2005 dfu_image_get_alt_setting (image),
2006 error);
2007 if (target_tmp == NULL)
2008 return FALSE;
2009
2010 /* we don't actually need to print this, but it makes sure the
2011 * target is setup prior to doing the cipher checks */
2012 alt_name = dfu_target_get_alt_name (target_tmp, error);
2013 if (alt_name == NULL)
2014 return FALSE;
2015 g_debug ("downloading to target: %s", alt_name);
2016
2017 /* check we're flashing a compatible firmware */
2018 cipher_target = dfu_target_get_cipher_kind (target_tmp);
2019 cipher_fw = dfu_firmware_get_cipher_kind (firmware);
2020 if ((flags & DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER) == 0) {
2021 if (cipher_fw != DFU_CIPHER_KIND_NONE &&
2022 cipher_target == DFU_CIPHER_KIND_NONE) {
2023 g_set_error (error,
2024 FWUPD_ERROR,
2025 FWUPD_ERROR_INVALID_FILE,
2026 "Device is only accepting "
2027 "unsigned firmware, not %s",
2028 dfu_cipher_kind_to_string (cipher_fw));
2029 return FALSE;
2030 }
2031 if (cipher_fw == DFU_CIPHER_KIND_NONE &&
2032 cipher_target != DFU_CIPHER_KIND_NONE) {
2033 g_set_error (error,
2034 FWUPD_ERROR,
2035 FWUPD_ERROR_INVALID_FILE,
2036 "Device is only accepting "
2037 "firmware with %s cipher kind",
2038 dfu_cipher_kind_to_string (cipher_target));
2039 return FALSE;
2040 }
2041 }
2042
2043 /* download onto target */
2044 if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY)
2045 flags_local = DFU_TARGET_TRANSFER_FLAG_VERIFY;
2046 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_RAW)
2047 flags_local |= DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC;
2048 id1 = g_signal_connect (target_tmp, "percentage-changed",
2049 G_CALLBACK (dfu_device_percentage_cb), device);
2050 id2 = g_signal_connect (target_tmp, "action-changed",
2051 G_CALLBACK (dfu_device_action_cb), device);
2052 ret = dfu_target_download (target_tmp,
2053 image,
2054 flags_local,
2055 cancellable,
2056 error);
2057 g_signal_handler_disconnect (target_tmp, id1);
2058 g_signal_handler_disconnect (target_tmp, id2);
2059 if (!ret)
2060 return FALSE;
2061 }
2062
2063 /* do not do the dummy upload for quirked devices */
2064 priv->done_upload_or_download = TRUE;
2065
2066 /* attempt to switch back to runtime */
2067 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
2068 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
2069 if (!dfu_device_attach (device, error))
2070 return FALSE;
2071 }
2072
2073 /* boot to runtime */
2074 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
2075 g_debug ("booting to runtime to set auto-boot");
2076 if (!dfu_device_wait_for_replug (device,
2077 DFU_DEVICE_REPLUG_TIMEOUT,
2078 cancellable,
2079 error))
2080 return FALSE;
2081 }
2082
2083 /* success */
2084 dfu_device_set_action (device, FWUPD_STATUS_IDLE);
2085 return TRUE;
2086 }
2087
2088 void
2089 dfu_device_error_fixup (DfuDevice *device,
2090 GCancellable *cancellable,
2091 GError **error)
2092 {
2093 DfuDevicePrivate *priv = GET_PRIVATE (device);
2094
2095 /* sad panda */
2096 if (error == NULL)
2097 return;
2098
2099 /* not the right error to query */
2100 if (!g_error_matches (*error,
2101 G_USB_DEVICE_ERROR,
2102 G_USB_DEVICE_ERROR_NOT_SUPPORTED))
2103 return;
2104
2105 /* get the status */
2106 if (!dfu_device_refresh (device, cancellable, NULL))
2107 return;
2108
2109 /* not in an error state */
2110 if (priv->state != DFU_STATE_DFU_ERROR)
2111 return;
2112
2113 /* prefix the error */
2114 switch (priv->status) {
2115 case DFU_STATUS_OK:
2116 /* ignore */
2117 break;
2118 case DFU_STATUS_ERR_VENDOR:
2119 g_prefix_error (error, "read protection is active: ");
2120 break;
2121 default:
2122 g_prefix_error (error, "[%s,%s]: ",
2123 dfu_state_to_string (priv->state),
2124 dfu_status_to_string (priv->status));
2125 break;
2126 }
2127 }
2128
2129 /**
2130 * dfu_device_get_quirks_as_string: (skip)
2131 * @device: a #DfuDevice
2132 *
2133 * Gets a string describing the quirks set for a device.
2134 *
2135 * Return value: string, or %NULL for no quirks
2136 **/
2137 gchar *
2138 dfu_device_get_quirks_as_string (DfuDevice *device)
2139 {
2140 DfuDevicePrivate *priv = GET_PRIVATE (device);
2141 GString *str;
2142
2143 /* just append to a string */
2144 str = g_string_new ("");
2145 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT)
2146 g_string_append_printf (str, "ignore-polltimeout|");
2147 if (priv->quirks & DFU_DEVICE_QUIRK_FORCE_DFU_MODE)
2148 g_string_append_printf (str, "force-dfu-mode|");
2149 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION)
2150 g_string_append_printf (str, "ignore-invalid-version|");
2151 if (priv->quirks & DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO)
2152 g_string_append_printf (str, "use-protocol-zero|");
2153 if (priv->quirks & DFU_DEVICE_QUIRK_NO_PID_CHANGE)
2154 g_string_append_printf (str, "no-pid-change|");
2155 if (priv->quirks & DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD)
2156 g_string_append_printf (str, "no-get-status-upload|");
2157 if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME)
2158 g_string_append_printf (str, "no-dfu-runtime|");
2159 if (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD)
2160 g_string_append_printf (str, "attach-upload-download|");
2161 if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_RUNTIME)
2162 g_string_append_printf (str, "ignore-runtime|");
2163
2164 /* a well behaved device */
2165 if (str->len == 0) {
2166 g_string_free (str, TRUE);
2167 return NULL;
2168 }
2169
2170 /* remove trailing pipe */
2171 g_string_truncate (str, str->len - 1);
2172 return g_string_free (str, FALSE);
2173 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_DEVICE_H
22 #define __DFU_DEVICE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-common.h"
29 #include "dfu-target.h"
30 #include "dfu-firmware.h"
31
32 G_BEGIN_DECLS
33
34 #define DFU_TYPE_DEVICE (dfu_device_get_type ())
35 G_DECLARE_DERIVABLE_TYPE (DfuDevice, dfu_device, DFU, DEVICE, GObject)
36
37 /**
38 * DfuDeviceOpenFlags:
39 * @DFU_DEVICE_OPEN_FLAG_NONE: No flags set
40 * @DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH: Do not do the initial GET_STATUS
41 *
42 * The optional flags used for opening the target.
43 **/
44 typedef enum {
45 DFU_DEVICE_OPEN_FLAG_NONE = 0,
46 DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH = (1 << 0),
47 /*< private >*/
48 DFU_DEVICE_OPEN_FLAG_LAST
49 } DfuDeviceOpenFlags;
50
51 /**
52 * DfuDeviceQuirks:
53 * @DFU_DEVICE_QUIRK_NONE: No device quirks
54 * @DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT: Ignore the device download timeout
55 * @DFU_DEVICE_QUIRK_FORCE_DFU_MODE: Force DFU mode
56 * @DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION: Ignore invalid version numbers
57 * @DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO: Fix up the protocol number
58 * @DFU_DEVICE_QUIRK_NO_PID_CHANGE: Accept the same VID:PID when changing modes
59 * @DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD: Do not do GetStatus when uploading
60 * @DFU_DEVICE_QUIRK_NO_DFU_RUNTIME: No DFU runtime interface is provided
61 * @DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD: An upload or download is required for attach
62 * @DFU_DEVICE_QUIRK_IGNORE_RUNTIME: Device has broken DFU runtime support
63 *
64 * The workarounds for different devices.
65 **/
66 typedef enum {
67 DFU_DEVICE_QUIRK_NONE = 0,
68 DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT = (1 << 0),
69 DFU_DEVICE_QUIRK_FORCE_DFU_MODE = (1 << 1),
70 DFU_DEVICE_QUIRK_IGNORE_INVALID_VERSION = (1 << 2),
71 DFU_DEVICE_QUIRK_USE_PROTOCOL_ZERO = (1 << 3),
72 DFU_DEVICE_QUIRK_NO_PID_CHANGE = (1 << 4),
73 DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD = (1 << 5),
74 DFU_DEVICE_QUIRK_NO_DFU_RUNTIME = (1 << 6),
75 DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD = (1 << 7),
76 DFU_DEVICE_QUIRK_IGNORE_RUNTIME = (1 << 8),
77 /*< private >*/
78 DFU_DEVICE_QUIRK_LAST
79 } DfuDeviceQuirks;
80
81 /**
82 * DfuDeviceAttributes:
83 * @DFU_DEVICE_ATTRIBUTE_NONE: No attributes set
84 * @DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD: Can download from host->device
85 * @DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD: Can upload from device->host
86 * @DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL: Can answer GetStatus in manifest
87 * @DFU_DEVICE_ATTRIBUTE_WILL_DETACH: Will self-detach
88 * @DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE: Use a larger transfer size for speed
89 *
90 * The device DFU attributes.
91 **/
92 typedef enum {
93 DFU_DEVICE_ATTRIBUTE_NONE = 0,
94 DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD = (1 << 0),
95 DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD = (1 << 1),
96 DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL = (1 << 2),
97 DFU_DEVICE_ATTRIBUTE_WILL_DETACH = (1 << 3),
98 DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE = (1 << 7),
99 /*< private >*/
100 DFU_DEVICE_ATTRIBUTE_LAST
101 } DfuDeviceAttributes;
102
103 struct _DfuDeviceClass
104 {
105 GObjectClass parent_class;
106 void (*status_changed) (DfuDevice *device,
107 DfuStatus status);
108 void (*state_changed) (DfuDevice *device,
109 DfuState state);
110 void (*percentage_changed) (DfuDevice *device,
111 guint percentage);
112 void (*action_changed) (DfuDevice *device,
113 FwupdStatus action);
114 /*< private >*/
115 /* Padding for future expansion */
116 void (*_dfu_device_reserved1) (void);
117 void (*_dfu_device_reserved2) (void);
118 void (*_dfu_device_reserved3) (void);
119 void (*_dfu_device_reserved4) (void);
120 void (*_dfu_device_reserved5) (void);
121 void (*_dfu_device_reserved6) (void);
122 void (*_dfu_device_reserved7) (void);
123 void (*_dfu_device_reserved8) (void);
124 };
125
126 DfuDevice *dfu_device_new (GUsbDevice *dev);
127 gboolean dfu_device_open (DfuDevice *device,
128 GError **error);
129 gboolean dfu_device_open_full (DfuDevice *device,
130 DfuDeviceOpenFlags flags,
131 GCancellable *cancellable,
132 GError **error);
133 gboolean dfu_device_close (DfuDevice *device,
134 GError **error);
135 const gchar *dfu_device_get_platform_id (DfuDevice *device);
136 GPtrArray *dfu_device_get_targets (DfuDevice *device);
137 DfuTarget *dfu_device_get_target_by_alt_setting (DfuDevice *device,
138 guint8 alt_setting,
139 GError **error);
140 DfuTarget *dfu_device_get_target_by_alt_name (DfuDevice *device,
141 const gchar *alt_name,
142 GError **error);
143 const gchar *dfu_device_get_display_name (DfuDevice *device);
144 const gchar *dfu_device_get_serial_number (DfuDevice *device);
145 guint16 dfu_device_get_runtime_vid (DfuDevice *device);
146 guint16 dfu_device_get_runtime_pid (DfuDevice *device);
147 guint16 dfu_device_get_runtime_release (DfuDevice *device);
148 gboolean dfu_device_reset (DfuDevice *device,
149 GError **error);
150 gboolean dfu_device_attach (DfuDevice *device,
151 GError **error);
152 gboolean dfu_device_wait_for_replug (DfuDevice *device,
153 guint timeout,
154 GCancellable *cancellable,
155 GError **error);
156 DfuFirmware *dfu_device_upload (DfuDevice *device,
157 DfuTargetTransferFlags flags,
158 GCancellable *cancellable,
159 GError **error);
160 gboolean dfu_device_download (DfuDevice *device,
161 DfuFirmware *firmware,
162 DfuTargetTransferFlags flags,
163 GCancellable *cancellable,
164 GError **error);
165 gboolean dfu_device_refresh (DfuDevice *device,
166 GCancellable *cancellable,
167 GError **error);
168 gboolean dfu_device_detach (DfuDevice *device,
169 GCancellable *cancellable,
170 GError **error);
171 gboolean dfu_device_abort (DfuDevice *device,
172 GCancellable *cancellable,
173 GError **error);
174 gboolean dfu_device_clear_status (DfuDevice *device,
175 GCancellable *cancellable,
176 GError **error);
177
178 guint8 dfu_device_get_interface (DfuDevice *device);
179 DfuMode dfu_device_get_mode (DfuDevice *device);
180 DfuState dfu_device_get_state (DfuDevice *device);
181 DfuStatus dfu_device_get_status (DfuDevice *device);
182 guint16 dfu_device_get_transfer_size (DfuDevice *device);
183 guint16 dfu_device_get_version (DfuDevice *device);
184 guint dfu_device_get_timeout (DfuDevice *device);
185 gboolean dfu_device_can_upload (DfuDevice *device);
186 gboolean dfu_device_can_download (DfuDevice *device);
187 gboolean dfu_device_is_open (DfuDevice *device);
188
189 gboolean dfu_device_has_attribute (DfuDevice *device,
190 DfuDeviceAttributes attribute);
191 gboolean dfu_device_has_quirk (DfuDevice *device,
192 DfuDeviceQuirks quirk);
193
194 void dfu_device_set_transfer_size (DfuDevice *device,
195 guint16 transfer_size);
196 void dfu_device_set_timeout (DfuDevice *device,
197 guint timeout_ms);
198
199 G_END_DECLS
200
201 #endif /* __DFU_DEVICE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-element
23 * @short_description: Object representing a binary element
24 *
25 * This object represents an binary blob of data at a specific address.
26 *
27 * This allows relocatable data segments to be stored in different
28 * locations on the device itself.
29 *
30 * See also: #DfuImage, #DfuFirmware
31 */
32
33 #include "config.h"
34
35 #include <string.h>
36 #include <stdio.h>
37
38 #include "dfu-common.h"
39 #include "dfu-element.h"
40
41 static void dfu_element_finalize (GObject *object);
42
43 typedef struct {
44 GBytes *contents;
45 guint32 target_size;
46 guint32 address;
47 guint8 padding_value;
48 } DfuElementPrivate;
49
50 G_DEFINE_TYPE_WITH_PRIVATE (DfuElement, dfu_element, G_TYPE_OBJECT)
51 #define GET_PRIVATE(o) (dfu_element_get_instance_private (o))
52
53 static void
54 dfu_element_class_init (DfuElementClass *klass)
55 {
56 GObjectClass *object_class = G_OBJECT_CLASS (klass);
57 object_class->finalize = dfu_element_finalize;
58 }
59
60 static void
61 dfu_element_init (DfuElement *element)
62 {
63 }
64
65 static void
66 dfu_element_finalize (GObject *object)
67 {
68 DfuElement *element = DFU_ELEMENT (object);
69 DfuElementPrivate *priv = GET_PRIVATE (element);
70
71 if (priv->contents != NULL)
72 g_bytes_unref (priv->contents);
73
74 G_OBJECT_CLASS (dfu_element_parent_class)->finalize (object);
75 }
76
77 /**
78 * dfu_element_new:
79 *
80 * Creates a new DFU element object.
81 *
82 * Return value: a new #DfuElement
83 **/
84 DfuElement *
85 dfu_element_new (void)
86 {
87 DfuElement *element;
88 element = g_object_new (DFU_TYPE_ELEMENT, NULL);
89 return element;
90 }
91
92 /**
93 * dfu_element_get_contents:
94 * @element: a #DfuElement
95 *
96 * Gets the element data.
97 *
98 * Return value: (transfer none): element data
99 **/
100 GBytes *
101 dfu_element_get_contents (DfuElement *element)
102 {
103 DfuElementPrivate *priv = GET_PRIVATE (element);
104 g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL);
105 return priv->contents;
106 }
107
108 /**
109 * dfu_element_get_address:
110 * @element: a #DfuElement
111 *
112 * Gets the offset address of the element.
113 *
114 * Return value: memory offset value, or 0x00 for unset
115 **/
116 guint32
117 dfu_element_get_address (DfuElement *element)
118 {
119 DfuElementPrivate *priv = GET_PRIVATE (element);
120 g_return_val_if_fail (DFU_IS_ELEMENT (element), 0x00);
121 return priv->address;
122 }
123
124 /**
125 * dfu_element_set_contents:
126 * @element: a #DfuElement
127 * @contents: element data
128 *
129 * Sets the element data.
130 **/
131 void
132 dfu_element_set_contents (DfuElement *element, GBytes *contents)
133 {
134 DfuElementPrivate *priv = GET_PRIVATE (element);
135 g_return_if_fail (DFU_IS_ELEMENT (element));
136 g_return_if_fail (contents != NULL);
137 if (priv->contents == contents)
138 return;
139 if (priv->contents != NULL)
140 g_bytes_unref (priv->contents);
141 priv->contents = g_bytes_ref (contents);
142 }
143
144 /**
145 * dfu_element_set_address:
146 * @element: a #DfuElement
147 * @address: memory offset value
148 *
149 * Sets the offset address of the element.
150 **/
151 void
152 dfu_element_set_address (DfuElement *element, guint32 address)
153 {
154 DfuElementPrivate *priv = GET_PRIVATE (element);
155 g_return_if_fail (DFU_IS_ELEMENT (element));
156 priv->address = address;
157 }
158
159 /**
160 * dfu_element_to_string:
161 * @element: a #DfuElement
162 *
163 * Returns a string representaiton of the object.
164 *
165 * Return value: NULL terminated string, or %NULL for invalid
166 **/
167 gchar *
168 dfu_element_to_string (DfuElement *element)
169 {
170 DfuElementPrivate *priv = GET_PRIVATE (element);
171 GString *str;
172
173 g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL);
174
175 str = g_string_new ("");
176 g_string_append_printf (str, "address: 0x%02x\n", priv->address);
177 if (priv->target_size > 0) {
178 g_string_append_printf (str, "target: 0x%04x\n",
179 priv->target_size);
180 }
181 if (priv->contents != NULL) {
182 g_string_append_printf (str, "contents: 0x%04x\n",
183 (guint32) g_bytes_get_size (priv->contents));
184 }
185
186 g_string_truncate (str, str->len - 1);
187 return g_string_free (str, FALSE);
188 }
189
190 /**
191 * dfu_element_set_padding_value:
192 * @element: a #DfuElement
193 * @padding_value: char value, typically 0x00 or 0xff
194 *
195 * Sets a the value of the padding byte to be used in the function
196 * dfu_element_set_target_size().
197 **/
198 void
199 dfu_element_set_padding_value (DfuElement *element, guint8 padding_value)
200 {
201 DfuElementPrivate *priv = GET_PRIVATE (element);
202 g_return_if_fail (DFU_IS_ELEMENT (element));
203 priv->padding_value = padding_value;
204 }
205
206 /**
207 * dfu_element_set_target_size:
208 * @element: a #DfuElement
209 * @target_size: size in bytes
210 *
211 * Sets a target size for the element. If the prepared element is smaller
212 * than this then it will be padded up to the required size.
213 *
214 * If a padding byte other than 0x00 is required then the function
215 * dfu_element_set_padding_value() should be used before this function is
216 * called.
217 **/
218 void
219 dfu_element_set_target_size (DfuElement *element, guint32 target_size)
220 {
221 DfuElementPrivate *priv = GET_PRIVATE (element);
222 const guint8 *data;
223 gsize length;
224 guint8 *buf;
225
226 g_return_if_fail (DFU_IS_ELEMENT (element));
227
228 /* save for dump */
229 priv->target_size = target_size;
230
231 /* no need to pad */
232 if (priv->contents == NULL)
233 return;
234 if (g_bytes_get_size (priv->contents) >= target_size)
235 return;
236
237 /* reallocate and pad */
238 data = g_bytes_get_data (priv->contents, &length);
239 buf = g_malloc0 (target_size);
240 g_assert (buf != NULL);
241 memcpy (buf, data, length);
242
243 /* set the pading value */
244 if (priv->padding_value != 0x00) {
245 memset (buf + length,
246 priv->padding_value,
247 target_size - length);
248 }
249
250 /* replace */
251 g_bytes_unref (priv->contents);
252 priv->contents = g_bytes_new_take (buf, target_size);
253 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_ELEMENT_H
22 #define __DFU_ELEMENT_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 #define DFU_TYPE_ELEMENT (dfu_element_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (DfuElement, dfu_element, DFU, ELEMENT, GObject)
31
32 struct _DfuElementClass
33 {
34 GObjectClass parent_class;
35 /*< private >*/
36 /* Padding for future expansion */
37 void (*_dfu_element_reserved1) (void);
38 void (*_dfu_element_reserved2) (void);
39 void (*_dfu_element_reserved3) (void);
40 void (*_dfu_element_reserved4) (void);
41 void (*_dfu_element_reserved5) (void);
42 void (*_dfu_element_reserved6) (void);
43 void (*_dfu_element_reserved7) (void);
44 void (*_dfu_element_reserved8) (void);
45 void (*_dfu_element_reserved9) (void);
46 };
47
48 DfuElement *dfu_element_new (void);
49
50 GBytes *dfu_element_get_contents (DfuElement *element);
51 guint32 dfu_element_get_address (DfuElement *element);
52
53 void dfu_element_set_contents (DfuElement *element,
54 GBytes *contents);
55 void dfu_element_set_address (DfuElement *element,
56 guint32 address);
57 void dfu_element_set_target_size (DfuElement *element,
58 guint32 target_size);
59 void dfu_element_set_padding_value (DfuElement *element,
60 guint8 padding_value);
61
62 gchar *dfu_element_to_string (DfuElement *element);
63
64 G_END_DECLS
65
66 #endif /* __DFU_ELEMENT_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-firmware
23 * @short_description: Object representing a DFU or DfuSe firmware file
24 *
25 * This object allows reading and writing firmware files either in
26 * raw, DFU or DfuSe formats.
27 *
28 * A #DfuFirmware can be made up of several #DfuImages, although
29 * typically there is only one.
30 *
31 * See also: #DfuImage
32 */
33
34 #include "config.h"
35
36 #include <string.h>
37 #include <stdio.h>
38 #include <appstream-glib.h>
39
40 #include "dfu-common.h"
41 #include "dfu-firmware.h"
42 #include "dfu-format-dfu.h"
43 #include "dfu-format-ihex.h"
44 #include "dfu-format-raw.h"
45 #include "dfu-image.h"
46
47 #include "fwupd-error.h"
48
49 static void dfu_firmware_finalize (GObject *object);
50
51 typedef struct {
52 GHashTable *metadata;
53 GPtrArray *images;
54 guint16 vid;
55 guint16 pid;
56 guint16 release;
57 DfuCipherKind cipher_kind;
58 DfuFirmwareFormat format;
59 } DfuFirmwarePrivate;
60
61 G_DEFINE_TYPE_WITH_PRIVATE (DfuFirmware, dfu_firmware, G_TYPE_OBJECT)
62 #define GET_PRIVATE(o) (dfu_firmware_get_instance_private (o))
63
64 static void
65 dfu_firmware_class_init (DfuFirmwareClass *klass)
66 {
67 GObjectClass *object_class = G_OBJECT_CLASS (klass);
68 object_class->finalize = dfu_firmware_finalize;
69 }
70
71 static void
72 dfu_firmware_init (DfuFirmware *firmware)
73 {
74 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
75 priv->vid = 0xffff;
76 priv->pid = 0xffff;
77 priv->release = 0xffff;
78 priv->images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
79 priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
80 }
81
82 static void
83 dfu_firmware_finalize (GObject *object)
84 {
85 DfuFirmware *firmware = DFU_FIRMWARE (object);
86 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
87
88 g_ptr_array_unref (priv->images);
89 g_hash_table_destroy (priv->metadata);
90
91 G_OBJECT_CLASS (dfu_firmware_parent_class)->finalize (object);
92 }
93
94 /**
95 * dfu_firmware_new:
96 *
97 * Creates a new DFU firmware object.
98 *
99 * Return value: a new #DfuFirmware
100 **/
101 DfuFirmware *
102 dfu_firmware_new (void)
103 {
104 DfuFirmware *firmware;
105 firmware = g_object_new (DFU_TYPE_FIRMWARE, NULL);
106 return firmware;
107 }
108
109 /**
110 * dfu_firmware_get_image:
111 * @firmware: a #DfuFirmware
112 * @alt_setting: an alternative setting, typically 0x00
113 *
114 * Gets an image from the firmware file.
115 *
116 * Return value: (transfer none): a #DfuImage, or %NULL for not found
117 **/
118 DfuImage *
119 dfu_firmware_get_image (DfuFirmware *firmware, guint8 alt_setting)
120 {
121 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
122
123 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
124
125 /* find correct image */
126 for (guint i = 0; i < priv->images->len; i++) {
127 DfuImage *im = g_ptr_array_index (priv->images, i);
128 if (dfu_image_get_alt_setting (im) == alt_setting)
129 return im;
130 }
131 return NULL;
132 }
133
134 /**
135 * dfu_firmware_get_image_by_name:
136 * @firmware: a #DfuFirmware
137 * @name: an alternative setting name
138 *
139 * Gets an image from the firmware file.
140 *
141 * Return value: (transfer none): a #DfuImage, or %NULL for not found
142 **/
143 DfuImage *
144 dfu_firmware_get_image_by_name (DfuFirmware *firmware, const gchar *name)
145 {
146 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
147
148 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
149
150 /* find correct image */
151 for (guint i = 0; i < priv->images->len; i++) {
152 DfuImage *im = g_ptr_array_index (priv->images, i);
153 if (g_strcmp0 (dfu_image_get_name (im), name) == 0)
154 return im;
155 }
156 return NULL;
157 }
158
159 /**
160 * dfu_firmware_get_image_default:
161 * @firmware: a #DfuFirmware
162 *
163 * Gets the default image from the firmware file.
164 *
165 * Return value: (transfer none): a #DfuImage, or %NULL for not found
166 **/
167 DfuImage *
168 dfu_firmware_get_image_default (DfuFirmware *firmware)
169 {
170 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
171 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
172 if (priv->images->len == 0)
173 return NULL;
174 return g_ptr_array_index (priv->images, 0);
175 }
176
177 /**
178 * dfu_firmware_get_images:
179 * @firmware: a #DfuFirmware
180 *
181 * Gets all the images contained in this firmware file.
182 *
183 * Return value: (transfer none) (element-type DfuImage): list of images
184 **/
185 GPtrArray *
186 dfu_firmware_get_images (DfuFirmware *firmware)
187 {
188 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
189 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
190 return priv->images;
191 }
192
193 /**
194 * dfu_firmware_get_size:
195 * @firmware: a #DfuFirmware
196 *
197 * Gets the size of all the images in the firmware.
198 *
199 * This only returns actual data that would be sent to the device and
200 * does not include any padding.
201 *
202 * Return value: a integer value, or 0 if there are no images.
203 **/
204 guint32
205 dfu_firmware_get_size (DfuFirmware *firmware)
206 {
207 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
208 guint32 length = 0;
209 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0);
210 for (guint i = 0; i < priv->images->len; i++) {
211 DfuImage *image = g_ptr_array_index (priv->images, i);
212 length += dfu_image_get_size (image);
213 }
214 return length;
215 }
216
217 /**
218 * dfu_firmware_add_image:
219 * @firmware: a #DfuFirmware
220 * @image: a #DfuImage
221 *
222 * Adds an image to the list of images.
223 **/
224 void
225 dfu_firmware_add_image (DfuFirmware *firmware, DfuImage *image)
226 {
227 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
228 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
229 g_return_if_fail (DFU_IS_IMAGE (image));
230 g_ptr_array_add (priv->images, g_object_ref (image));
231 }
232
233 /**
234 * dfu_firmware_get_vid:
235 * @firmware: a #DfuFirmware
236 *
237 * Gets the vendor ID.
238 *
239 * Return value: a vendor ID, or 0xffff for unset
240 **/
241 guint16
242 dfu_firmware_get_vid (DfuFirmware *firmware)
243 {
244 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
245 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
246 return priv->vid;
247 }
248
249 /**
250 * dfu_firmware_get_pid:
251 * @firmware: a #DfuFirmware
252 *
253 * Gets the product ID.
254 *
255 * Return value: a product ID, or 0xffff for unset
256 **/
257 guint16
258 dfu_firmware_get_pid (DfuFirmware *firmware)
259 {
260 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
261 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
262 return priv->pid;
263 }
264
265 /**
266 * dfu_firmware_get_release:
267 * @firmware: a #DfuFirmware
268 *
269 * Gets the device ID.
270 *
271 * Return value: a device ID, or 0xffff for unset
272 **/
273 guint16
274 dfu_firmware_get_release (DfuFirmware *firmware)
275 {
276 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
277 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
278 return priv->release;
279 }
280
281 /**
282 * dfu_firmware_get_format:
283 * @firmware: a #DfuFirmware
284 *
285 * Gets the DFU version.
286 *
287 * Return value: a version, or 0x0 for unset
288 **/
289 guint16
290 dfu_firmware_get_format (DfuFirmware *firmware)
291 {
292 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
293 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff);
294 return priv->format;
295 }
296
297 /**
298 * dfu_firmware_set_vid:
299 * @firmware: a #DfuFirmware
300 * @vid: vendor ID, or 0xffff for unset
301 *
302 * Sets the vendor ID.
303 **/
304 void
305 dfu_firmware_set_vid (DfuFirmware *firmware, guint16 vid)
306 {
307 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
308 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
309 priv->vid = vid;
310 }
311
312 /**
313 * dfu_firmware_set_pid:
314 * @firmware: a #DfuFirmware
315 * @pid: product ID, or 0xffff for unset
316 *
317 * Sets the product ID.
318 **/
319 void
320 dfu_firmware_set_pid (DfuFirmware *firmware, guint16 pid)
321 {
322 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
323 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
324 priv->pid = pid;
325 }
326
327 /**
328 * dfu_firmware_set_release:
329 * @firmware: a #DfuFirmware
330 * @release: device ID, or 0xffff for unset
331 *
332 * Sets the device ID.
333 **/
334 void
335 dfu_firmware_set_release (DfuFirmware *firmware, guint16 release)
336 {
337 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
338 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
339 priv->release = release;
340 }
341
342 /**
343 * dfu_firmware_set_format:
344 * @firmware: a #DfuFirmware
345 * @format: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFUSE
346 *
347 * Sets the DFU version in BCD format.
348 **/
349 void
350 dfu_firmware_set_format (DfuFirmware *firmware, DfuFirmwareFormat format)
351 {
352 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
353 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
354 priv->format = format;
355 }
356
357 /**
358 * dfu_firmware_parse_data:
359 * @firmware: a #DfuFirmware
360 * @bytes: raw firmware data
361 * @flags: optional flags, e.g. %DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST
362 * @error: a #GError, or %NULL
363 *
364 * Parses firmware data which may have an optional DFU suffix.
365 *
366 * Return value: %TRUE for success
367 **/
368 gboolean
369 dfu_firmware_parse_data (DfuFirmware *firmware, GBytes *bytes,
370 DfuFirmwareParseFlags flags, GError **error)
371 {
372 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
373
374 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE);
375 g_return_val_if_fail (bytes != NULL, FALSE);
376 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
377
378 /* set defaults */
379 priv->vid = 0xffff;
380 priv->pid = 0xffff;
381 priv->release = 0xffff;
382
383 /* try to get format if not already set */
384 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
385 priv->format = dfu_firmware_detect_ihex (bytes);
386 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
387 priv->format = dfu_firmware_detect_dfu (bytes);
388 if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN)
389 priv->format = dfu_firmware_detect_raw (bytes);
390
391 /* handled easily */
392 switch (priv->format) {
393 case DFU_FIRMWARE_FORMAT_INTEL_HEX:
394 if (!dfu_firmware_from_ihex (firmware, bytes, flags, error))
395 return FALSE;
396 break;
397 case DFU_FIRMWARE_FORMAT_DFU:
398 case DFU_FIRMWARE_FORMAT_DFUSE:
399 if (!dfu_firmware_from_dfu (firmware, bytes, flags, error))
400 return FALSE;
401 break;
402 default:
403 if (!dfu_firmware_from_raw (firmware, bytes, flags, error))
404 return FALSE;
405 break;
406 }
407
408 return TRUE;
409 }
410
411 /**
412 * dfu_firmware_parse_file:
413 * @firmware: a #DfuFirmware
414 * @file: a #GFile to load and parse
415 * @flags: optional flags, e.g. %DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST
416 * @cancellable: a #GCancellable, or %NULL
417 * @error: a #GError, or %NULL
418 *
419 * Parses a DFU firmware, which may contain an optional footer.
420 *
421 * Return value: %TRUE for success
422 **/
423 gboolean
424 dfu_firmware_parse_file (DfuFirmware *firmware, GFile *file,
425 DfuFirmwareParseFlags flags,
426 GCancellable *cancellable, GError **error)
427 {
428 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
429 gchar *contents = NULL;
430 gsize length = 0;
431 g_autofree gchar *basename = NULL;
432 g_autoptr(GBytes) bytes = NULL;
433
434 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE);
435 g_return_val_if_fail (G_IS_FILE (file), FALSE);
436 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
437
438 /* guess cipher kind based on file extension */
439 basename = g_file_get_basename (file);
440 if (g_str_has_suffix (basename, ".xdfu"))
441 priv->cipher_kind = DFU_CIPHER_KIND_XTEA;
442
443 if (!g_file_load_contents (file, cancellable, &contents,
444 &length, NULL, error))
445 return FALSE;
446 bytes = g_bytes_new_take (contents, length);
447 return dfu_firmware_parse_data (firmware, bytes, flags, error);
448 }
449
450 /**
451 * dfu_firmware_get_metadata:
452 * @firmware: a #DfuFirmware
453 * @key: metadata string key
454 *
455 * Gets metadata from the store with a specific key.
456 *
457 * Return value: the metadata value, or %NULL for unset
458 **/
459 const gchar *
460 dfu_firmware_get_metadata (DfuFirmware *firmware, const gchar *key)
461 {
462 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
463 return g_hash_table_lookup (priv->metadata, key);
464 }
465
466 /**
467 * dfu_firmware_get_metadata_table:
468 * @firmware: a #DfuFirmware
469 *
470 * Gets all metadata from the store.
471 *
472 * Return value: (transfer none): the metadata hash table
473 **/
474 GHashTable *
475 dfu_firmware_get_metadata_table (DfuFirmware *firmware)
476 {
477 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
478 return priv->metadata;
479 }
480
481 /**
482 * dfu_firmware_set_metadata:
483 * @firmware: a #DfuFirmware
484 * @key: metadata string key
485 * @value: metadata string value
486 *
487 * Sets a metadata value with a specific key.
488 **/
489 void
490 dfu_firmware_set_metadata (DfuFirmware *firmware, const gchar *key, const gchar *value)
491 {
492 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
493 g_debug ("adding metadata %s=%s", key, value);
494 g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value));
495 }
496
497 /**
498 * dfu_firmware_remove_metadata:
499 * @firmware: a #DfuFirmware
500 * @key: metadata string key
501 *
502 * Removes a metadata item from the store
503 **/
504 void
505 dfu_firmware_remove_metadata (DfuFirmware *firmware, const gchar *key)
506 {
507 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
508 g_debug ("removing metadata %s", key);
509 g_hash_table_remove (priv->metadata, key);
510 }
511
512 static gboolean
513 dfu_firmware_check_acceptable_for_format (DfuFirmware *firmware, GError **error)
514 {
515 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
516
517 /* always okay */
518 if (priv->images->len <= 1)
519 return TRUE;
520 if (priv->format == DFU_FIRMWARE_FORMAT_DFUSE)
521 return TRUE;
522
523 /* one is usual, and 2 is okay if one image is the signature */
524 if (priv->format == DFU_FIRMWARE_FORMAT_INTEL_HEX) {
525 if (priv->images->len == 2 &&
526 dfu_firmware_get_image_by_name (firmware, "signature") != NULL)
527 return TRUE;
528 }
529
530 /* unsupported */
531 g_set_error (error,
532 FWUPD_ERROR,
533 FWUPD_ERROR_INTERNAL,
534 "multiple images (%u) not supported for %s",
535 priv->images->len,
536 dfu_firmware_format_to_string (priv->format));
537 return TRUE;
538 }
539
540 /**
541 * dfu_firmware_write_data:
542 * @firmware: a #DfuFirmware
543 * @error: a #GError, or %NULL
544 *
545 * Writes DFU data to a data blob with a DFU-specific footer.
546 *
547 * Return value: (transfer none): firmware data
548 **/
549 GBytes *
550 dfu_firmware_write_data (DfuFirmware *firmware, GError **error)
551 {
552 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
553
554 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
555 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
556
557 /* at least one image */
558 if (priv->images == 0) {
559 g_set_error_literal (error,
560 FWUPD_ERROR,
561 FWUPD_ERROR_INTERNAL,
562 "no image data to write");
563 return NULL;
564 }
565
566 /* does the format support this many images */
567 if (!dfu_firmware_check_acceptable_for_format (firmware, error))
568 return NULL;
569
570 /* raw */
571 if (priv->format == DFU_FIRMWARE_FORMAT_RAW)
572 return dfu_firmware_to_raw (firmware, error);
573
574 /* DFU or DfuSe*/
575 if (priv->format == DFU_FIRMWARE_FORMAT_DFU ||
576 priv->format == DFU_FIRMWARE_FORMAT_DFUSE)
577 return dfu_firmware_to_dfu (firmware, error);
578
579 /* Intel HEX */
580 if (priv->format == DFU_FIRMWARE_FORMAT_INTEL_HEX)
581 return dfu_firmware_to_ihex (firmware, error);
582
583 /* invalid */
584 g_set_error (error,
585 FWUPD_ERROR,
586 FWUPD_ERROR_INTERNAL,
587 "invalid format for write (0x%04x)",
588 priv->format);
589 return NULL;
590 }
591
592 /**
593 * dfu_firmware_write_file:
594 * @firmware: a #DfuFirmware
595 * @file: a #GFile
596 * @cancellable: a #GCancellable, or %NULL
597 * @error: a #GError, or %NULL
598 *
599 * Writes a DFU firmware with the optional footer.
600 *
601 * Return value: %TRUE for success
602 **/
603 gboolean
604 dfu_firmware_write_file (DfuFirmware *firmware, GFile *file,
605 GCancellable *cancellable, GError **error)
606 {
607 const guint8 *data;
608 gsize length = 0;
609 g_autoptr(GBytes) bytes = NULL;
610
611 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE);
612 g_return_val_if_fail (G_IS_FILE (file), FALSE);
613 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
614
615 /* get blob */
616 bytes = dfu_firmware_write_data (firmware, error);
617 if (bytes == NULL)
618 return FALSE;
619
620 /* save to firmware */
621 data = g_bytes_get_data (bytes, &length);
622 return g_file_replace_contents (file,
623 (const gchar *) data,
624 length,
625 NULL,
626 FALSE,
627 G_FILE_CREATE_NONE,
628 NULL,
629 cancellable,
630 error);
631 }
632
633 /**
634 * dfu_firmware_to_string:
635 * @firmware: a #DfuFirmware
636 *
637 * Returns a string representaiton of the object.
638 *
639 * Return value: NULL terminated string, or %NULL for invalid
640 **/
641 gchar *
642 dfu_firmware_to_string (DfuFirmware *firmware)
643 {
644 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
645 DfuImage *image;
646 GString *str;
647 g_autofree gchar *release_str = NULL;
648 g_autoptr(GList) keys = NULL;
649
650 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL);
651
652 release_str = as_utils_version_from_uint16 (priv->release,
653 AS_VERSION_PARSE_FLAG_NONE);
654 str = g_string_new ("");
655 g_string_append_printf (str, "vid: 0x%04x\n", priv->vid);
656 g_string_append_printf (str, "pid: 0x%04x\n", priv->pid);
657 g_string_append_printf (str, "release: 0x%04x [%s]\n",
658 priv->release, release_str);
659 g_string_append_printf (str, "format: %s [0x%04x]\n",
660 dfu_firmware_format_to_string (priv->format),
661 priv->format);
662 g_string_append_printf (str, "cipher: %s\n",
663 dfu_cipher_kind_to_string (priv->cipher_kind));
664
665 /* print metadata */
666 keys = g_hash_table_get_keys (priv->metadata);
667 for (GList *l = keys; l != NULL; l = l->next) {
668 const gchar *key = l->data;
669 const gchar *value;
670 value = g_hash_table_lookup (priv->metadata, key);
671 g_string_append_printf (str, "metadata: %s=%s\n", key, value);
672 }
673
674 /* print images */
675 for (guint i = 0; i < priv->images->len; i++) {
676 g_autofree gchar *tmp = NULL;
677 image = g_ptr_array_index (priv->images, i);
678 tmp = dfu_image_to_string (image);
679 g_string_append_printf (str, "= IMAGE %u =\n", i);
680 g_string_append_printf (str, "%s\n", tmp);
681 }
682
683 g_string_truncate (str, str->len - 1);
684 return g_string_free (str, FALSE);
685 }
686
687 /**
688 * dfu_firmware_format_to_string:
689 * @format: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFU
690 *
691 * Returns a string representaiton of the format.
692 *
693 * Return value: NULL terminated string, or %NULL for invalid
694 **/
695 const gchar *
696 dfu_firmware_format_to_string (DfuFirmwareFormat format)
697 {
698 if (format == DFU_FIRMWARE_FORMAT_RAW)
699 return "raw";
700 if (format == DFU_FIRMWARE_FORMAT_DFU)
701 return "dfu";
702 if (format == DFU_FIRMWARE_FORMAT_DFUSE)
703 return "dfuse";
704 if (format == DFU_FIRMWARE_FORMAT_INTEL_HEX)
705 return "ihex";
706 return NULL;
707 }
708
709 /**
710 * dfu_firmware_format_from_string:
711 * @format: a format string, e.g. `dfuse`
712 *
713 * Returns an enumerated version of the format.
714 *
715 * Return value: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFUSE
716 **/
717 DfuFirmwareFormat
718 dfu_firmware_format_from_string (const gchar *format)
719 {
720 if (g_strcmp0 (format, "raw") == 0)
721 return DFU_FIRMWARE_FORMAT_RAW;
722 if (g_strcmp0 (format, "dfu") == 0)
723 return DFU_FIRMWARE_FORMAT_DFU;
724 if (g_strcmp0 (format, "dfuse") == 0)
725 return DFU_FIRMWARE_FORMAT_DFUSE;
726 if (g_strcmp0 (format, "ihex") == 0)
727 return DFU_FIRMWARE_FORMAT_INTEL_HEX;
728 return DFU_FIRMWARE_FORMAT_UNKNOWN;
729 }
730
731 /**
732 * dfu_firmware_get_cipher_kind:
733 * @firmware: a #DfuFirmware
734 *
735 * Returns the kind of cipher used by the firmware file.
736 *
737 * NOTE: this value is based on a heuristic, and may not be accurate.
738 * The value %DFU_CIPHER_KIND_NONE will be returned when the cipher
739 * is not recognised.
740 *
741 * Return value: NULL terminated string, or %NULL for invalid
742 **/
743 DfuCipherKind
744 dfu_firmware_get_cipher_kind (DfuFirmware *firmware)
745 {
746 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
747 g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0);
748 return priv->cipher_kind;
749 }
750
751 /**
752 * dfu_firmware_set_cipher_kind:
753 * @firmware: a #DfuFirmware
754 * @cipher_kind: a #DfuCipherKind, e.g. %DFU_CIPHER_KIND_XTEA
755 *
756 * Sets the kind of cipher used by the firmware file.
757 **/
758 void
759 dfu_firmware_set_cipher_kind (DfuFirmware *firmware, DfuCipherKind cipher_kind)
760 {
761 DfuFirmwarePrivate *priv = GET_PRIVATE (firmware);
762 g_return_if_fail (DFU_IS_FIRMWARE (firmware));
763 priv->cipher_kind = cipher_kind;
764 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FIRMWARE_H
22 #define __DFU_FIRMWARE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-common.h"
28 #include "dfu-image.h"
29
30 G_BEGIN_DECLS
31
32 #define DFU_TYPE_FIRMWARE (dfu_firmware_get_type ())
33 G_DECLARE_DERIVABLE_TYPE (DfuFirmware, dfu_firmware, DFU, FIRMWARE, GObject)
34
35 struct _DfuFirmwareClass
36 {
37 GObjectClass parent_class;
38 /*< private >*/
39 /* Padding for future expansion */
40 void (*_dfu_firmware_reserved1) (void);
41 void (*_dfu_firmware_reserved2) (void);
42 void (*_dfu_firmware_reserved3) (void);
43 void (*_dfu_firmware_reserved4) (void);
44 void (*_dfu_firmware_reserved5) (void);
45 void (*_dfu_firmware_reserved6) (void);
46 void (*_dfu_firmware_reserved7) (void);
47 void (*_dfu_firmware_reserved8) (void);
48 void (*_dfu_firmware_reserved9) (void);
49 };
50
51 /**
52 * DfuFirmwareParseFlags:
53 * @DFU_FIRMWARE_PARSE_FLAG_NONE: No flags set
54 * @DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST: Do not verify the CRC
55 * @DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST: Do not verify the DFU version
56 * @DFU_FIRMWARE_PARSE_FLAG_NO_METADATA: Do not read the metadata table
57 *
58 * The optional flags used for parsing.
59 **/
60 typedef enum {
61 DFU_FIRMWARE_PARSE_FLAG_NONE = 0,
62 DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST = (1 << 0),
63 DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST = (1 << 1),
64 DFU_FIRMWARE_PARSE_FLAG_NO_METADATA = (1 << 2),
65 /*< private >*/
66 DFU_FIRMWARE_PARSE_FLAG_LAST
67 } DfuFirmwareParseFlags;
68
69 /**
70 * DfuFirmwareFormat:
71 * @DFU_FIRMWARE_FORMAT_UNKNOWN: Format unknown
72 * @DFU_FIRMWARE_FORMAT_RAW: Raw format
73 * @DFU_FIRMWARE_FORMAT_DFU: DFU footer
74 * @DFU_FIRMWARE_FORMAT_DFUSE: DfuSe header
75 * @DFU_FIRMWARE_FORMAT_INTEL_HEX: Intel HEX
76 *
77 * The known versions of the DFU standard in BCD format.
78 **/
79 typedef enum {
80 DFU_FIRMWARE_FORMAT_UNKNOWN,
81 DFU_FIRMWARE_FORMAT_RAW,
82 DFU_FIRMWARE_FORMAT_DFU,
83 DFU_FIRMWARE_FORMAT_DFUSE,
84 DFU_FIRMWARE_FORMAT_INTEL_HEX,
85 /*< private >*/
86 DFU_FIRMWARE_FORMAT_LAST
87 } DfuFirmwareFormat;
88
89 DfuFirmware *dfu_firmware_new (void);
90
91 const gchar *dfu_firmware_format_to_string (DfuFirmwareFormat format);
92 DfuFirmwareFormat dfu_firmware_format_from_string(const gchar *format);
93
94 DfuImage *dfu_firmware_get_image (DfuFirmware *firmware,
95 guint8 alt_setting);
96 DfuImage *dfu_firmware_get_image_by_name (DfuFirmware *firmware,
97 const gchar *name);
98 DfuImage *dfu_firmware_get_image_default (DfuFirmware *firmware);
99 GPtrArray *dfu_firmware_get_images (DfuFirmware *firmware);
100 guint16 dfu_firmware_get_vid (DfuFirmware *firmware);
101 guint16 dfu_firmware_get_pid (DfuFirmware *firmware);
102 guint16 dfu_firmware_get_release (DfuFirmware *firmware);
103 guint16 dfu_firmware_get_format (DfuFirmware *firmware);
104 guint32 dfu_firmware_get_size (DfuFirmware *firmware);
105 DfuCipherKind dfu_firmware_get_cipher_kind (DfuFirmware *firmware);
106
107 void dfu_firmware_add_image (DfuFirmware *firmware,
108 DfuImage *image);
109 void dfu_firmware_set_vid (DfuFirmware *firmware,
110 guint16 vid);
111 void dfu_firmware_set_pid (DfuFirmware *firmware,
112 guint16 pid);
113 void dfu_firmware_set_release (DfuFirmware *firmware,
114 guint16 release);
115 void dfu_firmware_set_format (DfuFirmware *firmware,
116 DfuFirmwareFormat format);
117 void dfu_firmware_set_cipher_kind (DfuFirmware *firmware,
118 DfuCipherKind cipher_kind);
119
120 gboolean dfu_firmware_parse_data (DfuFirmware *firmware,
121 GBytes *bytes,
122 DfuFirmwareParseFlags flags,
123 GError **error);
124 gboolean dfu_firmware_parse_file (DfuFirmware *firmware,
125 GFile *file,
126 DfuFirmwareParseFlags flags,
127 GCancellable *cancellable,
128 GError **error);
129
130 GBytes *dfu_firmware_write_data (DfuFirmware *firmware,
131 GError **error);
132 gboolean dfu_firmware_write_file (DfuFirmware *firmware,
133 GFile *file,
134 GCancellable *cancellable,
135 GError **error);
136 gchar *dfu_firmware_to_string (DfuFirmware *firmware);
137
138 GHashTable *dfu_firmware_get_metadata_table(DfuFirmware *firmware);
139 const gchar *dfu_firmware_get_metadata (DfuFirmware *firmware,
140 const gchar *key);
141 void dfu_firmware_set_metadata (DfuFirmware *firmware,
142 const gchar *key,
143 const gchar *value);
144 void dfu_firmware_remove_metadata (DfuFirmware *firmware,
145 const gchar *key);
146
147 G_END_DECLS
148
149 #endif /* __DFU_FIRMWARE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-dfu.h"
27 #include "dfu-format-metadata.h"
28 #include "dfu-format-dfuse.h"
29 #include "dfu-format-raw.h"
30 #include "dfu-image.h"
31
32 #include "fwupd-error.h"
33
34 typedef struct __attribute__((packed)) {
35 guint16 release;
36 guint16 pid;
37 guint16 vid;
38 guint16 ver;
39 guint8 sig[3];
40 guint8 len;
41 guint32 crc;
42 } DfuFirmwareFooter;
43
44 /**
45 * dfu_firmware_detect_dfu: (skip)
46 * @bytes: data to parse
47 *
48 * Attempts to sniff the data and work out the firmware format
49 *
50 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW
51 **/
52 DfuFirmwareFormat
53 dfu_firmware_detect_dfu (GBytes *bytes)
54 {
55 DfuFirmwareFooter *ftr;
56 guint8 *data;
57 gsize len;
58
59 /* check data size */
60 data = (guint8 *) g_bytes_get_data (bytes, &len);
61 if (len < 16)
62 return DFU_FIRMWARE_FORMAT_UNKNOWN;
63
64 /* check for DFU signature */
65 ftr = (DfuFirmwareFooter *) &data[len - sizeof(DfuFirmwareFooter)];
66 if (memcmp (ftr->sig, "UFD", 3) != 0)
67 return DFU_FIRMWARE_FORMAT_UNKNOWN;
68
69 /* check versions */
70 switch (GUINT16_FROM_LE (ftr->ver)) {
71 case DFU_VERSION_DFU_1_0:
72 case DFU_VERSION_DFU_1_1:
73 return DFU_FIRMWARE_FORMAT_DFU;
74 case DFU_VERSION_DFUSE:
75 return DFU_FIRMWARE_FORMAT_DFUSE;
76 default:
77 break;
78 }
79 return DFU_FIRMWARE_FORMAT_UNKNOWN;
80 }
81
82 static guint32 _crctbl[] = {
83 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
84 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
85 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
86 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
87 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
88 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
89 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
90 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
91 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
92 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
93 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
94 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
95 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
96 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
97 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
98 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
99 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
100 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
101 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
102 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
103 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
104 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
105 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
106 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
107 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
108 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
109 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
110 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
111 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
112 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
113 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
114 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
115 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
116 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
117 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
118 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
119 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
120 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
121 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
122 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
123 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
124 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
125 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
126
127 static guint32
128 dfu_firmware_generate_crc32 (const guint8 *data, gsize length)
129 {
130 guint32 accum = 0xffffffff;
131 for (guint i = 0; i < length; i++)
132 accum = _crctbl[(accum^data[i]) & 0xff] ^ (accum >> 8);
133 return accum;
134 }
135
136 /**
137 * dfu_firmware_from_dfu: (skip)
138 * @firmware: a #DfuFirmware
139 * @bytes: data to parse
140 * @flags: some #DfuFirmwareParseFlags
141 * @error: a #GError, or %NULL
142 *
143 * Unpacks into a firmware object from dfu data.
144 *
145 * Returns: %TRUE for success
146 **/
147 gboolean
148 dfu_firmware_from_dfu (DfuFirmware *firmware,
149 GBytes *bytes,
150 DfuFirmwareParseFlags flags,
151 GError **error)
152 {
153 DfuFirmwareFooter *ftr;
154 const gchar *cipher_str;
155 gsize len;
156 guint32 crc;
157 guint32 crc_new;
158 guint8 *data;
159 g_autoptr(GBytes) contents = NULL;
160
161 /* check data size */
162 data = (guint8 *) g_bytes_get_data (bytes, &len);
163 if (len < 16) {
164 g_set_error_literal (error,
165 FWUPD_ERROR,
166 FWUPD_ERROR_INTERNAL,
167 "size check failed, too small");
168 return FALSE;
169 }
170
171 /* check for DFU signature */
172 ftr = (DfuFirmwareFooter *) &data[len - sizeof(DfuFirmwareFooter)];
173 if (memcmp (ftr->sig, "UFD", 3) != 0) {
174 g_set_error_literal (error,
175 FWUPD_ERROR,
176 FWUPD_ERROR_INTERNAL,
177 "no DFU signature");
178 return FALSE;
179 }
180
181 /* check version */
182 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST) == 0) {
183 if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFU &&
184 dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) {
185 g_set_error (error,
186 FWUPD_ERROR,
187 FWUPD_ERROR_INTERNAL,
188 "version check failed, got %04x",
189 dfu_firmware_get_format (firmware));
190 return FALSE;
191 }
192 }
193
194 /* verify the checksum */
195 crc = GUINT32_FROM_LE (ftr->crc);
196 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
197 crc_new = dfu_firmware_generate_crc32 (data, len - 4);
198 if (crc != crc_new) {
199 g_set_error (error,
200 FWUPD_ERROR,
201 FWUPD_ERROR_INTERNAL,
202 "CRC failed, expected %04x, got %04x",
203 crc_new, GUINT32_FROM_LE (ftr->crc));
204 return FALSE;
205 }
206 }
207
208 /* set from footer */
209 dfu_firmware_set_vid (firmware, GUINT16_FROM_LE (ftr->vid));
210 dfu_firmware_set_pid (firmware, GUINT16_FROM_LE (ftr->pid));
211 dfu_firmware_set_release (firmware, GUINT16_FROM_LE (ftr->release));
212
213 /* check reported length */
214 if (ftr->len > len) {
215 g_set_error (error,
216 FWUPD_ERROR,
217 FWUPD_ERROR_INTERNAL,
218 "reported firmware size %04x larger than file %04x",
219 (guint) ftr->len, (guint) len);
220 return FALSE;
221 }
222
223 /* parse the optional metadata segment */
224 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_METADATA) == 0) {
225 gsize offset = len - ftr->len;
226 g_autoptr(GBytes) md = g_bytes_new (&data[offset], ftr->len);
227 if (!dfu_firmware_from_metadata (firmware, md, flags, error))
228 return FALSE;
229 }
230
231 /* set this automatically */
232 cipher_str = dfu_firmware_get_metadata (firmware, DFU_METADATA_KEY_CIPHER_KIND);
233 if (cipher_str != NULL) {
234 if (g_strcmp0 (cipher_str, "XTEA") == 0)
235 dfu_firmware_set_cipher_kind (firmware, DFU_CIPHER_KIND_XTEA);
236 else
237 g_warning ("Unknown CipherKind: %s", cipher_str);
238 }
239
240 /* parse DfuSe prefix */
241 contents = g_bytes_new_from_bytes (bytes, 0, len - ftr->len);
242 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE)
243 return dfu_firmware_from_dfuse (firmware, contents, flags, error);
244
245 /* just copy old-plain DFU file */
246 return dfu_firmware_from_raw (firmware, contents, flags, error);
247 }
248
249 static DfuVersion
250 dfu_convert_version (DfuFirmwareFormat format)
251 {
252 if (format == DFU_FIRMWARE_FORMAT_DFU)
253 return DFU_VERSION_DFU_1_0;
254 if (format == DFU_FIRMWARE_FORMAT_DFUSE)
255 return DFU_VERSION_DFUSE;
256 return DFU_VERSION_UNKNOWN;
257 }
258
259 static GBytes *
260 dfu_firmware_add_footer (DfuFirmware *firmware, GBytes *contents, GError **error)
261 {
262 DfuFirmwareFooter *ftr;
263 const guint8 *data_bin;
264 const guint8 *data_md;
265 gsize length_bin = 0;
266 gsize length_md = 0;
267 guint32 crc_new;
268 guint8 *buf;
269 g_autoptr(GBytes) metadata_table = NULL;
270
271 /* get any file metadata */
272 metadata_table = dfu_firmware_to_metadata (firmware, error);
273 if (metadata_table == NULL)
274 return NULL;
275 data_md = g_bytes_get_data (metadata_table, &length_md);
276
277 /* add the raw firmware data */
278 data_bin = g_bytes_get_data (contents, &length_bin);
279 buf = g_malloc0 (length_bin + length_md + 0x10);
280 memcpy (buf + 0, data_bin, length_bin);
281
282 /* add the metadata table */
283 memcpy (buf + length_bin, data_md, length_md);
284
285 /* set up LE footer */
286 ftr = (DfuFirmwareFooter *) (buf + length_bin + length_md);
287 ftr->release = GUINT16_TO_LE (dfu_firmware_get_release (firmware));
288 ftr->pid = GUINT16_TO_LE (dfu_firmware_get_pid (firmware));
289 ftr->vid = GUINT16_TO_LE (dfu_firmware_get_vid (firmware));
290 ftr->ver = GUINT16_TO_LE (dfu_convert_version (dfu_firmware_get_format (firmware)));
291 ftr->len = (guint8) (sizeof (DfuFirmwareFooter) + length_md);
292 memcpy(ftr->sig, "UFD", 3);
293 crc_new = dfu_firmware_generate_crc32 (buf, length_bin + length_md + 12);
294 ftr->crc = GUINT32_TO_LE (crc_new);
295
296 /* return all data */
297 return g_bytes_new_take (buf, length_bin + length_md + 0x10);
298 }
299
300 /**
301 * dfu_firmware_to_dfu: (skip)
302 * @firmware: a #DfuFirmware
303 * @error: a #GError, or %NULL
304 *
305 * Packs dfu firmware
306 *
307 * Returns: (transfer full): the packed data
308 **/
309 GBytes *
310 dfu_firmware_to_dfu (DfuFirmware *firmware, GError **error)
311 {
312 /* plain DFU */
313 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFU) {
314 GBytes *contents;
315 DfuElement *element;
316 DfuImage *image;
317 image = dfu_firmware_get_image_default (firmware);
318 g_assert (image != NULL);
319 element = dfu_image_get_element (image, 0);
320 if (element == NULL) {
321 g_set_error (error,
322 FWUPD_ERROR,
323 FWUPD_ERROR_NOT_FOUND,
324 "no firmware element data to write");
325 return NULL;
326 }
327 contents = dfu_element_get_contents (element);
328 return dfu_firmware_add_footer (firmware, contents, error);
329 }
330
331 /* DfuSe */
332 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) {
333 g_autoptr(GBytes) contents = NULL;
334 contents = dfu_firmware_to_dfuse (firmware, error);
335 if (contents == NULL)
336 return NULL;
337 return dfu_firmware_add_footer (firmware, contents, error);
338 }
339
340 g_assert_not_reached ();
341 return NULL;
342 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_DFU_H
22 #define __DFU_FORMAT_DFU_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_dfu (GBytes *bytes);
32 GBytes *dfu_firmware_to_dfu (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_dfu (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_DFU_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-dfuse.h"
27 #include "dfu-image.h"
28
29 #include "fwupd-error.h"
30
31 /* DfuSe element header */
32 typedef struct __attribute__((packed)) {
33 guint32 address;
34 guint32 size;
35 } DfuSeElementPrefix;
36
37 /**
38 * dfu_element_from_dfuse: (skip)
39 * @data: data buffer
40 * @length: length of @data we can access
41 * @consumed: (out): the number of bytes we consued
42 * @error: a #GError, or %NULL
43 *
44 * Unpacks an element from DfuSe data.
45 *
46 * Returns: a #DfuElement, or %NULL for error
47 **/
48 static DfuElement *
49 dfu_element_from_dfuse (const guint8 *data,
50 guint32 length,
51 guint32 *consumed,
52 GError **error)
53 {
54 DfuElement *element = NULL;
55 DfuSeElementPrefix *el = (DfuSeElementPrefix *) data;
56 guint32 size;
57 g_autoptr(GBytes) contents = NULL;
58
59 g_assert_cmpint(sizeof(DfuSeElementPrefix), ==, 8);
60
61 /* check input buffer size */
62 if (length < sizeof(DfuSeElementPrefix)) {
63 g_set_error (error,
64 FWUPD_ERROR,
65 FWUPD_ERROR_INTERNAL,
66 "invalid element data size %u",
67 (guint32) length);
68 return NULL;
69 }
70
71 /* check size */
72 size = GUINT32_FROM_LE (el->size);
73 if (size + sizeof(DfuSeElementPrefix) > length) {
74 g_set_error (error,
75 FWUPD_ERROR,
76 FWUPD_ERROR_INTERNAL,
77 "invalid element size %u, only %u bytes left",
78 size,
79 (guint32) (length - sizeof(DfuSeElementPrefix)));
80 return NULL;
81 }
82
83 /* create new element */
84 element = dfu_element_new ();
85 dfu_element_set_address (element, GUINT32_FROM_LE (el->address));
86 contents = g_bytes_new (data + sizeof(DfuSeElementPrefix), size);
87 dfu_element_set_contents (element, contents);
88
89 /* return size */
90 if (consumed != NULL)
91 *consumed = (guint32) sizeof(DfuSeElementPrefix) + size;
92
93 return element;
94 }
95
96 /**
97 * dfu_element_to_dfuse: (skip)
98 * @element: a #DfuElement
99 *
100 * Packs a DfuSe element.
101 *
102 * Returns: (transfer full): the packed data
103 **/
104 static GBytes *
105 dfu_element_to_dfuse (DfuElement *element)
106 {
107 DfuSeElementPrefix *el;
108 const guint8 *data;
109 gsize length;
110 guint8 *buf;
111
112 data = g_bytes_get_data (dfu_element_get_contents (element), &length);
113 buf = g_malloc0 (length + sizeof (DfuSeElementPrefix));
114 el = (DfuSeElementPrefix *) buf;
115 el->address = GUINT32_TO_LE (dfu_element_get_address (element));
116 el->size = GUINT32_TO_LE (length);
117
118 memcpy (buf + sizeof (DfuSeElementPrefix), data, length);
119 return g_bytes_new_take (buf, length + sizeof (DfuSeElementPrefix));
120 }
121
122 /* DfuSe image header */
123 typedef struct __attribute__((packed)) {
124 guint8 sig[6];
125 guint8 alt_setting;
126 guint32 target_named;
127 gchar target_name[255];
128 guint32 target_size;
129 guint32 elements;
130 } DfuSeImagePrefix;
131
132 /**
133 * dfu_image_from_dfuse: (skip)
134 * @data: data buffer
135 * @length: length of @data we can access
136 * @consumed: (out): the number of bytes we consued
137 * @error: a #GError, or %NULL
138 *
139 * Unpacks an image from DfuSe data.
140 *
141 * Returns: a #DfuImage, or %NULL for error
142 **/
143 static DfuImage *
144 dfu_image_from_dfuse (const guint8 *data,
145 guint32 length,
146 guint32 *consumed,
147 GError **error)
148 {
149 DfuSeImagePrefix *im;
150 guint32 elements;
151 guint32 offset = sizeof(DfuSeImagePrefix);
152 g_autoptr(DfuImage) image = NULL;
153
154 g_assert_cmpint(sizeof(DfuSeImagePrefix), ==, 274);
155
156 /* check input buffer size */
157 if (length < sizeof(DfuSeImagePrefix)) {
158 g_set_error (error,
159 FWUPD_ERROR,
160 FWUPD_ERROR_INTERNAL,
161 "invalid image data size %u",
162 (guint32) length);
163 return NULL;
164 }
165
166 /* verify image signature */
167 im = (DfuSeImagePrefix *) data;
168 if (memcmp (im->sig, "Target", 6) != 0) {
169 g_set_error_literal (error,
170 FWUPD_ERROR,
171 FWUPD_ERROR_INVALID_FILE,
172 "invalid DfuSe target signature");
173 return NULL;
174 }
175
176 /* create new image */
177 image = dfu_image_new ();
178 dfu_image_set_alt_setting (image, im->alt_setting);
179 if (GUINT32_FROM_LE (im->target_named) == 0x01)
180 dfu_image_set_name (image, im->target_name);
181
182 /* parse elements */
183 length -= offset;
184 elements = GUINT32_FROM_LE (im->elements);
185 for (guint j = 0; j < elements; j++) {
186 guint32 consumed_local;
187 g_autoptr(DfuElement) element = NULL;
188 element = dfu_element_from_dfuse (data + offset, length,
189 &consumed_local, error);
190 if (element == NULL)
191 return NULL;
192 dfu_image_add_element (image, element);
193 offset += consumed_local;
194 length -= consumed_local;
195 }
196
197 /* return size */
198 if (consumed != NULL)
199 *consumed = offset;
200
201 return g_object_ref (image);
202 }
203
204 /**
205 * dfu_image_to_dfuse: (skip)
206 * @image: a #DfuImage
207 *
208 * Packs a DfuSe image
209 *
210 * Returns: (transfer full): the packed data
211 **/
212 static GBytes *
213 dfu_image_to_dfuse (DfuImage *image)
214 {
215 DfuSeImagePrefix *im;
216 GPtrArray *elements;
217 guint32 length_total = 0;
218 guint32 offset = sizeof (DfuSeImagePrefix);
219 guint8 *buf;
220 g_autoptr(GPtrArray) element_array = NULL;
221
222 /* get total size */
223 element_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
224 elements = dfu_image_get_elements (image);
225 for (guint i = 0; i < elements->len; i++) {
226 DfuElement *element = g_ptr_array_index (elements, i);
227 GBytes *bytes = dfu_element_to_dfuse (element);
228 g_ptr_array_add (element_array, bytes);
229 length_total += (guint32) g_bytes_get_size (bytes);
230 }
231
232 /* add prefix */
233 buf = g_malloc0 (length_total + sizeof (DfuSeImagePrefix));
234 im = (DfuSeImagePrefix *) buf;
235 memcpy (im->sig, "Target", 6);
236 im->alt_setting = dfu_image_get_alt_setting (image);
237 if (dfu_image_get_name (image) != NULL) {
238 im->target_named = GUINT32_TO_LE (0x01);
239 memcpy (im->target_name, dfu_image_get_name (image), 255);
240 }
241 im->target_size = GUINT32_TO_LE (length_total);
242 im->elements = GUINT32_TO_LE (elements->len);
243
244 /* copy data */
245 for (guint i = 0; i < element_array->len; i++) {
246 gsize length;
247 GBytes *bytes = g_ptr_array_index (element_array, i);
248 const guint8 *data = g_bytes_get_data (bytes, &length);
249 memcpy (buf + offset, data, length);
250 offset += (guint32) length;
251 }
252 return g_bytes_new_take (buf, length_total + sizeof (DfuSeImagePrefix));
253 }
254
255 /* DfuSe header */
256 typedef struct __attribute__((packed)) {
257 guint8 sig[5];
258 guint8 ver;
259 guint32 image_size;
260 guint8 targets;
261 } DfuSePrefix;
262
263 /**
264 * dfu_firmware_to_dfuse: (skip)
265 * @firmware: a #DfuFirmware
266 * @error: a #GError, or %NULL
267 *
268 * Packs a DfuSe firmware
269 *
270 * Returns: (transfer full): the packed data
271 **/
272 GBytes *
273 dfu_firmware_to_dfuse (DfuFirmware *firmware, GError **error)
274 {
275 DfuSePrefix *prefix;
276 GPtrArray *images;
277 guint32 image_size_total = 0;
278 guint32 offset = sizeof (DfuSePrefix);
279 g_autofree guint8 *buf = NULL;
280 g_autoptr(GPtrArray) dfuse_images = NULL;
281
282 /* get all the image data */
283 dfuse_images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
284 images = dfu_firmware_get_images (firmware);
285 for (guint i = 0; i < images->len; i++) {
286 DfuImage *im = g_ptr_array_index (images, i);
287 GBytes *contents;
288 contents = dfu_image_to_dfuse (im);
289 image_size_total += (guint32) g_bytes_get_size (contents);
290 g_ptr_array_add (dfuse_images, contents);
291 }
292 g_debug ("image_size_total: %" G_GUINT32_FORMAT, image_size_total);
293
294 buf = g_malloc0 (sizeof (DfuSePrefix) + image_size_total);
295
296 /* DfuSe header */
297 prefix = (DfuSePrefix *) buf;
298 memcpy (prefix->sig, "DfuSe", 5);
299 prefix->ver = 0x01;
300 prefix->image_size = GUINT32_TO_LE (offset + image_size_total);
301 if (images->len > G_MAXUINT8) {
302 g_set_error (error,
303 FWUPD_ERROR,
304 FWUPD_ERROR_INTERNAL,
305 "too many (%u) images to write DfuSe file",
306 images->len);
307 return NULL;
308 }
309 prefix->targets = (guint8) images->len;
310
311 /* copy images */
312 for (guint i = 0; i < dfuse_images->len; i++) {
313 GBytes *contents = g_ptr_array_index (dfuse_images, i);
314 gsize length;
315 const guint8 *data;
316 data = g_bytes_get_data (contents, &length);
317 memcpy (buf + offset, data, length);
318 offset += (guint32) length;
319 }
320
321 /* return blob */
322 return g_bytes_new (buf, sizeof (DfuSePrefix) + image_size_total);
323 }
324
325 /**
326 * dfu_firmware_from_dfuse: (skip)
327 * @firmware: a #DfuFirmware
328 * @bytes: data to parse
329 * @flags: some #DfuFirmwareParseFlags
330 * @error: a #GError, or %NULL
331 *
332 * Unpacks into a firmware object from DfuSe data.
333 *
334 * Returns: %TRUE for success
335 **/
336 gboolean
337 dfu_firmware_from_dfuse (DfuFirmware *firmware,
338 GBytes *bytes,
339 DfuFirmwareParseFlags flags,
340 GError **error)
341 {
342 DfuSePrefix *prefix;
343 gsize len;
344 guint32 offset = sizeof(DfuSePrefix);
345 guint8 *data;
346
347 /* check the prefix (BE) */
348 data = (guint8 *) g_bytes_get_data (bytes, &len);
349 prefix = (DfuSePrefix *) data;
350 if (memcmp (prefix->sig, "DfuSe", 5) != 0) {
351 g_set_error_literal (error,
352 FWUPD_ERROR,
353 FWUPD_ERROR_INTERNAL,
354 "invalid DfuSe prefix");
355 return FALSE;
356 }
357
358 /* check the version */
359 if (prefix->ver != 0x01) {
360 g_set_error (error,
361 FWUPD_ERROR,
362 FWUPD_ERROR_INTERNAL,
363 "invalid DfuSe version, got %02x",
364 prefix->ver);
365 return FALSE;
366 }
367
368 /* check image size */
369 if (GUINT32_FROM_LE (prefix->image_size) != len) {
370 g_set_error (error,
371 FWUPD_ERROR,
372 FWUPD_ERROR_INTERNAL,
373 "invalid DfuSe image size, "
374 "got %" G_GUINT32_FORMAT ", "
375 "expected %" G_GSIZE_FORMAT,
376 GUINT32_FROM_LE (prefix->image_size),
377 len);
378 return FALSE;
379 }
380
381 /* parse the image targets */
382 len -= sizeof(DfuSePrefix);
383 for (guint i = 0; i < prefix->targets; i++) {
384 guint consumed;
385 g_autoptr(DfuImage) image = NULL;
386 image = dfu_image_from_dfuse (data + offset, (guint32) len,
387 &consumed, error);
388 if (image == NULL)
389 return FALSE;
390 dfu_firmware_add_image (firmware, image);
391 offset += consumed;
392 len -= consumed;
393 }
394 return TRUE;
395 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_DFUSE_H
22 #define __DFU_FORMAT_DFUSE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_dfuse (GBytes *bytes);
32 GBytes *dfu_firmware_to_dfuse (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_dfuse (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_DFUSE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-firmware.h"
27 #include "dfu-format-ihex.h"
28 #include "dfu-image.h"
29
30 #include "fwupd-error.h"
31
32 /**
33 * dfu_firmware_detect_ihex: (skip)
34 * @bytes: data to parse
35 *
36 * Attempts to sniff the data and work out the firmware format
37 *
38 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW
39 **/
40 DfuFirmwareFormat
41 dfu_firmware_detect_ihex (GBytes *bytes)
42 {
43 guint8 *data;
44 gsize len;
45 data = (guint8 *) g_bytes_get_data (bytes, &len);
46 if (len < 12)
47 return DFU_FIRMWARE_FORMAT_UNKNOWN;
48 if (data[0] != ':')
49 return DFU_FIRMWARE_FORMAT_UNKNOWN;
50 return DFU_FIRMWARE_FORMAT_INTEL_HEX;
51 }
52
53 static guint8
54 dfu_firmware_ihex_parse_uint8 (const gchar *data, guint pos)
55 {
56 gchar buffer[3];
57 memcpy (buffer, data + pos, 2);
58 buffer[2] = '\0';
59 return (guint8) g_ascii_strtoull (buffer, NULL, 16);
60 }
61
62 static guint16
63 dfu_firmware_ihex_parse_uint16 (const gchar *data, guint pos)
64 {
65 gchar buffer[5];
66 memcpy (buffer, data + pos, 4);
67 buffer[4] = '\0';
68 return (guint16) g_ascii_strtoull (buffer, NULL, 16);
69 }
70
71 #define DFU_INHX32_RECORD_TYPE_DATA 0x00
72 #define DFU_INHX32_RECORD_TYPE_EOF 0x01
73 #define DFU_INHX32_RECORD_TYPE_EXTENDED 0x04
74 #define DFU_INHX32_RECORD_TYPE_SIGNATURE 0xfd
75
76 /**
77 * dfu_firmware_from_ihex: (skip)
78 * @firmware: a #DfuFirmware
79 * @bytes: data to parse
80 * @flags: some #DfuFirmwareParseFlags
81 * @error: a #GError, or %NULL
82 *
83 * Unpacks into a firmware object from raw data.
84 *
85 * Returns: %TRUE for success
86 **/
87 gboolean
88 dfu_firmware_from_ihex (DfuFirmware *firmware,
89 GBytes *bytes,
90 DfuFirmwareParseFlags flags,
91 GError **error)
92 {
93 const gchar *in_buffer;
94 gboolean got_eof = FALSE;
95 gsize len_in;
96 guint16 addr_high = 0;
97 guint16 addr_low = 0;
98 guint32 addr32 = 0;
99 guint32 addr32_last = 0;
100 guint32 element_address = 0;
101 guint8 checksum;
102 guint8 data_tmp;
103 guint8 len_tmp;
104 guint8 type;
105 guint end;
106 guint offset = 0;
107 g_autoptr(DfuElement) element = NULL;
108 g_autoptr(DfuImage) image = NULL;
109 g_autoptr(GBytes) contents = NULL;
110 g_autoptr(GString) string = NULL;
111 g_autoptr(GString) signature = g_string_new (NULL);
112
113 g_return_val_if_fail (bytes != NULL, FALSE);
114
115 /* create element */
116 image = dfu_image_new ();
117 dfu_image_set_name (image, "ihex");
118 element = dfu_element_new ();
119
120 /* parse records */
121 in_buffer = g_bytes_get_data (bytes, &len_in);
122 string = g_string_new ("");
123 while (offset < len_in) {
124
125 /* check starting token */
126 if (in_buffer[offset] != ':') {
127 g_set_error (error,
128 FWUPD_ERROR,
129 FWUPD_ERROR_INVALID_FILE,
130 "invalid starting token, got %c at %x",
131 in_buffer[offset], offset);
132 return FALSE;
133 }
134
135 /* check there's enough data for the smallest possible record */
136 if (offset + 12 > (guint) len_in) {
137 g_set_error (error,
138 FWUPD_ERROR,
139 FWUPD_ERROR_INVALID_FILE,
140 "record incomplete at %u, length %u",
141 offset, (guint) len_in);
142 return FALSE;
143 }
144
145 /* length, 16-bit address, type */
146 len_tmp = dfu_firmware_ihex_parse_uint8 (in_buffer, offset+1);
147 addr_low = dfu_firmware_ihex_parse_uint16 (in_buffer, offset+3);
148 type = dfu_firmware_ihex_parse_uint8 (in_buffer, offset+7);
149
150 /* position of checksum */
151 end = offset + 9 + len_tmp * 2;
152 if (end > (guint) len_in) {
153 g_set_error (error,
154 FWUPD_ERROR,
155 FWUPD_ERROR_INVALID_FILE,
156 "checksum > file length: %u",
157 end);
158 return FALSE;
159 }
160
161 /* verify checksum */
162 if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
163 checksum = 0;
164 for (guint i = offset + 1; i < end + 2; i += 2) {
165 data_tmp = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
166 checksum += data_tmp;
167 }
168 if (checksum != 0) {
169 g_set_error_literal (error,
170 FWUPD_ERROR,
171 FWUPD_ERROR_INVALID_FILE,
172 "invalid record checksum");
173 return FALSE;
174 }
175 }
176
177 /* process different record types */
178 switch (type) {
179 case DFU_INHX32_RECORD_TYPE_DATA:
180 /* if not contiguous with previous record */
181 if ((addr_high + addr_low) != addr32) {
182 if (addr32 == 0x0) {
183 g_debug ("base address %08x", addr_low);
184 dfu_element_set_address (element, addr_low);
185 }
186 addr32 = ((guint32) addr_high << 16) + addr_low;
187 if (element_address == 0x0)
188 element_address = addr32;
189 }
190
191 /* does not make sense */
192 if (addr32 < addr32_last) {
193 g_set_error (error,
194 FWUPD_ERROR,
195 FWUPD_ERROR_INVALID_FILE,
196 "invalid address 0x%x, last was 0x%x",
197 (guint) addr32,
198 (guint) addr32_last);
199 return FALSE;
200 }
201
202 /* parse bytes from line */
203 g_debug ("writing data 0x%08x", (guint32) addr32);
204 for (guint i = offset + 9; i < end; i += 2) {
205 /* any holes in the hex record */
206 guint32 len_hole = addr32 - addr32_last;
207 if (addr32_last > 0x0 && len_hole > 1) {
208 for (guint j = 1; j < len_hole; j++) {
209 g_debug ("filling address 0x%08x",
210 addr32_last + j);
211 /* although 0xff might be clearer,
212 * we can't write 0xffff to pic14 */
213 g_string_append_c (string, 0x00);
214 }
215 }
216 /* write into buf */
217 data_tmp = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
218 g_string_append_c (string, (gchar) data_tmp);
219 addr32_last = addr32++;
220 }
221 break;
222 case DFU_INHX32_RECORD_TYPE_EOF:
223 if (got_eof) {
224 g_set_error_literal (error,
225 FWUPD_ERROR,
226 FWUPD_ERROR_INVALID_FILE,
227 "duplicate EOF, perhaps "
228 "corrupt file");
229 return FALSE;
230 }
231 got_eof = TRUE;
232 break;
233 case DFU_INHX32_RECORD_TYPE_EXTENDED:
234 addr_high = dfu_firmware_ihex_parse_uint16 (in_buffer, offset+9);
235 addr32 = ((guint32) addr_high << 16) + addr_low;
236 break;
237 case DFU_INHX32_RECORD_TYPE_SIGNATURE:
238 for (guint i = offset + 9; i < end; i += 2) {
239 guint8 tmp_c = dfu_firmware_ihex_parse_uint8 (in_buffer, i);
240 g_string_append_c (signature, tmp_c);
241 }
242 break;
243 default:
244 /* vendors sneak in nonstandard sections past the EOF */
245 if (got_eof)
246 break;
247 g_set_error (error,
248 FWUPD_ERROR,
249 FWUPD_ERROR_INVALID_FILE,
250 "invalid ihex record type %i",
251 type);
252 return FALSE;
253 }
254
255 /* ignore any line return */
256 offset = end + 2;
257 for (; offset < len_in; offset++) {
258 if (in_buffer[offset] != '\n' &&
259 in_buffer[offset] != '\r')
260 break;
261 }
262 }
263
264 /* no EOF */
265 if (!got_eof) {
266 g_set_error_literal (error,
267 FWUPD_ERROR,
268 FWUPD_ERROR_INVALID_FILE,
269 "no EOF, perhaps truncated file");
270 return FALSE;
271 }
272
273 /* add single image */
274 contents = g_bytes_new (string->str, string->len);
275 dfu_element_set_contents (element, contents);
276 dfu_element_set_address (element, element_address);
277 dfu_image_add_element (image, element);
278 dfu_firmware_add_image (firmware, image);
279 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
280
281 /* add optional signature */
282 if (signature->len > 0) {
283 g_autoptr(DfuElement) element_sig = dfu_element_new ();
284 g_autoptr(DfuImage) image_sig = dfu_image_new ();
285 g_autoptr(GBytes) data = g_bytes_new_static (signature->str, signature->len);
286 dfu_element_set_contents (element_sig, data);
287 dfu_image_add_element (image_sig, element_sig);
288 dfu_image_set_name (image_sig, "signature");
289 dfu_firmware_add_image (firmware, image_sig);
290 }
291 return TRUE;
292 }
293
294 static void
295 dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type,
296 guint32 address, GBytes *contents)
297 {
298 const guint8 *data;
299 const guint chunk_size = 16;
300 gsize len;
301
302 /* get number of chunks */
303 data = g_bytes_get_data (contents, &len);
304 for (gsize i = 0; i < len; i += chunk_size) {
305 guint8 checksum = 0;
306
307 /* length, 16-bit address, type */
308 gsize chunk_len = MIN (len - i, 16);
309 g_string_append_printf (str, ":%02X%04X%02X",
310 (guint) chunk_len,
311 (guint) (address + i),
312 (guint) record_type);
313 for (gsize j = 0; j < chunk_len; j++)
314 g_string_append_printf (str, "%02X", data[i+j]);
315
316 /* add checksum */
317 for (gsize j = 0; j < (chunk_len * 2) + 8; j++)
318 checksum += (guint8) str->str[str->len - (j + 1)];
319 g_string_append_printf (str, "%02X\n", checksum);
320 }
321 }
322
323 static gboolean
324 dfu_firmware_to_ihex_element (DfuElement *element, GString *str,
325 guint8 record_type, GError **error)
326 {
327 GBytes *contents = dfu_element_get_contents (element);
328 dfu_firmware_to_ihex_bytes (str, record_type,
329 dfu_element_get_address (element),
330 contents);
331 return TRUE;
332 }
333
334 static gboolean
335 dfu_firmware_to_ihex_image (DfuImage *image, GString *str, GError **error)
336 {
337 GPtrArray *elements;
338 guint8 record_type = DFU_INHX32_RECORD_TYPE_DATA;
339
340 if (g_strcmp0 (dfu_image_get_name (image), "signature") == 0)
341 record_type = DFU_INHX32_RECORD_TYPE_SIGNATURE;
342 elements = dfu_image_get_elements (image);
343 for (guint i = 0; i < elements->len; i++) {
344 DfuElement *element = g_ptr_array_index (elements, i);
345 if (!dfu_firmware_to_ihex_element (element,
346 str,
347 record_type,
348 error))
349 return FALSE;
350 }
351 return TRUE;
352 }
353
354 /**
355 * dfu_firmware_to_ihex: (skip)
356 * @firmware: a #DfuFirmware
357 * @error: a #GError, or %NULL
358 *
359 * Packs a IHEX firmware
360 *
361 * Returns: (transfer full): the packed data
362 **/
363 GBytes *
364 dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error)
365 {
366 GPtrArray *images;
367 g_autoptr(GString) str = NULL;
368
369 /* write all the element data */
370 str = g_string_new ("");
371 images = dfu_firmware_get_images (firmware);
372 for (guint i = 0; i < images->len; i++) {
373 DfuImage *image = g_ptr_array_index (images, i);
374 if (!dfu_firmware_to_ihex_image (image, str, error))
375 return NULL;
376 }
377
378 /* add EOF */
379 g_string_append_printf (str, ":000000%02XFF\n",
380 (guint) DFU_INHX32_RECORD_TYPE_EOF);
381
382 return g_bytes_new (str->str, str->len);
383 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_IHEX_H
22 #define __DFU_FORMAT_IHEX_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_ihex (GBytes *bytes);
32 GBytes *dfu_firmware_to_ihex (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_ihex (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_IHEX_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-metadata.h"
27 #include "dfu-image.h"
28
29 #include "fwupd-error.h"
30
31 /**
32 * dfu_firmware_from_metadata: (skip)
33 * @firmware: a #DfuFirmware
34 * @bytes: data to parse
35 * @flags: some #DfuFirmwareParseFlags
36 * @error: a #GError, or %NULL
37 *
38 * Unpacks into a firmware object from metadata data.
39 *
40 * The representation in memory is as follows:
41 *
42 * uint16 signature='MD'
43 * uint8 number_of_keys
44 * uint8 number_of_keys
45 * uint8 key(n)_length
46 * ... key(n) (no NUL)
47 * uint8 value(n)_length
48 * ... value(n) (no NUL)
49 * <existing DFU footer>
50
51 * Returns: %TRUE for success
52 **/
53 gboolean
54 dfu_firmware_from_metadata (DfuFirmware *firmware,
55 GBytes *bytes,
56 DfuFirmwareParseFlags flags,
57 GError **error)
58 {
59 const guint8 *data;
60 gsize data_length;
61 guint idx = 2;
62 guint kvlen;
63 guint number_keys;
64
65 /* not big enough */
66 data = g_bytes_get_data (bytes, &data_length);
67 if (data_length <= 0x10)
68 return TRUE;
69
70 /* signature invalid */
71 if (memcmp (data, "MD", 2) != 0)
72 return TRUE;
73
74 /* parse key=value store */
75 number_keys = data[idx++];
76 for (guint i = 0; i < number_keys; i++) {
77 g_autofree gchar *key = NULL;
78 g_autofree gchar *value = NULL;
79
80 /* parse key */
81 kvlen = data[idx++];
82 if (kvlen > 233) {
83 g_set_error (error,
84 FWUPD_ERROR,
85 FWUPD_ERROR_INTERNAL,
86 "metadata table corrupt, key=%u",
87 kvlen);
88 return FALSE;
89 }
90 if (idx + kvlen + 0x10 > data_length) {
91 g_set_error (error,
92 FWUPD_ERROR,
93 FWUPD_ERROR_INTERNAL,
94 "metadata table corrupt, k-kvlen=%u",
95 kvlen);
96 return FALSE;
97 }
98 key = g_strndup ((const gchar *) data + idx, kvlen);
99 idx += kvlen;
100
101 /* parse value */
102 kvlen = data[idx++];
103 if (kvlen > 233) {
104 g_set_error (error,
105 FWUPD_ERROR,
106 FWUPD_ERROR_INTERNAL,
107 "metadata table corrupt, value=%u",
108 kvlen);
109 return FALSE;
110 }
111 if (idx + kvlen + 0x10 > data_length) {
112 g_set_error (error,
113 FWUPD_ERROR,
114 FWUPD_ERROR_INTERNAL,
115 "metadata table corrupt, v-kvlen=%u",
116 kvlen);
117 return FALSE;
118 }
119 value = g_strndup ((const gchar *) data + idx, kvlen);
120 idx += kvlen;
121 dfu_firmware_set_metadata (firmware, key, value);
122 }
123 return TRUE;
124 }
125
126 /**
127 * dfu_firmware_to_metadata: (skip)
128 * @firmware: a #DfuFirmware
129 * @error: a #GError, or %NULL
130 *
131 * Packs metadata firmware
132 *
133 * Returns: (transfer full): the packed data
134 **/
135 GBytes *
136 dfu_firmware_to_metadata (DfuFirmware *firmware, GError **error)
137 {
138 GHashTable *metadata;
139 guint8 mdbuf[239];
140 guint idx = 0;
141 guint number_keys;
142 g_autoptr(GList) keys = NULL;
143
144 /* no metadata */
145 metadata = dfu_firmware_get_metadata_table (firmware);
146 if (g_hash_table_size (metadata) == 0)
147 return g_bytes_new (NULL, 0);
148
149 /* check the number of keys */
150 keys = g_hash_table_get_keys (metadata);
151 number_keys = g_list_length (keys);
152 if (number_keys > 59) {
153 g_set_error (error,
154 FWUPD_ERROR,
155 FWUPD_ERROR_NOT_SUPPORTED,
156 "too many metadata keys (%u)",
157 number_keys);
158 return NULL;
159 }
160
161 /* write the signature */
162 mdbuf[idx++] = 'M';
163 mdbuf[idx++] = 'D';
164 mdbuf[idx++] = (guint8) number_keys;
165 for (GList *l = keys; l != NULL; l = l->next) {
166 const gchar *key;
167 const gchar *value;
168 guint key_len;
169 guint value_len;
170
171 /* check key and value length */
172 key = l->data;
173 key_len = (guint) strlen (key);
174 if (key_len > 233) {
175 g_set_error (error,
176 FWUPD_ERROR,
177 FWUPD_ERROR_NOT_SUPPORTED,
178 "metdata key too long: %s",
179 key);
180 return NULL;
181 }
182 value = g_hash_table_lookup (metadata, key);
183 value_len = (guint) strlen (value);
184 if (value_len > 233) {
185 g_set_error (error,
186 FWUPD_ERROR,
187 FWUPD_ERROR_NOT_SUPPORTED,
188 "value too long: %s",
189 value);
190 return NULL;
191 }
192
193 /* do we still have space? */
194 if (idx + key_len + value_len + 2 > sizeof(mdbuf)) {
195 g_set_error (error,
196 FWUPD_ERROR,
197 FWUPD_ERROR_NOT_SUPPORTED,
198 "not enough space in metadata table, "
199 "already used %u bytes", idx);
200 return NULL;
201 }
202
203 /* write the key */
204 mdbuf[idx++] = (guint8) key_len;
205 memcpy(mdbuf + idx, key, key_len);
206 idx += key_len;
207
208 /* write the value */
209 mdbuf[idx++] = (guint8) value_len;
210 memcpy(mdbuf + idx, value, value_len);
211 idx += value_len;
212 }
213 g_debug ("metadata table was %u/%" G_GSIZE_FORMAT " bytes",
214 idx, sizeof(mdbuf));
215 return g_bytes_new (mdbuf, idx);
216 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_METADATA_H
22 #define __DFU_FORMAT_METADATA_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 GBytes *dfu_firmware_to_metadata (DfuFirmware *firmware,
32 GError **error);
33 gboolean dfu_firmware_from_metadata (DfuFirmware *firmware,
34 GBytes *bytes,
35 DfuFirmwareParseFlags flags,
36 GError **error);
37
38 G_END_DECLS
39
40 #endif /* __DFU_FORMAT_METADATA_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "dfu-element.h"
26 #include "dfu-format-raw.h"
27 #include "dfu-image.h"
28
29 #include "fwupd-error.h"
30
31 /**
32 * dfu_firmware_detect_raw: (skip)
33 * @bytes: data to parse
34 *
35 * Attempts to sniff the data and work out the firmware format
36 *
37 * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW
38 **/
39 DfuFirmwareFormat
40 dfu_firmware_detect_raw (GBytes *bytes)
41 {
42 return DFU_FIRMWARE_FORMAT_RAW;
43 }
44
45 /**
46 * dfu_firmware_from_raw: (skip)
47 * @firmware: a #DfuFirmware
48 * @bytes: data to parse
49 * @flags: some #DfuFirmwareParseFlags
50 * @error: a #GError, or %NULL
51 *
52 * Unpacks into a firmware object from raw data.
53 *
54 * Returns: %TRUE for success
55 **/
56 gboolean
57 dfu_firmware_from_raw (DfuFirmware *firmware,
58 GBytes *bytes,
59 DfuFirmwareParseFlags flags,
60 GError **error)
61 {
62 g_autoptr(DfuElement) element = NULL;
63 g_autoptr(DfuImage) image = NULL;
64 image = dfu_image_new ();
65 element = dfu_element_new ();
66 dfu_element_set_contents (element, bytes);
67 dfu_image_add_element (image, element);
68 dfu_firmware_add_image (firmware, image);
69 return TRUE;
70 }
71
72 /**
73 * dfu_firmware_to_raw: (skip)
74 * @firmware: a #DfuFirmware
75 * @error: a #GError, or %NULL
76 *
77 * Packs raw firmware
78 *
79 * Returns: (transfer full): the packed data
80 **/
81 GBytes *
82 dfu_firmware_to_raw (DfuFirmware *firmware, GError **error)
83 {
84 DfuElement *element;
85 DfuImage *image;
86 GBytes *contents;
87
88 image = dfu_firmware_get_image_default (firmware);
89 if (image == NULL) {
90 g_set_error_literal (error,
91 FWUPD_ERROR,
92 FWUPD_ERROR_NOT_FOUND,
93 "no firmware image data to write");
94 return NULL;
95 }
96 element = dfu_image_get_element (image, 0);
97 if (element == NULL) {
98 g_set_error_literal (error,
99 FWUPD_ERROR,
100 FWUPD_ERROR_NOT_FOUND,
101 "no firmware element data to write");
102 return NULL;
103 }
104 contents = dfu_element_get_contents (element);
105 return g_bytes_ref (contents);
106 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_FORMAT_RAW_H
22 #define __DFU_FORMAT_RAW_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-firmware.h"
28
29 G_BEGIN_DECLS
30
31 DfuFirmwareFormat dfu_firmware_detect_raw (GBytes *bytes);
32 GBytes *dfu_firmware_to_raw (DfuFirmware *firmware,
33 GError **error);
34 gboolean dfu_firmware_from_raw (DfuFirmware *firmware,
35 GBytes *bytes,
36 DfuFirmwareParseFlags flags,
37 GError **error);
38
39 G_END_DECLS
40
41 #endif /* __DFU_FORMAT_RAW_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-image
23 * @short_description: Object representing a a firmware image
24 *
25 * A #DfuImage is typically made up of several #DfuElements, although
26 * typically there will only be one.
27 *
28 * See also: #DfuElement
29 */
30
31 #include "config.h"
32
33 #include <string.h>
34 #include <stdio.h>
35
36 #include "dfu-common.h"
37 #include "dfu-element.h"
38 #include "dfu-image.h"
39
40 static void dfu_image_finalize (GObject *object);
41
42 typedef struct {
43 GPtrArray *elements;
44 gchar name[255];
45 guint8 alt_setting;
46 } DfuImagePrivate;
47
48 G_DEFINE_TYPE_WITH_PRIVATE (DfuImage, dfu_image, G_TYPE_OBJECT)
49 #define GET_PRIVATE(o) (dfu_image_get_instance_private (o))
50
51 static void
52 dfu_image_class_init (DfuImageClass *klass)
53 {
54 GObjectClass *object_class = G_OBJECT_CLASS (klass);
55 object_class->finalize = dfu_image_finalize;
56 }
57
58 static void
59 dfu_image_init (DfuImage *image)
60 {
61 DfuImagePrivate *priv = GET_PRIVATE (image);
62 priv->elements = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
63 memset (priv->name, 0x00, 255);
64 }
65
66 static void
67 dfu_image_finalize (GObject *object)
68 {
69 DfuImage *image = DFU_IMAGE (object);
70 DfuImagePrivate *priv = GET_PRIVATE (image);
71
72 g_ptr_array_unref (priv->elements);
73
74 G_OBJECT_CLASS (dfu_image_parent_class)->finalize (object);
75 }
76
77 /**
78 * dfu_image_new:
79 *
80 * Creates a new DFU image object.
81 *
82 * Return value: a new #DfuImage
83 **/
84 DfuImage *
85 dfu_image_new (void)
86 {
87 DfuImage *image;
88 image = g_object_new (DFU_TYPE_IMAGE, NULL);
89 return image;
90 }
91
92 /**
93 * dfu_image_get_elements:
94 * @image: a #DfuImage
95 *
96 * Gets the element data.
97 *
98 * Return value: (transfer none) (element-type DfuElement): element data
99 **/
100 GPtrArray *
101 dfu_image_get_elements (DfuImage *image)
102 {
103 DfuImagePrivate *priv = GET_PRIVATE (image);
104 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
105 return priv->elements;
106 }
107
108 /**
109 * dfu_image_get_element:
110 * @image: a #DfuImage
111 * @idx: an array index
112 *
113 * Gets the element.
114 *
115 * Return value: (transfer none): element data, or %NULL for invalid
116 **/
117 DfuElement *
118 dfu_image_get_element (DfuImage *image, guint8 idx)
119 {
120 DfuImagePrivate *priv = GET_PRIVATE (image);
121 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
122 if (idx >= priv->elements->len)
123 return NULL;
124 return g_ptr_array_index (priv->elements, idx);
125 }
126
127 /**
128 * dfu_image_get_element_default:
129 * @image: a #DfuImage
130 *
131 * Gets the default element.
132 *
133 * Return value: (transfer none): element data, or %NULL for invalid
134 **/
135 DfuElement *
136 dfu_image_get_element_default (DfuImage *image)
137 {
138 DfuImagePrivate *priv = GET_PRIVATE (image);
139 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
140 if (priv->elements->len == 0)
141 return NULL;
142 return g_ptr_array_index (priv->elements, 0);
143 }
144
145 /**
146 * dfu_image_get_alt_setting:
147 * @image: a #DfuImage
148 *
149 * Gets the alternate setting.
150 *
151 * Return value: integer, or 0x00 for unset
152 **/
153 guint8
154 dfu_image_get_alt_setting (DfuImage *image)
155 {
156 DfuImagePrivate *priv = GET_PRIVATE (image);
157 g_return_val_if_fail (DFU_IS_IMAGE (image), 0xff);
158 return priv->alt_setting;
159 }
160
161 /**
162 * dfu_image_get_name:
163 * @image: a #DfuImage
164 *
165 * Gets the target name.
166 *
167 * Return value: a string, or %NULL for unset
168 **/
169 const gchar *
170 dfu_image_get_name (DfuImage *image)
171 {
172 DfuImagePrivate *priv = GET_PRIVATE (image);
173 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
174 return priv->name;
175 }
176
177 /**
178 * dfu_image_get_size:
179 * @image: a #DfuImage
180 *
181 * Gets the size of all the elements in the image.
182 *
183 * This only returns actual data that would be sent to the device and
184 * does not include any padding.
185 *
186 * Return value: a integer value, or 0 if there are no elements.
187 **/
188 guint32
189 dfu_image_get_size (DfuImage *image)
190 {
191 DfuImagePrivate *priv = GET_PRIVATE (image);
192 guint32 length = 0;
193 g_return_val_if_fail (DFU_IS_IMAGE (image), 0);
194 for (guint i = 0; i < priv->elements->len; i++) {
195 DfuElement *element = g_ptr_array_index (priv->elements, i);
196 length += (guint32) g_bytes_get_size (dfu_element_get_contents (element));
197 }
198 return length;
199 }
200
201 /**
202 * dfu_image_add_element:
203 * @image: a #DfuImage
204 * @element: a #DfuElement
205 *
206 * Adds an element to the image.
207 **/
208 void
209 dfu_image_add_element (DfuImage *image, DfuElement *element)
210 {
211 DfuImagePrivate *priv = GET_PRIVATE (image);
212 g_return_if_fail (DFU_IS_IMAGE (image));
213 g_return_if_fail (DFU_IS_ELEMENT (element));
214 g_ptr_array_add (priv->elements, g_object_ref (element));
215 }
216
217 /**
218 * dfu_image_set_alt_setting:
219 * @image: a #DfuImage
220 * @alt_setting: vendor ID, or 0xffff for unset
221 *
222 * Sets the vendor ID.
223 **/
224 void
225 dfu_image_set_alt_setting (DfuImage *image, guint8 alt_setting)
226 {
227 DfuImagePrivate *priv = GET_PRIVATE (image);
228 g_return_if_fail (DFU_IS_IMAGE (image));
229 priv->alt_setting = alt_setting;
230 }
231
232 /**
233 * dfu_image_set_name:
234 * @image: a #DfuImage
235 * @name: a target string, or %NULL
236 *
237 * Sets the target name.
238 **/
239 void
240 dfu_image_set_name (DfuImage *image, const gchar *name)
241 {
242 guint16 sz;
243 DfuImagePrivate *priv = GET_PRIVATE (image);
244 g_return_if_fail (DFU_IS_IMAGE (image));
245
246 /* this is a hard limit in DfuSe */
247 memset (priv->name, 0x00, 0xff);
248 if (name != NULL) {
249 sz = MIN ((guint16) strlen (name), 0xff - 1);
250 memcpy (priv->name, name, sz);
251 }
252
253 /* copy junk data in self tests for 1:1 copies */
254 if (name != NULL && G_UNLIKELY (g_getenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME") != NULL))
255 memcpy (priv->name, name, 0xff);
256 }
257
258 /**
259 * dfu_image_to_string:
260 * @image: a #DfuImage
261 *
262 * Returns a string representaiton of the object.
263 *
264 * Return value: NULL terminated string, or %NULL for invalid
265 **/
266 gchar *
267 dfu_image_to_string (DfuImage *image)
268 {
269 DfuImagePrivate *priv = GET_PRIVATE (image);
270 GString *str;
271
272 g_return_val_if_fail (DFU_IS_IMAGE (image), NULL);
273
274 str = g_string_new ("");
275 g_string_append_printf (str, "alt_setting: 0x%02x\n", priv->alt_setting);
276 if (priv->name[0] != '\0')
277 g_string_append_printf (str, "name: %s\n", priv->name);
278 g_string_append_printf (str, "elements: 0x%02x\n",
279 priv->elements->len);
280
281 /* add elements */
282 for (guint i = 0; i < priv->elements->len; i++) {
283 DfuElement *element = g_ptr_array_index (priv->elements, i);
284 g_autofree gchar *tmp = NULL;
285 tmp = dfu_element_to_string (element);
286 g_string_append_printf (str, "== ELEMENT %u ==\n", i);
287 g_string_append_printf (str, "%s\n", tmp);
288 }
289
290 g_string_truncate (str, str->len - 1);
291 return g_string_free (str, FALSE);
292 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_IMAGE_H
22 #define __DFU_IMAGE_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 #include "dfu-element.h"
28
29 G_BEGIN_DECLS
30
31 #define DFU_TYPE_IMAGE (dfu_image_get_type ())
32 G_DECLARE_DERIVABLE_TYPE (DfuImage, dfu_image, DFU, IMAGE, GObject)
33
34 struct _DfuImageClass
35 {
36 GObjectClass parent_class;
37 /*< private >*/
38 /* Padding for future expansion */
39 void (*_dfu_image_reserved1) (void);
40 void (*_dfu_image_reserved2) (void);
41 void (*_dfu_image_reserved3) (void);
42 void (*_dfu_image_reserved4) (void);
43 void (*_dfu_image_reserved5) (void);
44 void (*_dfu_image_reserved6) (void);
45 void (*_dfu_image_reserved7) (void);
46 void (*_dfu_image_reserved8) (void);
47 void (*_dfu_image_reserved9) (void);
48 };
49
50 DfuImage *dfu_image_new (void);
51
52 GPtrArray *dfu_image_get_elements (DfuImage *image);
53 DfuElement *dfu_image_get_element (DfuImage *image,
54 guint8 idx);
55 DfuElement *dfu_image_get_element_default (DfuImage *image);
56 guint8 dfu_image_get_alt_setting (DfuImage *image);
57 const gchar *dfu_image_get_name (DfuImage *image);
58 guint32 dfu_image_get_size (DfuImage *image);
59
60 void dfu_image_add_element (DfuImage *image,
61 DfuElement *element);
62
63 void dfu_image_set_alt_setting (DfuImage *image,
64 guint8 alt_setting);
65 void dfu_image_set_name (DfuImage *image,
66 const gchar *name);
67
68 gchar *dfu_image_to_string (DfuImage *image);
69
70 G_END_DECLS
71
72 #endif /* __DFU_IMAGE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-patch
23 * @short_description: Object representing a binary patch
24 *
25 * This object represents an binary patch that can be applied on a firmware
26 * image. The patch itself is made up of chunks of data that have an offset
27 * and that can replace the data to upgrade the firmware.
28 *
29 * Note: this is one way operation -- the patch can only be used to go forwards
30 * and also cannot be used to truncate the existing image.
31 *
32 * See also: #DfuImage, #DfuFirmware
33 */
34
35 #include "config.h"
36
37 #include <string.h>
38 #include <stdio.h>
39
40 #include "dfu-common.h"
41 #include "dfu-patch.h"
42
43 #include "fwupd-error.h"
44
45 static void dfu_patch_finalize (GObject *object);
46
47 typedef struct __attribute__((packed)) {
48 guint32 off;
49 guint32 sz;
50 guint32 flags;
51 } DfuPatchChunkHeader;
52
53 typedef struct __attribute__((packed)) {
54 guint8 signature[4]; /* 'DfuP' */
55 guint8 reserved[4];
56 guint8 checksum_old[20]; /* SHA1 */
57 guint8 checksum_new[20]; /* SHA1 */
58 } DfuPatchFileHeader;
59
60 typedef struct {
61 GBytes *checksum_old;
62 GBytes *checksum_new;
63 GPtrArray *chunks; /* of DfuPatchChunk */
64 } DfuPatchPrivate;
65
66 typedef struct {
67 guint32 off;
68 GBytes *blob;
69 } DfuPatchChunk;
70
71 G_DEFINE_TYPE_WITH_PRIVATE (DfuPatch, dfu_patch, G_TYPE_OBJECT)
72 #define GET_PRIVATE(o) (dfu_patch_get_instance_private (o))
73
74 static void
75 dfu_patch_class_init (DfuPatchClass *klass)
76 {
77 GObjectClass *object_class = G_OBJECT_CLASS (klass);
78 object_class->finalize = dfu_patch_finalize;
79 }
80
81 static void
82 dfu_patch_chunk_free (DfuPatchChunk *chunk)
83 {
84 g_bytes_unref (chunk->blob);
85 g_free (chunk);
86 }
87
88 static void
89 dfu_patch_init (DfuPatch *self)
90 {
91 DfuPatchPrivate *priv = GET_PRIVATE (self);
92 priv->chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_patch_chunk_free);
93 }
94
95 static void
96 dfu_patch_finalize (GObject *object)
97 {
98 DfuPatch *self = DFU_PATCH (object);
99 DfuPatchPrivate *priv = GET_PRIVATE (self);
100
101 if (priv->checksum_old != NULL)
102 g_bytes_unref (priv->checksum_old);
103 if (priv->checksum_new != NULL)
104 g_bytes_unref (priv->checksum_new);
105 g_ptr_array_unref (priv->chunks);
106
107 G_OBJECT_CLASS (dfu_patch_parent_class)->finalize (object);
108 }
109
110 /**
111 * dfu_patch_export:
112 * @self: a #DfuPatch
113 * @error: a #GError, or %NULL
114 *
115 * Converts the patch to a binary blob that can be stored as a file.
116 *
117 * Return value: (transfer full): blob
118 **/
119 GBytes *
120 dfu_patch_export (DfuPatch *self, GError **error)
121 {
122 DfuPatchPrivate *priv = GET_PRIVATE (self);
123 gsize addr;
124 gsize sz;
125 guint8 *data;
126
127 g_return_val_if_fail (DFU_IS_PATCH (self), NULL);
128
129 /* check we have something to write */
130 if (priv->chunks->len == 0) {
131 g_set_error_literal (error,
132 FWUPD_ERROR,
133 FWUPD_ERROR_INVALID_FILE,
134 "no chunks to process");
135 return NULL;
136 }
137
138 /* calculate the size of the new blob */
139 sz = sizeof(DfuPatchFileHeader);
140 for (guint i = 0; i < priv->chunks->len; i++) {
141 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
142 sz += sizeof(DfuPatchChunkHeader) + g_bytes_get_size (chunk->blob);
143 }
144 g_debug ("blob size is %" G_GSIZE_FORMAT, sz);
145
146 /* actually allocate and fill in the blob */
147 data = g_malloc0 (sz);
148 memcpy (data, "DfuP", 4);
149
150 /* add checksums */
151 if (priv->checksum_old != NULL) {
152 gsize csum_sz = 0;
153 const guint8 *csum_data = g_bytes_get_data (priv->checksum_old, &csum_sz);
154 memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old),
155 csum_data, csum_sz);
156 }
157 if (priv->checksum_new != NULL) {
158 gsize csum_sz = 0;
159 const guint8 *csum_data = g_bytes_get_data (priv->checksum_new, &csum_sz);
160 memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new),
161 csum_data, csum_sz);
162 }
163
164 addr = sizeof(DfuPatchFileHeader);
165 for (guint i = 0; i < priv->chunks->len; i++) {
166 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
167 DfuPatchChunkHeader chunkhdr;
168 gsize sz_tmp = 0;
169 const guint8 *data_new = g_bytes_get_data (chunk->blob, &sz_tmp);
170
171 /* build chunk header and append data */
172 chunkhdr.off = GUINT32_TO_LE (chunk->off);
173 chunkhdr.sz = GUINT32_TO_LE (sz_tmp);
174 chunkhdr.flags = 0;
175 memcpy (data + addr, &chunkhdr, sizeof(DfuPatchChunkHeader));
176 memcpy (data + addr + sizeof(DfuPatchChunkHeader), data_new, sz_tmp);
177
178 /* move up after the copied data */
179 addr += sizeof(DfuPatchChunkHeader) + sz_tmp;
180 }
181 return g_bytes_new_take (data, sz);
182
183 }
184
185 /**
186 * dfu_patch_import:
187 * @self: a #DfuPatch
188 * @blob: patch data
189 * @error: a #GError, or %NULL
190 *
191 * Creates a patch from a serialized patch, possibly from a file.
192 *
193 * Return value: %TRUE on success
194 **/
195 gboolean
196 dfu_patch_import (DfuPatch *self, GBytes *blob, GError **error)
197 {
198 DfuPatchPrivate *priv = GET_PRIVATE (self);
199 const guint8 *data;
200 gsize sz = 0;
201 guint32 off;
202
203 g_return_val_if_fail (DFU_IS_PATCH (self), FALSE);
204 g_return_val_if_fail (blob != NULL, FALSE);
205
206 /* cannot reuse object */
207 if (priv->chunks->len > 0) {
208 g_set_error_literal (error,
209 FWUPD_ERROR,
210 FWUPD_ERROR_INVALID_FILE,
211 "patch has already been loaded");
212 return FALSE;
213 }
214
215 /* check minimum size */
216 data = g_bytes_get_data (blob, &sz);
217 if (sz < sizeof(DfuPatchFileHeader) + sizeof(DfuPatchChunkHeader) + 1) {
218 g_set_error_literal (error,
219 FWUPD_ERROR,
220 FWUPD_ERROR_INVALID_FILE,
221 "file is too small");
222 return FALSE;
223 }
224
225 /* check header */
226 if (memcmp (data, "DfuP", 4) != 0) {
227 g_set_error_literal (error,
228 FWUPD_ERROR,
229 FWUPD_ERROR_INVALID_FILE,
230 "header signature is not correct");
231 return FALSE;
232 }
233
234 /* get checksums */
235 priv->checksum_old = g_bytes_new (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old), 20);
236 priv->checksum_new = g_bytes_new (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new), 20);
237
238 /* look for each chunk */
239 off = sizeof(DfuPatchFileHeader);
240 while (off < (guint32) sz) {
241 DfuPatchChunkHeader *chunkhdr = (DfuPatchChunkHeader *) (data + off);
242 DfuPatchChunk *chunk;
243 guint32 chunk_sz = GUINT32_FROM_LE (chunkhdr->sz);
244 guint32 chunk_off = GUINT32_FROM_LE (chunkhdr->off);
245
246 /* check chunk size, assuming it can overflow */
247 if (chunk_sz > sz || off + chunk_sz > sz) {
248 g_set_error (error,
249 FWUPD_ERROR,
250 FWUPD_ERROR_INVALID_FILE,
251 "chunk offset 0x%04x outsize file size 0x%04x",
252 (guint) (off + chunk_sz), (guint) sz);
253 return FALSE;
254 }
255 chunk = g_new0 (DfuPatchChunk, 1);
256 chunk->off = chunk_off;
257 chunk->blob = g_bytes_new_from_bytes (blob, off + sizeof(DfuPatchChunkHeader), chunk_sz);
258 g_ptr_array_add (priv->chunks, chunk);
259 off += sizeof(DfuPatchChunkHeader) + chunk_sz;
260 }
261
262 /* check we finished properly */
263 if (off != sz) {
264 g_set_error_literal (error,
265 FWUPD_ERROR,
266 FWUPD_ERROR_INVALID_FILE,
267 "blob chunk sizes did not sum to total");
268 return FALSE;
269 }
270
271 /* success */
272 return TRUE;
273 }
274
275
276 static GBytes *
277 dfu_patch_calculate_checksum (GBytes *blob)
278 {
279 const guchar *data;
280 gsize digest_len = 20;
281 gsize sz = 0;
282 guint8 *buf = g_malloc0 (digest_len);
283 g_autoptr(GChecksum) csum = NULL;
284 csum = g_checksum_new (G_CHECKSUM_SHA1);
285 data = g_bytes_get_data (blob, &sz);
286 g_checksum_update (csum, data, (gssize) sz);
287 g_checksum_get_digest (csum, buf, &digest_len);
288 return g_bytes_new_take (buf, digest_len);
289 }
290
291 typedef struct {
292 guint32 diff_start;
293 guint32 diff_end;
294 GBytes *blob; /* no ref */
295 } DfuPatchCreateHelper;
296
297 static void
298 dfu_patch_flush (DfuPatch *self, DfuPatchCreateHelper *helper)
299 {
300 DfuPatchChunk *chunk;
301 DfuPatchPrivate *priv = GET_PRIVATE (self);
302
303 if (helper->diff_end == 0xffff)
304 return;
305 g_debug ("add chunk @0x%04x (len %" G_GUINT32_FORMAT ")",
306 (guint) helper->diff_start, helper->diff_end - helper->diff_start + 1);
307
308 chunk = g_new0 (DfuPatchChunk, 1);
309 chunk->off = helper->diff_start;
310 chunk->blob = g_bytes_new_from_bytes (helper->blob, chunk->off,
311 helper->diff_end - helper->diff_start + 1);
312 g_ptr_array_add (priv->chunks, chunk);
313 helper->diff_end = 0xffff;
314 }
315
316 /**
317 * dfu_patch_create:
318 * @self: a #DfuPatch
319 * @blob1: a #GBytes, typically the old firmware image
320 * @blob2: a #GBytes, typically the new firmware image
321 * @error: a #GError, or %NULL
322 *
323 * Creates a patch from two blobs of memory.
324 *
325 * The blobs should ideally be the same size. If @blob2 is has grown in size
326 * the binary diff will still work but the algorithm will probably not perform
327 * well unless the majority of data has just been appended.
328 *
329 * As an additional constrainst, @blob2 cannot be smaller than @blob1, i.e.
330 * the firmware cannot be truncated by this format.
331 *
332 * Return value: %TRUE on success
333 **/
334 gboolean
335 dfu_patch_create (DfuPatch *self, GBytes *blob1, GBytes *blob2, GError **error)
336 {
337 DfuPatchPrivate *priv = GET_PRIVATE (self);
338 DfuPatchCreateHelper helper;
339 const guint8 *data1;
340 const guint8 *data2;
341 gsize sz1 = 0;
342 gsize sz2 = 0;
343 guint32 same_sz = 0;
344
345 g_return_val_if_fail (DFU_IS_PATCH (self), FALSE);
346 g_return_val_if_fail (blob1 != NULL, FALSE);
347 g_return_val_if_fail (blob2 != NULL, FALSE);
348
349 /* are the blobs the same */
350 if (g_bytes_equal (blob1, blob2)) {
351 g_set_error_literal (error,
352 FWUPD_ERROR,
353 FWUPD_ERROR_INVALID_FILE,
354 "old and new binaries are the same");
355 return FALSE;
356 }
357
358 /* cannot reuse object */
359 if (priv->chunks->len > 0) {
360 g_set_error_literal (error,
361 FWUPD_ERROR,
362 FWUPD_ERROR_INVALID_FILE,
363 "patch has already been loaded");
364 return FALSE;
365 }
366
367 /* get the hash of the old firmware file */
368 priv->checksum_old = dfu_patch_calculate_checksum (blob1);
369 priv->checksum_new = dfu_patch_calculate_checksum (blob2);
370
371 /* get the raw data, and ensure they are the same size */
372 data1 = g_bytes_get_data (blob1, &sz1);
373 data2 = g_bytes_get_data (blob2, &sz2);
374 if (sz1 > sz2) {
375 g_set_error (error,
376 FWUPD_ERROR,
377 FWUPD_ERROR_NOT_SUPPORTED,
378 "firmware binary cannot go down, got "
379 "%" G_GSIZE_FORMAT " and %" G_GSIZE_FORMAT,
380 sz1, sz2);
381 return FALSE;
382 }
383 if (sz1 == sz2) {
384 g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz1);
385 } else {
386 g_debug ("binary growing from: %" G_GSIZE_FORMAT
387 " to %" G_GSIZE_FORMAT, sz1, sz2);
388 }
389
390 /* start the dumb comparison algorithm */
391 helper.diff_start = 0;
392 helper.diff_end = 0xffff;
393 helper.blob = blob2;
394 for (gsize i = 0; i < sz1 || i < sz2; i++) {
395 if (i < sz1 && i < sz2 &&
396 data1[i] == data2[i]) {
397 /* if we got enough the same, dump what is pending */
398 if (++same_sz > sizeof(DfuPatchChunkHeader) * 2)
399 dfu_patch_flush (self, &helper);
400 continue;
401 }
402 if (helper.diff_end == 0xffff)
403 helper.diff_start = (guint32) i;
404 helper.diff_end = (guint32) i;
405 same_sz = 0;
406 }
407 dfu_patch_flush (self, &helper);
408 return TRUE;
409 }
410
411 static gchar *
412 _g_bytes_to_string (GBytes *blob)
413 {
414 gsize sz = 0;
415 const guint8 *data = g_bytes_get_data (blob, &sz);
416 GString *str = g_string_new (NULL);
417 for (gsize i = 0; i < sz; i++)
418 g_string_append_printf (str, "%02x", (guint) data[i]);
419 return g_string_free (str, FALSE);
420 }
421
422 /**
423 * dfu_patch_get_checksum_old:
424 * @self: a #DfuPatch
425 *
426 * Get the checksum for the old firmware image.
427 *
428 * Return value: A #GBytes, or %NULL if nothing has been loaded.
429 **/
430 GBytes *
431 dfu_patch_get_checksum_old (DfuPatch *self)
432 {
433 DfuPatchPrivate *priv = GET_PRIVATE (self);
434 return priv->checksum_old;
435 }
436
437 /**
438 * dfu_patch_get_checksum_new:
439 * @self: a #DfuPatch
440 *
441 * Get the checksum for the new firmware image.
442 *
443 * Return value: A #GBytes, or %NULL if nothing has been loaded.
444 **/
445 GBytes *
446 dfu_patch_get_checksum_new (DfuPatch *self)
447 {
448 DfuPatchPrivate *priv = GET_PRIVATE (self);
449 return priv->checksum_new;
450 }
451
452 /**
453 * dfu_patch_apply:
454 * @self: a #DfuPatch
455 * @blob: a #GBytes, typically the old firmware image
456 * @flags: a #DfuPatchApplyFlags, e.g. %DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM
457 * @error: a #GError, or %NULL
458 *
459 * Apply the currently loaded patch to a new firmware image.
460 *
461 * Return value: A #GBytes, typically saved as the new firmware file
462 **/
463 GBytes *
464 dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError **error)
465 {
466 DfuPatchPrivate *priv = GET_PRIVATE (self);
467 const guint8 *data_old;
468 gsize sz;
469 gsize sz_max = 0;
470 g_autofree guint8 *data_new = NULL;
471 g_autoptr(GBytes) blob_checksum_new = NULL;
472 g_autoptr(GBytes) blob_checksum = NULL;
473 g_autoptr(GBytes) blob_new = NULL;
474
475 /* not loaded yet */
476 if (priv->chunks->len == 0) {
477 g_set_error_literal (error,
478 FWUPD_ERROR,
479 FWUPD_ERROR_INVALID_FILE,
480 "no patches loaded");
481 return NULL;
482 }
483
484 /* get the hash of the old firmware file */
485 blob_checksum = dfu_patch_calculate_checksum (blob);
486 if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 &&
487 !g_bytes_equal (blob_checksum, priv->checksum_old)) {
488 g_autofree gchar *actual = _g_bytes_to_string (blob_checksum);
489 g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_old);
490 g_set_error (error,
491 FWUPD_ERROR,
492 FWUPD_ERROR_INVALID_FILE,
493 "checksum for source did not match, expected %s, got %s",
494 expect, actual);
495 return NULL;
496 }
497
498 /* get the size of the new image size */
499 for (guint i = 0; i < priv->chunks->len; i++) {
500 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
501 gsize chunk_sz = g_bytes_get_size (chunk->blob);
502 if (chunk->off + chunk_sz > sz_max)
503 sz_max = chunk->off + chunk_sz;
504 }
505
506 /* first, copy the data buffer */
507 data_old = g_bytes_get_data (blob, &sz);
508 if (sz_max < sz) {
509 g_set_error_literal (error,
510 FWUPD_ERROR,
511 FWUPD_ERROR_INVALID_FILE,
512 "binary patch cannot truncate binary");
513 return NULL;
514 }
515 if (sz == sz_max) {
516 g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz);
517 } else {
518 g_debug ("binary growing from: %" G_GSIZE_FORMAT
519 " to %" G_GSIZE_FORMAT, sz, sz_max);
520 }
521
522 data_new = g_malloc0 (sz_max);
523 memcpy (data_new, data_old, sz_max);
524 for (guint i = 0; i < priv->chunks->len; i++) {
525 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
526 const guint8 *chunk_data;
527 gsize chunk_sz;
528
529 /* bigger than the total size */
530 chunk_data = g_bytes_get_data (chunk->blob, &chunk_sz);
531 if (chunk->off + chunk_sz > sz_max) {
532 g_set_error (error,
533 FWUPD_ERROR,
534 FWUPD_ERROR_INVALID_FILE,
535 "cannot apply chunk as larger than max size");
536 return NULL;
537 }
538
539 /* apply one chunk */
540 g_debug ("applying chunk %u/%u @0x%04x (length %" G_GSIZE_FORMAT ")",
541 i + 1, priv->chunks->len, chunk->off, chunk_sz);
542 memcpy (data_new + chunk->off, chunk_data, chunk_sz);
543 }
544
545 /* check we got the desired hash */
546 blob_new = g_bytes_new (data_new, sz_max);
547 blob_checksum_new = dfu_patch_calculate_checksum (blob_new);
548 if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 &&
549 !g_bytes_equal (blob_checksum_new, priv->checksum_new)) {
550 g_autofree gchar *actual = _g_bytes_to_string (blob_checksum_new);
551 g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_new);
552 g_set_error (error,
553 FWUPD_ERROR,
554 FWUPD_ERROR_INVALID_FILE,
555 "checksum for result did not match, expected %s, got %s",
556 expect, actual);
557 return NULL;
558 }
559
560 /* success */
561 return g_steal_pointer (&blob_new);
562 }
563
564 /**
565 * dfu_patch_to_string:
566 * @self: a #DfuPatch
567 *
568 * Returns a string representaiton of the object.
569 *
570 * Return value: NULL terminated string, or %NULL for invalid
571 **/
572 gchar *
573 dfu_patch_to_string (DfuPatch *self)
574 {
575 DfuPatchPrivate *priv = GET_PRIVATE (self);
576 GString *str = g_string_new (NULL);
577 g_autofree gchar *checksum_old = NULL;
578 g_autofree gchar *checksum_new = NULL;
579
580 g_return_val_if_fail (DFU_IS_PATCH (self), NULL);
581
582 /* add checksums */
583 checksum_old = _g_bytes_to_string (priv->checksum_old);
584 g_string_append_printf (str, "checksum-old: %s\n", checksum_old);
585 checksum_new = _g_bytes_to_string (priv->checksum_new);
586 g_string_append_printf (str, "checksum-new: %s\n", checksum_new);
587
588 /* add chunks */
589 for (guint i = 0; i < priv->chunks->len; i++) {
590 DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i);
591 g_string_append_printf (str, "chunk #%02u 0x%04x, length %" G_GSIZE_FORMAT "\n",
592 i, chunk->off, g_bytes_get_size (chunk->blob));
593 }
594 g_string_truncate (str, str->len - 1);
595 return g_string_free (str, FALSE);
596 }
597
598 /**
599 * dfu_patch_new:
600 *
601 * Creates a new DFU patch object.
602 *
603 * Return value: a new #DfuPatch
604 **/
605 DfuPatch *
606 dfu_patch_new (void)
607 {
608 DfuPatch *self;
609 self = g_object_new (DFU_TYPE_PATCH, NULL);
610 return self;
611 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_PATCH_H
22 #define __DFU_PATCH_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 #define DFU_TYPE_PATCH (dfu_patch_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (DfuPatch, dfu_patch, DFU, PATCH, GObject)
31
32 struct _DfuPatchClass
33 {
34 GObjectClass parent_class;
35 /*< private >*/
36 void (*_dfu_patch_reserved1) (void);
37 void (*_dfu_patch_reserved2) (void);
38 void (*_dfu_patch_reserved3) (void);
39 void (*_dfu_patch_reserved4) (void);
40 void (*_dfu_patch_reserved5) (void);
41 void (*_dfu_patch_reserved6) (void);
42 void (*_dfu_patch_reserved7) (void);
43 void (*_dfu_patch_reserved8) (void);
44 void (*_dfu_patch_reserved9) (void);
45 };
46
47 /**
48 * DfuPatchApplyFlags:
49 * @DFU_PATCH_APPLY_FLAG_NONE: No flags set
50 * @DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM: Do not check the checksum
51 *
52 * The optional flags used for applying a patch.
53 **/
54 typedef enum {
55 DFU_PATCH_APPLY_FLAG_NONE = 0,
56 DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM = (1 << 0),
57 /*< private >*/
58 DFU_PATCH_APPLY_FLAG_LAST
59 } DfuPatchApplyFlags;
60
61 DfuPatch *dfu_patch_new (void);
62
63 gchar *dfu_patch_to_string (DfuPatch *self);
64 GBytes *dfu_patch_export (DfuPatch *self,
65 GError **error);
66 gboolean dfu_patch_import (DfuPatch *self,
67 GBytes *blob,
68 GError **error);
69 gboolean dfu_patch_create (DfuPatch *self,
70 GBytes *blob1,
71 GBytes *blob2,
72 GError **error);
73 GBytes *dfu_patch_apply (DfuPatch *self,
74 GBytes *blob,
75 DfuPatchApplyFlags flags,
76 GError **error);
77 GBytes *dfu_patch_get_checksum_old (DfuPatch *self);
78 GBytes *dfu_patch_get_checksum_new (DfuPatch *self);
79
80 G_END_DECLS
81
82 #endif /* __DFU_PATCH_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_SECTOR_PRIVATE_H
22 #define __DFU_SECTOR_PRIVATE_H
23
24 #include "dfu-sector.h"
25
26 G_BEGIN_DECLS
27
28 DfuSector *dfu_sector_new (guint32 address,
29 guint32 size,
30 guint32 size_left,
31 guint16 zone,
32 guint16 number,
33 DfuSectorCap cap);
34
35 G_END_DECLS
36
37 #endif /* __DFU_SECTOR_PRIVATE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-sector
23 * @short_description: Object representing a sector on a chip
24 *
25 * This object represents an sector of memory at a specific address on the
26 * device itself.
27 *
28 * This allows relocatable data segments to be stored in different
29 * locations on the device itself.
30 *
31 * You can think of these objects as flash segments on devices, where a
32 * complete block can be erased and then written to.
33 *
34 * See also: #DfuElement
35 */
36
37 #include "config.h"
38
39 #include <string.h>
40 #include <stdio.h>
41
42 #include "dfu-common.h"
43 #include "dfu-sector-private.h"
44
45 typedef struct {
46 guint32 address;
47 guint32 size;
48 guint32 size_left;
49 guint16 zone;
50 guint16 number;
51 DfuSectorCap cap;
52 } DfuSectorPrivate;
53
54 G_DEFINE_TYPE_WITH_PRIVATE (DfuSector, dfu_sector, G_TYPE_OBJECT)
55 #define GET_PRIVATE(o) (dfu_sector_get_instance_private (o))
56
57 static void
58 dfu_sector_class_init (DfuSectorClass *klass)
59 {
60 }
61
62 static void
63 dfu_sector_init (DfuSector *sector)
64 {
65 }
66
67 /**
68 * dfu_sector_new: (skip)
69 * address: the address for the sector
70 * size: the size of this sector
71 * size_left: the size of the rest of the sector
72 * zone: the zone of memory the setor belongs
73 * number: the sector number in the zone
74 * cap: the #DfuSectorCap
75 *
76 * Creates a new DFU sector object.
77 *
78 * Return value: a new #DfuSector
79 **/
80 DfuSector *
81 dfu_sector_new (guint32 address, guint32 size, guint32 size_left,
82 guint16 zone, guint16 number, DfuSectorCap cap)
83 {
84 DfuSectorPrivate *priv;
85 DfuSector *sector;
86 sector = g_object_new (DFU_TYPE_SECTOR, NULL);
87 priv = GET_PRIVATE (sector);
88 priv->address = address;
89 priv->size = size;
90 priv->size_left = size_left;
91 priv->zone = zone;
92 priv->number = number;
93 priv->cap = cap;
94 return sector;
95 }
96
97 /**
98 * dfu_sector_get_address:
99 * @sector: a #DfuSector
100 *
101 * Gets the alternate setting.
102 *
103 * Return value: integer, or 0x00 for unset
104 **/
105 guint32
106 dfu_sector_get_address (DfuSector *sector)
107 {
108 DfuSectorPrivate *priv = GET_PRIVATE (sector);
109 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
110 return priv->address;
111 }
112
113 /**
114 * dfu_sector_get_size:
115 * @sector: a #DfuSector
116 *
117 * Gets the sector size.
118 *
119 * Return value: integer, or 0x00 for unset
120 **/
121 guint32
122 dfu_sector_get_size (DfuSector *sector)
123 {
124 DfuSectorPrivate *priv = GET_PRIVATE (sector);
125 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
126 return priv->size;
127 }
128
129 /**
130 * dfu_sector_get_size_left:
131 * @sector: a #DfuSector
132 *
133 * Gets the size of the rest of the sector.
134 *
135 * Return value: integer, or 0x00 for unset
136 **/
137 guint32
138 dfu_sector_get_size_left (DfuSector *sector)
139 {
140 DfuSectorPrivate *priv = GET_PRIVATE (sector);
141 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
142 return priv->size_left;
143 }
144
145 /**
146 * dfu_sector_get_zone:
147 * @sector: a #DfuSector
148 *
149 * Gets the sector zone number.
150 *
151 * Return value: integer, or 0x00 for unset
152 **/
153 guint16
154 dfu_sector_get_zone (DfuSector *sector)
155 {
156 DfuSectorPrivate *priv = GET_PRIVATE (sector);
157 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
158 return priv->zone;
159 }
160
161 /**
162 * dfu_sector_get_number:
163 * @sector: a #DfuSector
164 *
165 * Gets the sector index number.
166 *
167 * Return value: integer, or 0x00 for unset
168 **/
169 guint16
170 dfu_sector_get_number (DfuSector *sector)
171 {
172 DfuSectorPrivate *priv = GET_PRIVATE (sector);
173 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
174 return priv->number;
175 }
176
177 /**
178 * dfu_sector_get_id:
179 * @sector: a #DfuSector
180 *
181 * Gets the sector ID which is a combination of the zone and sector number.
182 * You can use this number to check if the segment is the 'same' as the last
183 * written or read sector.
184 *
185 * Return value: integer ID, or 0x00 for unset
186 **/
187 guint32
188 dfu_sector_get_id (DfuSector *sector)
189 {
190 DfuSectorPrivate *priv = GET_PRIVATE (sector);
191 g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00);
192 return (((guint32) priv->zone) << 16) | priv->number;
193 }
194
195 /**
196 * dfu_sector_has_cap:
197 * @sector: a #DfuSector
198 * @cap: a #DfuSectorCap, e.g. %DFU_SECTOR_CAP_ERASEABLE
199 *
200 * Finds out if the sector has the required capability.
201 *
202 * Return value: %TRUE if the sector has the capabilily
203 **/
204 gboolean
205 dfu_sector_has_cap (DfuSector *sector, DfuSectorCap cap)
206 {
207 DfuSectorPrivate *priv = GET_PRIVATE (sector);
208 g_return_val_if_fail (DFU_IS_SECTOR (sector), FALSE);
209 return (priv->cap & cap) > 0;
210 }
211
212 static gchar *
213 dfu_sector_cap_to_string (DfuSectorCap cap)
214 {
215 GString *str = g_string_new (NULL);
216 if (cap & DFU_SECTOR_CAP_READABLE)
217 g_string_append (str, "R");
218 if (cap & DFU_SECTOR_CAP_ERASEABLE)
219 g_string_append (str, "E");
220 if (cap & DFU_SECTOR_CAP_WRITEABLE)
221 g_string_append (str, "W");
222 return g_string_free (str, FALSE);
223 }
224
225 /**
226 * dfu_sector_to_string:
227 * @sector: a #DfuSector
228 *
229 * Returns a string representaiton of the object.
230 *
231 * Return value: NULL terminated string, or %NULL for invalid
232 **/
233 gchar *
234 dfu_sector_to_string (DfuSector *sector)
235 {
236 DfuSectorPrivate *priv = GET_PRIVATE (sector);
237 GString *str;
238 g_autofree gchar *caps_str = NULL;
239
240 g_return_val_if_fail (DFU_IS_SECTOR (sector), NULL);
241
242 str = g_string_new ("");
243 caps_str = dfu_sector_cap_to_string (priv->cap);
244 g_string_append_printf (str,
245 "Zone:%i, Sec#:%i, Addr:0x%08x, "
246 "Size:0x%04x, Caps:0x%01x [%s]",
247 priv->zone, priv->number, priv->address,
248 priv->size, priv->cap, caps_str);
249 return g_string_free (str, FALSE);
250 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_SECTOR_H
22 #define __DFU_SECTOR_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26
27 G_BEGIN_DECLS
28
29 #define DFU_TYPE_SECTOR (dfu_sector_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (DfuSector, dfu_sector, DFU, SECTOR, GObject)
31
32 struct _DfuSectorClass
33 {
34 GObjectClass parent_class;
35 /*< private >*/
36 /* Padding for future expansion */
37 void (*_dfu_sector_reserved1) (void);
38 void (*_dfu_sector_reserved2) (void);
39 void (*_dfu_sector_reserved3) (void);
40 void (*_dfu_sector_reserved4) (void);
41 void (*_dfu_sector_reserved5) (void);
42 void (*_dfu_sector_reserved6) (void);
43 void (*_dfu_sector_reserved7) (void);
44 void (*_dfu_sector_reserved8) (void);
45 void (*_dfu_sector_reserved9) (void);
46 };
47
48 /**
49 * DfuSectorCap:
50 * @DFU_SECTOR_CAP_NONE: No operations possible
51 * @DFU_SECTOR_CAP_READABLE: Sector can be read
52 * @DFU_SECTOR_CAP_WRITEABLE: Sector can be written
53 * @DFU_SECTOR_CAP_ERASEABLE: Sector can be erased
54 *
55 * The flags indicating what the sector can do.
56 **/
57 typedef enum {
58 DFU_SECTOR_CAP_NONE = 0,
59 DFU_SECTOR_CAP_READABLE = 1 << 0,
60 DFU_SECTOR_CAP_WRITEABLE = 1 << 1,
61 DFU_SECTOR_CAP_ERASEABLE = 1 << 2,
62 /*< private >*/
63 DFU_SECTOR_CAP_LAST
64 } DfuSectorCap;
65
66 guint32 dfu_sector_get_id (DfuSector *sector);
67 guint32 dfu_sector_get_address (DfuSector *sector);
68 guint32 dfu_sector_get_size (DfuSector *sector);
69 guint32 dfu_sector_get_size_left (DfuSector *sector);
70 guint16 dfu_sector_get_zone (DfuSector *sector);
71 guint16 dfu_sector_get_number (DfuSector *sector);
72 gboolean dfu_sector_has_cap (DfuSector *sector,
73 DfuSectorCap cap);
74 gchar *dfu_sector_to_string (DfuSector *sector);
75
76 G_END_DECLS
77
78 #endif /* __DFU_SECTOR_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "config.h"
22
23 #include <glib-object.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <fnmatch.h>
27
28 #include "dfu-cipher-xtea.h"
29 #include "dfu-common.h"
30 #include "dfu-context.h"
31 #include "dfu-device.h"
32 #include "dfu-firmware.h"
33 #include "dfu-patch.h"
34 #include "dfu-sector-private.h"
35 #include "dfu-target-private.h"
36
37 #include "fwupd-error.h"
38
39 static gchar *
40 dfu_test_get_filename (const gchar *filename)
41 {
42 gchar *tmp;
43 char full_tmp[PATH_MAX];
44 g_autofree gchar *path = NULL;
45 path = g_build_filename (TESTDATADIR, filename, NULL);
46 tmp = realpath (path, full_tmp);
47 if (tmp == NULL)
48 return NULL;
49 return g_strdup (full_tmp);
50 }
51
52 static gboolean
53 dfu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error)
54 {
55 g_autofree gchar *output = NULL;
56
57 /* exactly the same */
58 if (g_strcmp0 (txt1, txt2) == 0)
59 return TRUE;
60
61 /* matches a pattern */
62 if (fnmatch (txt2, txt1, FNM_NOESCAPE) == 0)
63 return TRUE;
64
65 /* save temp files and diff them */
66 if (!g_file_set_contents ("/tmp/a", txt1, -1, error))
67 return FALSE;
68 if (!g_file_set_contents ("/tmp/b", txt2, -1, error))
69 return FALSE;
70 if (!g_spawn_command_line_sync ("diff -urNp /tmp/b /tmp/a",
71 &output, NULL, NULL, error))
72 return FALSE;
73
74 /* just output the diff */
75 g_set_error_literal (error, 1, 0, output);
76 return FALSE;
77 }
78
79 static gchar *
80 _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2)
81 {
82 const guint8 *data1;
83 const guint8 *data2;
84 gsize length1;
85 gsize length2;
86
87 data1 = g_bytes_get_data (bytes1, &length1);
88 data2 = g_bytes_get_data (bytes2, &length2);
89
90 /* not the same length */
91 if (length1 != length2) {
92 return g_strdup_printf ("got %" G_GSIZE_FORMAT " bytes, "
93 "expected %" G_GSIZE_FORMAT,
94 length1, length2);
95 }
96
97 /* return 00 01 02 03 */
98 for (guint i = 0; i < length1; i++) {
99 if (data1[i] != data2[i]) {
100 return g_strdup_printf ("got 0x%02x, expected 0x%02x @ 0x%04x",
101 data1[i], data2[i], i);
102 }
103 }
104 return NULL;
105 }
106
107 static void
108 dfu_cipher_xtea_func (void)
109 {
110 gboolean ret;
111 guint8 buf[] = { 'H', 'i', 'y', 'a', 'D', 'a', 'v', 'e' };
112 g_autoptr(GError) error = NULL;
113
114 ret = dfu_cipher_encrypt_xtea ("test", buf, sizeof(buf), &error);
115 g_assert_no_error (error);
116 g_assert (ret);
117
118 g_assert_cmpint (buf[0], ==, 128);
119 g_assert_cmpint (buf[1], ==, 220);
120 g_assert_cmpint (buf[2], ==, 23);
121 g_assert_cmpint (buf[3], ==, 55);
122 g_assert_cmpint (buf[4], ==, 201);
123 g_assert_cmpint (buf[5], ==, 207);
124 g_assert_cmpint (buf[6], ==, 182);
125 g_assert_cmpint (buf[7], ==, 177);
126
127 ret = dfu_cipher_decrypt_xtea ("test", buf, sizeof(buf), &error);
128 g_assert_no_error (error);
129 g_assert (ret);
130
131 g_assert_cmpint (buf[0], ==, 'H');
132 g_assert_cmpint (buf[1], ==, 'i');
133 g_assert_cmpint (buf[2], ==, 'y');
134 g_assert_cmpint (buf[3], ==, 'a');
135 g_assert_cmpint (buf[4], ==, 'D');
136 g_assert_cmpint (buf[5], ==, 'a');
137 g_assert_cmpint (buf[6], ==, 'v');
138 g_assert_cmpint (buf[7], ==, 'e');
139 }
140
141 static void
142 dfu_firmware_xdfu_func (void)
143 {
144 gboolean ret;
145 g_autofree gchar *fn = NULL;
146 g_autoptr(DfuFirmware) firmware = NULL;
147 g_autoptr(GError) error = NULL;
148 g_autoptr(GFile) file = NULL;
149
150 fn = dfu_test_get_filename ("example.xdfu");
151 g_assert (fn != NULL);
152 firmware = dfu_firmware_new ();
153 file = g_file_new_for_path (fn);
154 ret = dfu_firmware_parse_file (firmware, file,
155 DFU_FIRMWARE_PARSE_FLAG_NONE,
156 NULL, &error);
157 g_assert_no_error (error);
158 g_assert (ret);
159 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_XTEA);
160 }
161
162 static void
163 dfu_enums_func (void)
164 {
165 for (guint i = 0; i < DFU_STATE_LAST; i++)
166 g_assert_cmpstr (dfu_state_to_string (i), !=, NULL);
167 for (guint i = 0; i < DFU_STATUS_LAST; i++)
168 g_assert_cmpstr (dfu_status_to_string (i), !=, NULL);
169 }
170
171 static GBytes *
172 dfu_self_test_get_bytes_for_file (GFile *file, GError **error)
173 {
174 gchar *contents = NULL;
175 gsize length = 0;
176 if (!g_file_load_contents (file, NULL, &contents, &length, NULL, error))
177 return NULL;
178 return g_bytes_new_take (contents, length);
179 }
180
181 static void
182 dfu_firmware_raw_func (void)
183 {
184 DfuElement *element;
185 DfuImage *image_tmp;
186 GBytes *no_suffix_contents;
187 gchar buf[256];
188 gboolean ret;
189 g_autoptr(DfuFirmware) firmware = NULL;
190 g_autoptr(GBytes) fw = NULL;
191 g_autoptr(GBytes) roundtrip = NULL;
192 g_autoptr(GError) error = NULL;
193
194 /* set up some dummy data */
195 for (guint i = 0; i < 256; i++)
196 buf[i] = (gchar) i;
197 fw = g_bytes_new_static (buf, 256);
198
199 /* load a non DFU firmware */
200 firmware = dfu_firmware_new ();
201 ret = dfu_firmware_parse_data (firmware, fw, DFU_FIRMWARE_PARSE_FLAG_NONE, &error);
202 g_assert_no_error (error);
203 g_assert (ret);
204 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0xffff);
205 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xffff);
206 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff);
207 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_RAW);
208 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
209 image_tmp = dfu_firmware_get_image (firmware, 0xfe);
210 g_assert (image_tmp == NULL);
211 image_tmp = dfu_firmware_get_image (firmware, 0);
212 g_assert (image_tmp != NULL);
213 g_assert_cmpint (dfu_image_get_size (image_tmp), ==, 256);
214 element = dfu_image_get_element (image_tmp, 0);
215 g_assert (element != NULL);
216 no_suffix_contents = dfu_element_get_contents (element);
217 g_assert (no_suffix_contents != NULL);
218 g_assert_cmpint (g_bytes_compare (no_suffix_contents, fw), ==, 0);
219
220 /* can we roundtrip without adding data */
221 roundtrip = dfu_firmware_write_data (firmware, &error);
222 g_assert_no_error (error);
223 g_assert (roundtrip != NULL);
224 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, fw), ==, NULL);
225 }
226
227 static void
228 dfu_firmware_dfu_func (void)
229 {
230 gchar buf[256];
231 gboolean ret;
232 g_autofree gchar *filename = NULL;
233 g_autoptr(DfuFirmware) firmware = NULL;
234 g_autoptr(DfuImage) image = NULL;
235 g_autoptr(DfuElement) element = NULL;
236 g_autoptr(GBytes) data = NULL;
237 g_autoptr(GBytes) fw = NULL;
238 g_autoptr(GBytes) roundtrip_orig = NULL;
239 g_autoptr(GBytes) roundtrip = NULL;
240 g_autoptr(GError) error = NULL;
241 g_autoptr(GFile) file = NULL;
242
243 /* set up some dummy data */
244 for (guint i = 0; i < 256; i++)
245 buf[i] = (gchar) i;
246 fw = g_bytes_new_static (buf, 256);
247
248 /* write DFU format */
249 firmware = dfu_firmware_new ();
250 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU);
251 dfu_firmware_set_vid (firmware, 0x1234);
252 dfu_firmware_set_pid (firmware, 0x5678);
253 dfu_firmware_set_release (firmware, 0xfedc);
254 image = dfu_image_new ();
255 element = dfu_element_new ();
256 dfu_element_set_contents (element, fw);
257 dfu_image_add_element (image, element);
258 dfu_firmware_add_image (firmware, image);
259 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 256);
260 data = dfu_firmware_write_data (firmware, &error);
261 g_assert_no_error (error);
262 g_assert (data != NULL);
263
264 /* can we load it again? */
265 g_ptr_array_set_size (dfu_firmware_get_images (firmware), 0);
266 ret = dfu_firmware_parse_data (firmware, data, DFU_FIRMWARE_PARSE_FLAG_NONE, &error);
267 g_assert_no_error (error);
268 g_assert (ret);
269 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x1234);
270 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0x5678);
271 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xfedc);
272 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFU);
273 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 256);
274
275 /* load a real firmware */
276 filename = dfu_test_get_filename ("kiibohd.dfu.bin");
277 g_assert (filename != NULL);
278 file = g_file_new_for_path (filename);
279 g_ptr_array_set_size (dfu_firmware_get_images (firmware), 0);
280 ret = dfu_firmware_parse_file (firmware, file,
281 DFU_FIRMWARE_PARSE_FLAG_NONE,
282 NULL, &error);
283 g_assert_no_error (error);
284 g_assert (ret);
285 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x1c11);
286 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xb007);
287 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff);
288 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFU);
289 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x8eB4);
290 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
291
292 /* can we roundtrip without loosing data */
293 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
294 g_assert_no_error (error);
295 g_assert (roundtrip_orig != NULL);
296 roundtrip = dfu_firmware_write_data (firmware, &error);
297 g_assert_no_error (error);
298 g_assert (roundtrip != NULL);
299 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
300 }
301
302 static void
303 dfu_firmware_dfuse_func (void)
304 {
305 gboolean ret;
306 g_autofree gchar *filename = NULL;
307 g_autoptr(DfuFirmware) firmware = NULL;
308 g_autoptr(GBytes) roundtrip_orig = NULL;
309 g_autoptr(GBytes) roundtrip = NULL;
310 g_autoptr(GError) error = NULL;
311 g_autoptr(GFile) file = NULL;
312
313 /* load a DeFUse firmware */
314 g_setenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME", "", FALSE);
315 filename = dfu_test_get_filename ("dev_VRBRAIN.dfu");
316 g_assert (filename != NULL);
317 file = g_file_new_for_path (filename);
318 firmware = dfu_firmware_new ();
319 ret = dfu_firmware_parse_file (firmware, file,
320 DFU_FIRMWARE_PARSE_FLAG_NONE,
321 NULL, &error);
322 g_assert_no_error (error);
323 g_assert (ret);
324 g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x0483);
325 g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0x0000);
326 g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0x0000);
327 g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFUSE);
328 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x168d5);
329 g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE);
330
331 /* can we roundtrip without loosing data */
332 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
333 g_assert_no_error (error);
334 g_assert (roundtrip_orig != NULL);
335 roundtrip = dfu_firmware_write_data (firmware, &error);
336 g_assert_no_error (error);
337 g_assert (roundtrip != NULL);
338
339 // g_file_set_contents ("/tmp/1.bin",
340 // g_bytes_get_data (roundtrip, NULL),
341 // g_bytes_get_size (roundtrip), NULL);
342
343 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
344
345 /* use usual image name copying */
346 g_unsetenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME");
347 }
348
349 static void
350 dfu_firmware_metadata_func (void)
351 {
352 gboolean ret;
353 g_autofree gchar *filename = NULL;
354 g_autoptr(DfuFirmware) firmware = NULL;
355 g_autoptr(GBytes) roundtrip_orig = NULL;
356 g_autoptr(GBytes) roundtrip = NULL;
357 g_autoptr(GError) error = NULL;
358 g_autoptr(GFile) file = NULL;
359
360 /* load a DFU firmware with a metadata table */
361 filename = dfu_test_get_filename ("metadata.dfu");
362 g_assert (filename != NULL);
363 file = g_file_new_for_path (filename);
364 firmware = dfu_firmware_new ();
365 ret = dfu_firmware_parse_file (firmware, file,
366 DFU_FIRMWARE_PARSE_FLAG_NONE,
367 NULL, &error);
368 g_assert_no_error (error);
369 g_assert (ret);
370 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 6);
371 g_assert_cmpstr (dfu_firmware_get_metadata (firmware, "key"), ==, "value");
372 g_assert_cmpstr (dfu_firmware_get_metadata (firmware, "???"), ==, NULL);
373
374 /* can we roundtrip without loosing data */
375 roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error);
376 g_assert_no_error (error);
377 g_assert (roundtrip_orig != NULL);
378 roundtrip = dfu_firmware_write_data (firmware, &error);
379 g_assert_no_error (error);
380 g_assert (roundtrip != NULL);
381
382 g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL);
383 }
384
385 static void
386 dfu_firmware_intel_hex_func (void)
387 {
388 const guint8 *data;
389 gboolean ret;
390 gsize len;
391 g_autofree gchar *filename_hex = NULL;
392 g_autofree gchar *filename_ref = NULL;
393 g_autofree gchar *str = NULL;
394 g_autoptr(DfuFirmware) firmware = NULL;
395 g_autoptr(GBytes) data_bin2 = NULL;
396 g_autoptr(GBytes) data_bin = NULL;
397 g_autoptr(GBytes) data_hex = NULL;
398 g_autoptr(GBytes) data_ref = NULL;
399 g_autoptr(GError) error = NULL;
400 g_autoptr(GFile) file_bin = NULL;
401 g_autoptr(GFile) file_hex = NULL;
402
403 /* load a Intel hex32 file */
404 filename_hex = dfu_test_get_filename ("firmware.hex");
405 g_assert (filename_hex != NULL);
406 file_hex = g_file_new_for_path (filename_hex);
407 firmware = dfu_firmware_new ();
408 ret = dfu_firmware_parse_file (firmware, file_hex,
409 DFU_FIRMWARE_PARSE_FLAG_NONE,
410 NULL, &error);
411 g_assert_no_error (error);
412 g_assert (ret);
413 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 136);
414 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
415 data_bin = dfu_firmware_write_data (firmware, &error);
416 g_assert_no_error (error);
417 g_assert (data_bin != NULL);
418
419 /* did we match the reference file? */
420 filename_ref = dfu_test_get_filename ("firmware.bin");
421 g_assert (filename_ref != NULL);
422 file_bin = g_file_new_for_path (filename_ref);
423 data_ref = dfu_self_test_get_bytes_for_file (file_bin, &error);
424 g_assert_no_error (error);
425 g_assert (data_ref != NULL);
426 g_assert_cmpstr (_g_bytes_compare_verbose (data_bin, data_ref), ==, NULL);
427
428 /* export a ihex file (which will be slightly different due to
429 * non-continous regions being expanded */
430 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX);
431 data_hex = dfu_firmware_write_data (firmware, &error);
432 g_assert_no_error (error);
433 g_assert (data_hex != NULL);
434 data = g_bytes_get_data (data_hex, &len);
435 str = g_strndup ((const gchar *) data, len);
436 g_assert_cmpstr (str, ==,
437 ":104000003DEF20F000000000FACF01F0FBCF02F0AF\n"
438 ":10401000E9CF03F0EACF04F0E1CF05F0E2CF06F005\n"
439 ":10402000D9CF07F0DACF08F0F3CF09F0F4CF0AF021\n"
440 ":10403000F6CF0BF0F7CF0CF0F8CF0DF0F5CF0EF044\n"
441 ":104040000EC0F5FF0DC0F8FF0CC0F7FF0BC0F6FF45\n"
442 ":104050000AC0F4FF09C0F3FF08C0DAFF07C0D9FF24\n"
443 ":1040600006C0E2FF05C0E1FF04C0EAFF03C0E9FF0A\n"
444 ":1040700002C0FBFF01C0FAFF11003FEF20F00001BB\n"
445 ":0840800042EF20F03DEF20F037\n"
446 ":00000001FF\n");
447
448 /* do we match the binary file again */
449 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW);
450 data_bin2 = dfu_firmware_write_data (firmware, &error);
451 g_assert_no_error (error);
452 g_assert (data_bin2 != NULL);
453 g_assert_cmpstr (_g_bytes_compare_verbose (data_bin, data_bin2), ==, NULL);
454 }
455
456 static void
457 dfu_firmware_intel_hex_signed_func (void)
458 {
459 DfuElement *element;
460 DfuImage *image;
461 GBytes *data_sig;
462 const guint8 *data;
463 gboolean ret;
464 gsize len;
465 g_autofree gchar *filename_hex = NULL;
466 g_autoptr(DfuFirmware) firmware = NULL;
467 g_autoptr(GError) error = NULL;
468 g_autoptr(GFile) file_hex = NULL;
469
470 /* load a Intel hex32 file */
471 filename_hex = dfu_test_get_filename ("firmware.shex");
472 g_assert (filename_hex != NULL);
473 file_hex = g_file_new_for_path (filename_hex);
474 firmware = dfu_firmware_new ();
475 ret = dfu_firmware_parse_file (firmware, file_hex,
476 DFU_FIRMWARE_PARSE_FLAG_NONE,
477 NULL, &error);
478 g_assert_no_error (error);
479 g_assert (ret);
480 g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 144);
481
482 /* get the signed image element */
483 image = dfu_firmware_get_image_by_name (firmware, "signature");
484 g_assert (image != NULL);
485 element = dfu_image_get_element_default (image);
486 data_sig = dfu_element_get_contents (element);
487 g_assert (data_sig != NULL);
488 data = g_bytes_get_data (data_sig, &len);
489 g_assert_cmpint (len, ==, 8);
490 g_assert (data != NULL);
491 }
492
493 static void
494 dfu_device_func (void)
495 {
496 GPtrArray *targets;
497 gboolean ret;
498 g_autoptr(DfuDevice) device = NULL;
499 g_autoptr(DfuTarget) target1 = NULL;
500 g_autoptr(DfuTarget) target2 = NULL;
501 g_autoptr(GError) error = NULL;
502 g_autoptr(GUsbContext) usb_ctx = NULL;
503 g_autoptr(GUsbDevice) usb_device = NULL;
504
505 /* find any DFU in appIDLE mode */
506 usb_ctx = g_usb_context_new (&error);
507 g_assert_no_error (error);
508 g_assert (usb_ctx != NULL);
509 g_usb_context_enumerate (usb_ctx);
510 usb_device = g_usb_context_find_by_vid_pid (usb_ctx,
511 0x273f,
512 0x1005,
513 &error);
514 if (usb_device == NULL)
515 return;
516 g_assert_no_error (error);
517 g_assert (usb_device != NULL);
518
519 /* check it's DFU-capable */
520 device = dfu_device_new (usb_device);
521 g_assert (device != NULL);
522
523 /* get targets */
524 targets = dfu_device_get_targets (device);
525 g_assert_cmpint (targets->len, ==, 2);
526
527 /* get by ID */
528 target1 = dfu_device_get_target_by_alt_setting (device, 1, &error);
529 g_assert_no_error (error);
530 g_assert (target1 != NULL);
531
532 /* ensure open */
533 ret = dfu_device_open (device, &error);
534 g_assert_no_error (error);
535 g_assert (ret);
536
537 /* get by name */
538 target2 = dfu_device_get_target_by_alt_name (device, "sram", &error);
539 g_assert_no_error (error);
540 g_assert (target2 != NULL);
541
542 /* close */
543 ret = dfu_device_close (device, &error);
544 g_assert_no_error (error);
545 g_assert (ret);
546 }
547
548 static void
549 dfu_colorhug_plus_func (void)
550 {
551 GPtrArray *elements;
552 gboolean ret;
553 gboolean seen_app_idle = FALSE;
554 g_autoptr(DfuContext) context = NULL;
555 g_autoptr(DfuDevice) device = NULL;
556 g_autoptr(DfuDevice) device2 = NULL;
557 g_autoptr(DfuTarget) target = NULL;
558 g_autoptr(DfuImage) image = NULL;
559 g_autoptr(GError) error = NULL;
560
561 /* create context */
562 context = dfu_context_new ();
563 ret = dfu_context_enumerate (context, &error);
564 g_assert_no_error (error);
565 g_assert (ret);
566
567 /* push appIDLE into dfuIDLE */
568 device2 = dfu_context_get_device_by_vid_pid (context,
569 0x273f,
570 0x1002,
571 NULL);
572 if (device2 != NULL) {
573 ret = dfu_device_open (device2, &error);
574 g_assert_no_error (error);
575 g_assert (ret);
576 ret = dfu_device_detach (device2, NULL, &error);
577 g_assert_no_error (error);
578 g_assert (ret);
579
580 /* wait for it to come back as 273f:1005 */
581 ret = dfu_device_wait_for_replug (device2, 5000, NULL, &error);
582 g_assert_no_error (error);
583 g_assert (ret);
584
585 /* close it */
586 ret = dfu_device_close (device2, &error);
587 g_assert_no_error (error);
588 g_assert (ret);
589 }
590
591 /* find any DFU in dfuIDLE mode */
592 device = dfu_context_get_device_by_vid_pid (context,
593 0x273f,
594 0x1003,
595 NULL);
596 if (device == NULL)
597 return;
598
599 /* we don't know this unless we went from appIDLE -> dfuIDLE */
600 if (device2 == NULL) {
601 g_assert_cmpint (dfu_device_get_runtime_vid (device), ==, 0xffff);
602 g_assert_cmpint (dfu_device_get_runtime_pid (device), ==, 0xffff);
603 }
604
605 /* open it */
606 ret = dfu_device_open (device, &error);
607 g_assert_no_error (error);
608 g_assert (ret);
609
610 /* is in dfuIDLE mode */
611 g_assert_cmpstr (dfu_state_to_string (dfu_device_get_state (device)), ==, "dfuIDLE");
612
613 /* lets try and flash something inappropriate */
614 if (seen_app_idle) {
615 g_autoptr(DfuFirmware) firmware = NULL;
616 g_autoptr(GFile) file = NULL;
617 g_autofree gchar *filename = NULL;
618
619 filename = dfu_test_get_filename ("kiibohd.dfu.bin");
620 g_assert (filename != NULL);
621 file = g_file_new_for_path (filename);
622 firmware = dfu_firmware_new ();
623 ret = dfu_firmware_parse_file (firmware, file,
624 DFU_FIRMWARE_PARSE_FLAG_NONE,
625 NULL, &error);
626 g_assert_no_error (error);
627 g_assert (ret);
628 ret = dfu_device_download (device, firmware,
629 DFU_TARGET_TRANSFER_FLAG_DETACH |
630 DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME,
631 NULL, &error);
632 g_assert_error (error,
633 FWUPD_ERROR,
634 FWUPD_ERROR_INTERNAL);
635 g_assert (ret);
636 g_clear_error (&error);
637 }
638
639 /* get a dump of the existing firmware */
640 target = dfu_device_get_target_by_alt_setting (device, 0, &error);
641 g_assert_no_error (error);
642 g_assert (target != NULL);
643 image = dfu_target_upload (target, DFU_TARGET_TRANSFER_FLAG_NONE,
644 NULL, &error);
645 g_assert_no_error (error);
646 g_assert (DFU_IS_IMAGE (image));
647 elements = dfu_image_get_elements (image);
648 g_assert (elements != NULL);
649 g_assert_cmpint (elements->len, ==, 1);
650
651 /* download a new firmware */
652 ret = dfu_target_download (target, image,
653 DFU_TARGET_TRANSFER_FLAG_VERIFY |
654 DFU_TARGET_TRANSFER_FLAG_ATTACH,
655 NULL, &error);
656 g_assert_no_error (error);
657 g_assert (ret);
658
659 /* wait for it to come back as 273f:1004 */
660 ret = dfu_device_wait_for_replug (device, 5000, NULL, &error);
661 g_assert_no_error (error);
662 g_assert (ret);
663
664 /* we should know now */
665 g_assert_cmpint (dfu_device_get_runtime_vid (device), ==, 0x273f);
666 g_assert_cmpint (dfu_device_get_runtime_pid (device), ==, 0x1002);
667 }
668
669 static gchar *
670 dfu_target_sectors_to_string (DfuTarget *target)
671 {
672 GPtrArray *sectors;
673 GString *str;
674
675 str = g_string_new ("");
676 sectors = dfu_target_get_sectors (target);
677 for (guint i = 0; i < sectors->len; i++) {
678 DfuSector *sector = g_ptr_array_index (sectors, i);
679 g_autofree gchar *tmp = dfu_sector_to_string (sector);
680 g_string_append_printf (str, "%s\n", tmp);
681 }
682 if (str->len > 0)
683 g_string_truncate (str, str->len - 1);
684 return g_string_free (str, FALSE);
685 }
686
687 static void
688 dfu_target_dfuse_func (void)
689 {
690 gboolean ret;
691 gchar *tmp;
692 g_autoptr(DfuTarget) target = NULL;
693 g_autoptr(GError) error = NULL;
694
695 /* NULL */
696 target = g_object_new (DFU_TYPE_TARGET, NULL);
697 ret = dfu_target_parse_sectors (target, NULL, &error);
698 g_assert_no_error (error);
699 g_assert (ret);
700 tmp = dfu_target_sectors_to_string (target);
701 g_assert_cmpstr (tmp, ==, "");
702 g_free (tmp);
703
704 /* no addresses */
705 ret = dfu_target_parse_sectors (target, "@Flash3", &error);
706 g_assert_no_error (error);
707 g_assert (ret);
708 tmp = dfu_target_sectors_to_string (target);
709 g_assert_cmpstr (tmp, ==, "");
710 g_free (tmp);
711
712 /* one sector, no space */
713 ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000/2*001Ka", &error);
714 g_assert_no_error (error);
715 g_assert (ret);
716 tmp = dfu_target_sectors_to_string (target);
717 ret = dfu_test_compare_lines (tmp,
718 "Zone:0, Sec#:0, Addr:0x08000000, Size:0x0400, Caps:0x1 [R]\n"
719 "Zone:0, Sec#:0, Addr:0x08000400, Size:0x0400, Caps:0x1 [R]",
720 &error);
721 g_assert_no_error (error);
722 g_assert (ret);
723 g_free (tmp);
724
725 /* multiple sectors */
726 ret = dfu_target_parse_sectors (target, "@Flash1 /0x08000000/2*001Ka,4*001Kg", &error);
727 g_assert_no_error (error);
728 g_assert (ret);
729 tmp = dfu_target_sectors_to_string (target);
730 ret = dfu_test_compare_lines (tmp,
731 "Zone:0, Sec#:0, Addr:0x08000000, Size:0x0400, Caps:0x1 [R]\n"
732 "Zone:0, Sec#:0, Addr:0x08000400, Size:0x0400, Caps:0x1 [R]\n"
733 "Zone:0, Sec#:1, Addr:0x08000800, Size:0x0400, Caps:0x7 [REW]\n"
734 "Zone:0, Sec#:1, Addr:0x08000c00, Size:0x0400, Caps:0x7 [REW]\n"
735 "Zone:0, Sec#:1, Addr:0x08001000, Size:0x0400, Caps:0x7 [REW]\n"
736 "Zone:0, Sec#:1, Addr:0x08001400, Size:0x0400, Caps:0x7 [REW]",
737 &error);
738 g_assert_no_error (error);
739 g_assert (ret);
740 g_free (tmp);
741
742 /* non-contiguous */
743 ret = dfu_target_parse_sectors (target, "@Flash2 /0xF000/4*100Ba/0xE000/3*8Kg/0x80000/2*24Kg", &error);
744 g_assert_no_error (error);
745 g_assert (ret);
746 tmp = dfu_target_sectors_to_string (target);
747 ret = dfu_test_compare_lines (tmp,
748 "Zone:0, Sec#:0, Addr:0x0000f000, Size:0x0064, Caps:0x1 [R]\n"
749 "Zone:0, Sec#:0, Addr:0x0000f064, Size:0x0064, Caps:0x1 [R]\n"
750 "Zone:0, Sec#:0, Addr:0x0000f0c8, Size:0x0064, Caps:0x1 [R]\n"
751 "Zone:0, Sec#:0, Addr:0x0000f12c, Size:0x0064, Caps:0x1 [R]\n"
752 "Zone:1, Sec#:0, Addr:0x0000e000, Size:0x2000, Caps:0x7 [REW]\n"
753 "Zone:1, Sec#:0, Addr:0x00010000, Size:0x2000, Caps:0x7 [REW]\n"
754 "Zone:1, Sec#:0, Addr:0x00012000, Size:0x2000, Caps:0x7 [REW]\n"
755 "Zone:2, Sec#:0, Addr:0x00080000, Size:0x6000, Caps:0x7 [REW]\n"
756 "Zone:2, Sec#:0, Addr:0x00086000, Size:0x6000, Caps:0x7 [REW]",
757 &error);
758 g_assert_no_error (error);
759 g_assert (ret);
760 g_free (tmp);
761
762 /* invalid */
763 ret = dfu_target_parse_sectors (target, "Flash", NULL);
764 g_assert (ret);
765 ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000", NULL);
766 g_assert (!ret);
767 ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000/12*001a", NULL);
768 g_assert (!ret);
769
770 /* indicate a cipher being used */
771 g_assert_cmpint (dfu_target_get_cipher_kind (target), ==, DFU_CIPHER_KIND_NONE);
772 ret = dfu_target_parse_sectors (target, "@Flash|XTEA", &error);
773 g_assert_no_error (error);
774 g_assert (ret);
775 g_assert_cmpint (dfu_target_get_cipher_kind (target), ==, DFU_CIPHER_KIND_XTEA);
776 }
777
778 static gboolean
779 dfu_patch_create_from_strings (DfuPatch *patch,
780 const gchar *dold,
781 const gchar *dnew,
782 GError **error)
783 {
784 guint32 sz1 = strlen (dold);
785 guint32 sz2 = strlen (dnew);
786 g_autoptr(GBytes) blob1 = g_bytes_new (dold, sz1);
787 g_autoptr(GBytes) blob2 = g_bytes_new (dnew, sz2);
788 g_debug ("compare:\n%s\n%s", dold, dnew);
789 return dfu_patch_create (patch, blob1, blob2, error);
790 }
791
792 static void
793 dfu_patch_merges_func (void)
794 {
795 const guint8 *data;
796 gboolean ret;
797 gsize sz;
798 g_autoptr(DfuPatch) patch = dfu_patch_new ();
799 g_autoptr(GBytes) blob = NULL;
800 g_autoptr(GError) error = NULL;
801
802 /* check merges happen */
803 ret = dfu_patch_create_from_strings (patch, "XXX", "YXY", &error);
804 g_assert_no_error (error);
805 g_assert (ret);
806 blob = dfu_patch_export (patch, &error);
807 g_assert_no_error (error);
808 g_assert (ret);
809 data = g_bytes_get_data (blob, &sz);
810 g_assert_cmpint (data[0x00], ==, 'D');
811 g_assert_cmpint (data[0x01], ==, 'f');
812 g_assert_cmpint (data[0x02], ==, 'u');
813 g_assert_cmpint (data[0x03], ==, 'P');
814 g_assert_cmpint (data[0x04], ==, 0x00); /* reserved */
815 g_assert_cmpint (data[0x05], ==, 0x00);
816 g_assert_cmpint (data[0x06], ==, 0x00);
817 g_assert_cmpint (data[0x07], ==, 0x00);
818 g_assert_cmpint (data[0x08 + 0x28], ==, 0x00); /* chunk1, offset */
819 g_assert_cmpint (data[0x09 + 0x28], ==, 0x00);
820 g_assert_cmpint (data[0x0a + 0x28], ==, 0x00);
821 g_assert_cmpint (data[0x0b + 0x28], ==, 0x00);
822 g_assert_cmpint (data[0x0c + 0x28], ==, 0x03); /* chunk1, size */
823 g_assert_cmpint (data[0x0d + 0x28], ==, 0x00);
824 g_assert_cmpint (data[0x0e + 0x28], ==, 0x00);
825 g_assert_cmpint (data[0x0f + 0x28], ==, 0x00);
826 g_assert_cmpint (data[0x10 + 0x28], ==, 0x00); /* reserved */
827 g_assert_cmpint (data[0x11 + 0x28], ==, 0x00);
828 g_assert_cmpint (data[0x12 + 0x28], ==, 0x00);
829 g_assert_cmpint (data[0x13 + 0x28], ==, 0x00);
830 g_assert_cmpint (data[0x14 + 0x28], ==, 'Y');
831 g_assert_cmpint (data[0x15 + 0x28], ==, 'X');
832 g_assert_cmpint (data[0x16 + 0x28], ==, 'Y');
833 g_assert_cmpint (sz, ==, 48 /* hdr */ + 12 /* chunk */ + 3 /* data */);
834 }
835
836 static void
837 dfu_patch_apply_func (void)
838 {
839 gboolean ret;
840 g_autoptr(DfuPatch) patch = dfu_patch_new ();
841 g_autoptr(GBytes) blob_new2 = NULL;
842 g_autoptr(GBytes) blob_new3 = NULL;
843 g_autoptr(GBytes) blob_new4 = NULL;
844 g_autoptr(GBytes) blob_new = NULL;
845 g_autoptr(GBytes) blob_old = NULL;
846 g_autoptr(GBytes) blob_wrong = NULL;
847 g_autoptr(GError) error = NULL;
848
849 /* create a patch */
850 blob_old = g_bytes_new_static ("helloworldhelloworldhelloworldhelloworld", 40);
851 blob_new = g_bytes_new_static ("XelloXorldhelloworldhelloworldhelloworlXXX", 42);
852 ret = dfu_patch_create (patch, blob_old, blob_new, &error);
853 g_assert_no_error (error);
854 g_assert (ret);
855
856 /* apply the patch */
857 blob_new2 = dfu_patch_apply (patch, blob_old, DFU_PATCH_APPLY_FLAG_NONE, &error);
858 g_assert_no_error (error);
859 g_assert (blob_new2 != NULL);
860 g_assert_cmpint (g_bytes_compare (blob_new, blob_new2), ==, 0);
861
862 /* check we force the patch to an unrelated blob */
863 blob_wrong = g_bytes_new_static ("wrongwrongwrongwrongwrongwrongwrongwrong", 40);
864 blob_new3 = dfu_patch_apply (patch, blob_wrong, DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM, &error);
865 g_assert_no_error (error);
866 g_assert (blob_new3 != NULL);
867
868 /* check we can't apply the patch to an unrelated blob */
869 blob_new4 = dfu_patch_apply (patch, blob_wrong, DFU_PATCH_APPLY_FLAG_NONE, &error);
870 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE);
871 g_assert (blob_new4 == NULL);
872 }
873
874 static void
875 dfu_patch_func (void)
876 {
877 const guint8 *data;
878 gboolean ret;
879 gsize sz;
880 g_autoptr(DfuPatch) patch = dfu_patch_new ();
881 g_autoptr(DfuPatch) patch2 = dfu_patch_new ();
882 g_autoptr(GBytes) blob = NULL;
883 g_autoptr(GError) error = NULL;
884 g_autofree gchar *serialized_str = NULL;
885
886 /* create binary diff */
887 ret = dfu_patch_create_from_strings (patch, "XXX", "XYY", &error);
888 g_assert_no_error (error);
889 g_assert (ret);
890
891 /* check we can serialize this object to a blob */
892 blob = dfu_patch_export (patch, &error);
893 g_assert_no_error (error);
894 g_assert (ret);
895 data = g_bytes_get_data (blob, &sz);
896 g_assert_cmpint (data[0x00], ==, 'D');
897 g_assert_cmpint (data[0x01], ==, 'f');
898 g_assert_cmpint (data[0x02], ==, 'u');
899 g_assert_cmpint (data[0x03], ==, 'P');
900 g_assert_cmpint (data[0x04], ==, 0x00); /* reserved */
901 g_assert_cmpint (data[0x05], ==, 0x00);
902 g_assert_cmpint (data[0x06], ==, 0x00);
903 g_assert_cmpint (data[0x07], ==, 0x00);
904 g_assert_cmpint (data[0x08 + 0x28], ==, 0x01); /* chunk1, offset */
905 g_assert_cmpint (data[0x09 + 0x28], ==, 0x00);
906 g_assert_cmpint (data[0x0a + 0x28], ==, 0x00);
907 g_assert_cmpint (data[0x0b + 0x28], ==, 0x00);
908 g_assert_cmpint (data[0x0c + 0x28], ==, 0x02); /* chunk1, size */
909 g_assert_cmpint (data[0x0d + 0x28], ==, 0x00);
910 g_assert_cmpint (data[0x0e + 0x28], ==, 0x00);
911 g_assert_cmpint (data[0x0f + 0x28], ==, 0x00);
912 g_assert_cmpint (data[0x10 + 0x28], ==, 0x00); /* reserved */
913 g_assert_cmpint (data[0x11 + 0x28], ==, 0x00);
914 g_assert_cmpint (data[0x12 + 0x28], ==, 0x00);
915 g_assert_cmpint (data[0x13 + 0x28], ==, 0x00);
916 g_assert_cmpint (data[0x14 + 0x28], ==, 'Y');
917 g_assert_cmpint (data[0x15 + 0x28], ==, 'Y');
918 g_assert_cmpint (sz, ==, 48 /* hdr */ + 12 /* chunk */ + 2 /* data */);
919
920 /* try to load it from the serialized blob */
921 ret = dfu_patch_import (patch2, blob, &error);
922 g_assert_no_error (error);
923 g_assert (ret);
924 serialized_str = dfu_patch_to_string (patch2);
925 g_debug ("serialized blob %s", serialized_str);
926 }
927
928 int
929 main (int argc, char **argv)
930 {
931 g_test_init (&argc, &argv, NULL);
932
933 /* only critical and error are fatal */
934 g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
935
936 /* log everything */
937 g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
938
939 /* tests go here */
940 g_test_add_func ("/dfu/patch", dfu_patch_func);
941 g_test_add_func ("/dfu/patch{merges}", dfu_patch_merges_func);
942 g_test_add_func ("/dfu/patch{apply}", dfu_patch_apply_func);
943 g_test_add_func ("/dfu/enums", dfu_enums_func);
944 g_test_add_func ("/dfu/target(DfuSe}", dfu_target_dfuse_func);
945 g_test_add_func ("/dfu/cipher{xtea}", dfu_cipher_xtea_func);
946 g_test_add_func ("/dfu/firmware{raw}", dfu_firmware_raw_func);
947 g_test_add_func ("/dfu/firmware{dfu}", dfu_firmware_dfu_func);
948 g_test_add_func ("/dfu/firmware{dfuse}", dfu_firmware_dfuse_func);
949 g_test_add_func ("/dfu/firmware{xdfu}", dfu_firmware_xdfu_func);
950 g_test_add_func ("/dfu/firmware{metadata}", dfu_firmware_metadata_func);
951 g_test_add_func ("/dfu/firmware{intel-hex}", dfu_firmware_intel_hex_func);
952 g_test_add_func ("/dfu/firmware{intel-hex-signed}", dfu_firmware_intel_hex_signed_func);
953 g_test_add_func ("/dfu/device", dfu_device_func);
954 g_test_add_func ("/dfu/colorhug+", dfu_colorhug_plus_func);
955 return g_test_run ();
956 }
957
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_TARGET_PRIVATE_H
22 #define __DFU_TARGET_PRIVATE_H
23
24 #include <gusb.h>
25
26 #include "dfu-device.h"
27 #include "dfu-target.h"
28
29 G_BEGIN_DECLS
30
31 DfuTarget *dfu_target_new (DfuDevice *device,
32 GUsbInterface *iface);
33
34 GBytes *dfu_target_upload_chunk (DfuTarget *target,
35 guint8 index,
36 GCancellable *cancellable,
37 GError **error);
38 gboolean dfu_target_download_chunk (DfuTarget *target,
39 guint8 index,
40 GBytes *bytes,
41 GCancellable *cancellable,
42 GError **error);
43
44 /* export this just for the self tests */
45 gboolean dfu_target_parse_sectors (DfuTarget *target,
46 const gchar *alt_name,
47 GError **error);
48
49 G_END_DECLS
50
51 #endif /* __DFU_TARGET_PRIVATE_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * SECTION:dfu-target
23 * @short_description: Object representing a DFU-capable target
24 *
25 * This object allows uploading and downloading an image onto a
26 * specific DFU-capable target.
27 *
28 * You only need to use this in preference to #DfuDevice if you only
29 * want to update one target on the device. Most users will want to
30 * update all the targets on the device at the same time.
31 *
32 * See also: #DfuDevice, #DfuImage
33 */
34
35 #include "config.h"
36
37 #include <string.h>
38 #include <math.h>
39
40 #include "dfu-common.h"
41 #include "dfu-device-private.h"
42 #include "dfu-sector-private.h"
43 #include "dfu-target-private.h"
44
45 #include "fwupd-error.h"
46
47 static void dfu_target_finalize (GObject *object);
48
49 typedef enum {
50 DFU_CMD_DFUSE_GET_COMMAND = 0x00,
51 DFU_CMD_DFUSE_SET_ADDRESS_POINTER = 0x21,
52 DFU_CMD_DFUSE_ERASE = 0x41,
53 DFU_CMD_DFUSE_READ_UNPROTECT = 0x92,
54 DFU_CMD_DFUSE_LAST
55 } DfuCmdDfuse;
56
57 typedef struct {
58 DfuDevice *device; /* not refcounted */
59 DfuCipherKind cipher_kind;
60 gboolean done_setup;
61 guint8 alt_setting;
62 guint8 alt_idx;
63 gchar *alt_name;
64 gchar *alt_name_for_display;
65 GPtrArray *sectors; /* of DfuSector */
66 guint old_percentage;
67 FwupdStatus old_action;
68 } DfuTargetPrivate;
69
70 enum {
71 SIGNAL_PERCENTAGE_CHANGED,
72 SIGNAL_ACTION_CHANGED,
73 SIGNAL_LAST
74 };
75
76 static guint signals [SIGNAL_LAST] = { 0 };
77
78 G_DEFINE_TYPE_WITH_PRIVATE (DfuTarget, dfu_target, G_TYPE_OBJECT)
79 #define GET_PRIVATE(o) (dfu_target_get_instance_private (o))
80
81 static void
82 dfu_target_class_init (DfuTargetClass *klass)
83 {
84 GObjectClass *object_class = G_OBJECT_CLASS (klass);
85
86 /**
87 * DfuTarget::percentage-changed:
88 * @device: the #DfuTarget instance that emitted the signal
89 * @percentage: the new percentage
90 *
91 * The ::percentage-changed signal is emitted when the percentage changes.
92 **/
93 signals [SIGNAL_PERCENTAGE_CHANGED] =
94 g_signal_new ("percentage-changed",
95 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
96 G_STRUCT_OFFSET (DfuTargetClass, percentage_changed),
97 NULL, NULL, g_cclosure_marshal_VOID__UINT,
98 G_TYPE_NONE, 1, G_TYPE_UINT);
99
100 /**
101 * DfuTarget::action-changed:
102 * @device: the #DfuTarget instance that emitted the signal
103 * @action: the new FwupdStatus
104 *
105 * The ::action-changed signal is emitted when the high level action changes.
106 **/
107 signals [SIGNAL_ACTION_CHANGED] =
108 g_signal_new ("action-changed",
109 G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
110 G_STRUCT_OFFSET (DfuTargetClass, action_changed),
111 NULL, NULL, g_cclosure_marshal_VOID__UINT,
112 G_TYPE_NONE, 1, G_TYPE_UINT);
113
114 object_class->finalize = dfu_target_finalize;
115 }
116
117 static void
118 dfu_target_init (DfuTarget *target)
119 {
120 DfuTargetPrivate *priv = GET_PRIVATE (target);
121 priv->sectors = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
122 priv->old_percentage = G_MAXUINT;
123 priv->old_action = FWUPD_STATUS_IDLE;
124 }
125
126 static void
127 dfu_target_finalize (GObject *object)
128 {
129 DfuTarget *target = DFU_TARGET (object);
130 DfuTargetPrivate *priv = GET_PRIVATE (target);
131
132 g_free (priv->alt_name);
133 g_free (priv->alt_name_for_display);
134 g_ptr_array_unref (priv->sectors);
135
136 /* we no longer care */
137 if (priv->device != NULL) {
138 g_object_remove_weak_pointer (G_OBJECT (priv->device),
139 (gpointer *) &priv->device);
140 }
141
142 G_OBJECT_CLASS (dfu_target_parent_class)->finalize (object);
143 }
144
145 static gchar *
146 dfu_target_sectors_to_string (DfuTarget *target)
147 {
148 DfuTargetPrivate *priv = GET_PRIVATE (target);
149 GString *str = g_string_new ("");
150 for (guint i = 0; i < priv->sectors->len; i++) {
151 DfuSector *sector = g_ptr_array_index (priv->sectors, i);
152 g_autofree gchar *tmp = dfu_sector_to_string (sector);
153 g_string_append_printf (str, "%s\n", tmp);
154 }
155 if (str->len > 0)
156 g_string_truncate (str, str->len - 1);
157 return g_string_free (str, FALSE);
158 }
159
160 static DfuSector *
161 dfu_target_get_sector_for_addr (DfuTarget *target, guint32 addr)
162 {
163 DfuTargetPrivate *priv = GET_PRIVATE (target);
164
165 for (guint i = 0; i < priv->sectors->len; i++) {
166 DfuSector *sector = g_ptr_array_index (priv->sectors, i);
167 if (addr < dfu_sector_get_address (sector))
168 continue;
169 if (addr > dfu_sector_get_address (sector) +
170 dfu_sector_get_size (sector))
171 continue;
172 return sector;
173 }
174 return NULL;
175 }
176
177 static gboolean
178 dfu_target_parse_sector (DfuTarget *target,
179 const gchar *dfuse_sector_id,
180 guint32 *addr,
181 guint16 zone,
182 guint16 number,
183 GError **error)
184 {
185 DfuTargetPrivate *priv = GET_PRIVATE (target);
186 DfuSectorCap cap = DFU_SECTOR_CAP_NONE;
187 gchar *tmp;
188 guint32 addr_offset = 0;
189 guint64 nr_sectors;
190 guint64 sector_size;
191
192 /* parse # of sectors */
193 nr_sectors = g_ascii_strtoull (dfuse_sector_id, &tmp, 10);
194 if (nr_sectors > 999) {
195 g_set_error (error,
196 FWUPD_ERROR,
197 FWUPD_ERROR_NOT_SUPPORTED,
198 "Invalid number of sectors: %s",
199 dfuse_sector_id);
200 return FALSE;
201 }
202
203 /* check this is the delimiter */
204 if (tmp[0] != '*') {
205 g_set_error (error,
206 FWUPD_ERROR,
207 FWUPD_ERROR_NOT_SUPPORTED,
208 "Invalid sector ID: %s",
209 dfuse_sector_id);
210 return FALSE;
211 }
212
213 /* parse sector size */
214 sector_size = g_ascii_strtoull (tmp + 1, &tmp, 10);
215 if (sector_size > 999) {
216 g_set_error (error,
217 FWUPD_ERROR,
218 FWUPD_ERROR_NOT_SUPPORTED,
219 "Invalid sector size: %s",
220 dfuse_sector_id);
221 return FALSE;
222 }
223
224 /* get multiplier */
225 switch (tmp[0]) {
226 case 'B': /* byte */
227 case ' ': /* byte, ST reference bootloader :/ */
228 break;
229 case 'K': /* Kilo */
230 sector_size *= 0x400;
231 break;
232 case 'M': /* Mega */
233 sector_size *= 0x100000 ;
234 break;
235 default:
236 g_set_error (error,
237 FWUPD_ERROR,
238 FWUPD_ERROR_NOT_SUPPORTED,
239 "Invalid sector multiplier: %s",
240 tmp);
241 return FALSE;
242 }
243
244 /* get sector type */
245 switch (tmp[1]) {
246 case 'a':
247 cap = DFU_SECTOR_CAP_READABLE;
248 break;
249 case 'b':
250 cap = DFU_SECTOR_CAP_ERASEABLE;
251 break;
252 case 'c':
253 cap = DFU_SECTOR_CAP_READABLE |
254 DFU_SECTOR_CAP_ERASEABLE;
255 break;
256 case 'd':
257 cap = DFU_SECTOR_CAP_WRITEABLE;
258 break;
259 case 'e':
260 cap = DFU_SECTOR_CAP_READABLE |
261 DFU_SECTOR_CAP_WRITEABLE;
262 break;
263 case 'f':
264 cap = DFU_SECTOR_CAP_ERASEABLE |
265 DFU_SECTOR_CAP_WRITEABLE;
266 break;
267 case 'g':
268 cap = DFU_SECTOR_CAP_READABLE |
269 DFU_SECTOR_CAP_ERASEABLE |
270 DFU_SECTOR_CAP_WRITEABLE;
271 break;
272 default:
273 g_set_error (error,
274 FWUPD_ERROR,
275 FWUPD_ERROR_NOT_SUPPORTED,
276 "Invalid sector type: %s",
277 tmp);
278 return FALSE;
279 }
280
281 /* add all the sectors */
282 for (guint i = 0; i < nr_sectors; i++) {
283 DfuSector *sector;
284 sector = dfu_sector_new (*addr + addr_offset,
285 (guint32) sector_size,
286 (guint32) ((nr_sectors * sector_size) - addr_offset),
287 zone,
288 number,
289 cap);
290 g_ptr_array_add (priv->sectors, sector);
291 addr_offset += dfu_sector_get_size (sector);
292 }
293
294 /* update for next sector */
295 *addr += addr_offset;
296 return TRUE;
297 }
298
299 gboolean
300 dfu_target_parse_sectors (DfuTarget *target, const gchar *alt_name, GError **error)
301 {
302 DfuTargetPrivate *priv = GET_PRIVATE (target);
303 g_autofree gchar *str_debug = NULL;
304 g_auto(GStrv) zones = NULL;
305
306 /* not set */
307 if (alt_name == NULL)
308 return TRUE;
309
310 /* do we have any hint for the cipher */
311 if (g_strstr_len (alt_name, -1, "|XTEA") != NULL)
312 priv->cipher_kind = DFU_CIPHER_KIND_XTEA;
313
314 /* From the Neo Freerunner */
315 if (g_str_has_prefix (alt_name, "RAM 0x")) {
316 DfuSector *sector;
317 guint64 addr_tmp;
318 addr_tmp = g_ascii_strtoull (alt_name + 6, NULL, 16);
319 if (addr_tmp == 0 || addr_tmp > G_MAXUINT32)
320 return FALSE;
321 g_debug ("RAM description, so parsing");
322 sector = dfu_sector_new ((guint32) addr_tmp,
323 0x0, /* size */
324 0x0, /* size_left */
325 0x0, /* zone */
326 0x0, /* number */
327 DFU_SECTOR_CAP_READABLE |
328 DFU_SECTOR_CAP_WRITEABLE);
329 g_ptr_array_add (priv->sectors, sector);
330 }
331
332 /* not a DfuSe alternative name */
333 if (alt_name[0] != '@')
334 return TRUE;
335
336 /* clear any existing zones */
337 g_ptr_array_set_size (priv->sectors, 0);
338
339 /* parse zones */
340 zones = g_strsplit (alt_name, "/", -1);
341 g_free (priv->alt_name_for_display);
342 priv->alt_name_for_display = g_strdup (g_strchomp (zones[0] + 1));
343 for (guint i = 1; zones[i] != NULL; i += 2) {
344 guint32 addr;
345 guint64 addr_tmp;
346 g_auto(GStrv) sectors = NULL;
347
348 /* parse address */
349 if (!g_str_has_prefix (zones[i], "0x")) {
350 g_set_error_literal (error,
351 FWUPD_ERROR,
352 FWUPD_ERROR_NOT_SUPPORTED,
353 "No sector address");
354 return FALSE;
355 }
356 addr_tmp = g_ascii_strtoull (zones[i] + 2, NULL, 16);
357 if (addr_tmp > G_MAXUINT32) {
358 g_set_error_literal (error,
359 FWUPD_ERROR,
360 FWUPD_ERROR_NOT_SUPPORTED,
361 "Sector address too large");
362 return FALSE;
363 }
364 addr = (guint32) addr_tmp;
365
366 /* no sectors?! */
367 if (zones[i+1] == NULL) {
368 g_set_error_literal (error,
369 FWUPD_ERROR,
370 FWUPD_ERROR_NOT_SUPPORTED,
371 "No sector section");
372 return FALSE;
373 }
374
375 /* parse sectors */
376 sectors = g_strsplit (zones[i+1], ",", -1);
377 for (guint16 j = 0; sectors[j] != NULL; j++) {
378 if (!dfu_target_parse_sector (target,
379 sectors[j],
380 &addr,
381 (i - 1) / 2, j,
382 error)) {
383 g_prefix_error (error,
384 "Failed to parse: '%s': ",
385 sectors[j]);
386 return FALSE;
387 }
388 }
389 }
390
391 /* success */
392 str_debug = dfu_target_sectors_to_string (target);
393 g_debug ("%s", str_debug);
394 return TRUE;
395 }
396
397 /**
398 * dfu_target_new: (skip)
399 * @device: a #DfuDevice
400 * @iface: a #GUsbInterface
401 *
402 * Creates a new DFU target, which represents an alt-setting on a
403 * DFU-capable device.
404 *
405 * Return value: a #DfuTarget, or %NULL if @iface was not DFU-capable
406 **/
407 DfuTarget *
408 dfu_target_new (DfuDevice *device, GUsbInterface *iface)
409 {
410 DfuTargetPrivate *priv;
411 DfuTarget *target;
412 target = g_object_new (DFU_TYPE_TARGET, NULL);
413 priv = GET_PRIVATE (target);
414 priv->device = device;
415 priv->alt_idx = g_usb_interface_get_index (iface);
416 priv->alt_setting = g_usb_interface_get_alternate (iface);
417
418 /* if we try to ref the target and destroy the device */
419 g_object_add_weak_pointer (G_OBJECT (priv->device),
420 (gpointer *) &priv->device);
421
422 return target;
423 }
424
425 /**
426 * dfu_target_get_sectors:
427 * @target: a #GUsbDevice
428 *
429 * Gets the sectors exported by the device.
430 *
431 * Return value: (transfer none) (element-type DfuSector): sectors
432 **/
433 GPtrArray *
434 dfu_target_get_sectors (DfuTarget *target)
435 {
436 DfuTargetPrivate *priv = GET_PRIVATE (target);
437 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
438 return priv->sectors;
439 }
440
441 /**
442 * dfu_target_status_to_error_msg:
443 * @status: a #DfuStatus, e.g. %DFU_STATUS_ERR_ERASE
444 *
445 * Converts an enumerated value to an error description.
446 *
447 * Return value: a string
448 **/
449 static const gchar *
450 dfu_target_status_to_error_msg (DfuStatus status)
451 {
452 if (status == DFU_STATUS_OK)
453 return "No error condition is present";
454 if (status == DFU_STATUS_ERR_TARGET)
455 return "Firmware is not for designed this device";
456 if (status == DFU_STATUS_ERR_FILE)
457 return "Firmware is for this device but fails verification";
458 if (status == DFU_STATUS_ERR_WRITE)
459 return "Device is unable to write memory";
460 if (status == DFU_STATUS_ERR_ERASE)
461 return "Memory erase function failed";
462 if (status == DFU_STATUS_ERR_CHECK_ERASED)
463 return "Memory erase check failed";
464 if (status == DFU_STATUS_ERR_PROG)
465 return "Program memory function failed";
466 if (status == DFU_STATUS_ERR_VERIFY)
467 return "Programmed memory failed verification";
468 if (status == DFU_STATUS_ERR_ADDRESS)
469 return "Cannot program memory due to address out of range";
470 if (status == DFU_STATUS_ERR_NOTDONE)
471 return "Received zero-length download but data is incomplete";
472 if (status == DFU_STATUS_ERR_FIRMWARE)
473 return "Device firmware is corrupt";
474 if (status == DFU_STATUS_ERR_VENDOR)
475 return "Vendor-specific error";
476 if (status == DFU_STATUS_ERR_USBR)
477 return "Device detected unexpected USB reset signaling";
478 if (status == DFU_STATUS_ERR_POR)
479 return "Device detected unexpected power on reset";
480 if (status == DFU_STATUS_ERR_UNKNOWN)
481 return "Something unexpected went wrong";
482 if (status == DFU_STATUS_ERR_STALLDPKT)
483 return "Device stalled an unexpected request";
484 return NULL;
485 }
486
487 static gboolean
488 dfu_target_check_status (DfuTarget *target,
489 GCancellable *cancellable,
490 GError **error)
491 {
492 DfuTargetPrivate *priv = GET_PRIVATE (target);
493 DfuStatus status;
494
495 /* get the status */
496 if (!dfu_device_refresh (priv->device, cancellable, error))
497 return FALSE;
498
499 /* wait for dfuDNBUSY to not be set */
500 if (dfu_device_has_dfuse_support (priv->device)) {
501 while (dfu_device_get_state (priv->device) == DFU_STATE_DFU_DNBUSY) {
502 g_debug ("waiting for DFU_STATE_DFU_DNBUSY to clear");
503 g_usleep (dfu_device_get_download_timeout (priv->device) * 1000);
504 if (!dfu_device_refresh (priv->device, cancellable, error))
505 return FALSE;
506 }
507 }
508
509 /* not in an error state */
510 if (dfu_device_get_state (priv->device) != DFU_STATE_DFU_ERROR)
511 return TRUE;
512
513 /* DfuSe-specific long errors */
514 status = dfu_device_get_status (priv->device);
515 if (dfu_device_has_dfuse_support (priv->device)) {
516 if (status == DFU_STATUS_ERR_VENDOR) {
517 g_set_error (error,
518 FWUPD_ERROR,
519 FWUPD_ERROR_NOT_SUPPORTED,
520 "Read protection is active");
521 return FALSE;
522 }
523 if (status == DFU_STATUS_ERR_TARGET) {
524 g_set_error (error,
525 FWUPD_ERROR,
526 FWUPD_ERROR_NOT_SUPPORTED,
527 "Address is wrong or unsupported");
528 return FALSE;
529 }
530 }
531
532 /* use a proper error description */
533 g_set_error_literal (error,
534 FWUPD_ERROR,
535 FWUPD_ERROR_NOT_SUPPORTED,
536 dfu_target_status_to_error_msg (status));
537 return FALSE;
538 }
539
540 /**
541 * dfu_target_use_alt_setting:
542 * @target: a #DfuTarget
543 * @error: a #GError, or %NULL
544 *
545 * Opens a DFU-capable target.
546 *
547 * Return value: %TRUE for success
548 **/
549 static gboolean
550 dfu_target_use_alt_setting (DfuTarget *target, GError **error)
551 {
552 DfuTargetPrivate *priv = GET_PRIVATE (target);
553 GUsbDevice *dev;
554 g_autoptr(GError) error_local = NULL;
555
556 g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
557 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
558
559 /* ensure interface is claimed */
560 if (!dfu_device_ensure_interface (priv->device, NULL, error))
561 return FALSE;
562
563 /* use the correct setting */
564 dev = dfu_device_get_usb_dev (priv->device);
565 if (dfu_device_get_mode (priv->device) == DFU_MODE_DFU) {
566 if (!g_usb_device_set_interface_alt (dev,
567 (gint) dfu_device_get_interface (priv->device),
568 (gint) priv->alt_setting,
569 &error_local)) {
570 g_set_error (error,
571 FWUPD_ERROR,
572 FWUPD_ERROR_NOT_SUPPORTED,
573 "cannot set alternate setting 0x%02x on interface %i: %s",
574 priv->alt_setting,
575 dfu_device_get_interface (priv->device),
576 error_local->message);
577 return FALSE;
578 }
579 }
580
581 return TRUE;
582 }
583
584 /**
585 * dfu_target_setup:
586 * @target: a #DfuTarget
587 * @error: a #GError, or %NULL
588 *
589 * Opens a DFU-capable target.
590 *
591 * Return value: %TRUE for success
592 **/
593 static gboolean
594 dfu_target_setup (DfuTarget *target, GError **error)
595 {
596 DfuTargetPrivate *priv = GET_PRIVATE (target);
597
598 g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
599 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
600
601 /* already done */
602 if (priv->done_setup)
603 return TRUE;
604
605 /* get string */
606 if (priv->alt_idx != 0x00) {
607 GUsbDevice *dev;
608 dev = dfu_device_get_usb_dev (priv->device);
609 priv->alt_name =
610 g_usb_device_get_string_descriptor (dev,
611 priv->alt_idx,
612 NULL);
613 }
614
615 /* parse the DfuSe format according to UM0424 */
616 if (!dfu_target_parse_sectors (target,
617 priv->alt_name,
618 error))
619 return FALSE;
620
621 /* add a dummy entry */
622 if (priv->sectors->len == 0) {
623 DfuSector *sector;
624 sector = dfu_sector_new (0x0, /* addr */
625 0x0, /* size */
626 0x0, /* size_left */
627 0x0, /* zone */
628 0x0, /* number */
629 DFU_SECTOR_CAP_READABLE |
630 DFU_SECTOR_CAP_WRITEABLE);
631 g_debug ("no UM0424 sector description in %s", priv->alt_name);
632 g_ptr_array_add (priv->sectors, sector);
633 }
634
635 priv->done_setup = TRUE;
636 return TRUE;
637 }
638
639 gboolean
640 dfu_target_download_chunk (DfuTarget *target, guint8 index, GBytes *bytes,
641 GCancellable *cancellable, GError **error)
642 {
643 DfuTargetPrivate *priv = GET_PRIVATE (target);
644 g_autoptr(GError) error_local = NULL;
645 gsize actual_length;
646
647 if (!g_usb_device_control_transfer (dfu_device_get_usb_dev (priv->device),
648 G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE,
649 G_USB_DEVICE_REQUEST_TYPE_CLASS,
650 G_USB_DEVICE_RECIPIENT_INTERFACE,
651 DFU_REQUEST_DNLOAD,
652 index,
653 dfu_device_get_interface (priv->device),
654 (guint8 *) g_bytes_get_data (bytes, NULL),
655 g_bytes_get_size (bytes),
656 &actual_length,
657 dfu_device_get_timeout (priv->device),
658 cancellable,
659 &error_local)) {
660 /* refresh the error code */
661 dfu_device_error_fixup (priv->device, cancellable, &error_local);
662 g_set_error (error,
663 FWUPD_ERROR,
664 FWUPD_ERROR_NOT_SUPPORTED,
665 "cannot download data: %s",
666 error_local->message);
667 return FALSE;
668 }
669
670 /* for ST devices, the action only occurs when we do GetStatus */
671 if (!dfu_device_refresh (priv->device, cancellable, error))
672 return FALSE;
673
674 /* give the target a chance to update */
675 g_usleep (dfu_device_get_download_timeout (priv->device) * 1000);
676
677 g_assert (actual_length == g_bytes_get_size (bytes));
678 return TRUE;
679 }
680
681 /**
682 * dfu_target_set_address:
683 * @target: a #DfuTarget
684 * @address: memory address
685 * @cancellable: a #GCancellable, or %NULL
686 * @error: a #GError, or %NULL
687 *
688 * Sets the address used for the next download or upload request.
689 *
690 * IMPORTANT: This only works on DfuSe-capable devices from ST.
691 *
692 * Return value: %TRUE for success
693 **/
694 static gboolean
695 dfu_target_set_address (DfuTarget *target,
696 guint32 address,
697 GCancellable *cancellable,
698 GError **error)
699 {
700 DfuTargetPrivate *priv = GET_PRIVATE (target);
701 GBytes *data_in;
702 guint8 buf[5];
703
704 /* invalid */
705 if (!dfu_device_has_dfuse_support (priv->device)) {
706 g_set_error_literal (error,
707 FWUPD_ERROR,
708 FWUPD_ERROR_NOT_SUPPORTED,
709 "only supported for DfuSe targets");
710 return FALSE;
711 }
712
713 /* format buffer */
714 buf[0] = DFU_CMD_DFUSE_SET_ADDRESS_POINTER;
715 memcpy (buf + 1, &address, 4);
716 data_in = g_bytes_new_static (buf, sizeof(buf));
717 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
718 g_prefix_error (error, "cannot set address 0x%x: ", address);
719 return FALSE;
720 }
721
722 /* 2nd check required to get error code */
723 g_debug ("doing actual check status");
724 return dfu_target_check_status (target, cancellable, error);
725 }
726
727 /**
728 * dfu_target_erase_address:
729 * @target: a #DfuTarget
730 * @address: memory address
731 * @cancellable: a #GCancellable, or %NULL
732 * @error: a #GError, or %NULL
733 *
734 * Erases a memory sector at a given address.
735 *
736 * IMPORTANT: This only works on DfuSe-capable devices from ST.
737 *
738 * Return value: %TRUE for success
739 **/
740 static gboolean
741 dfu_target_erase_address (DfuTarget *target,
742 guint32 address,
743 GCancellable *cancellable,
744 GError **error)
745 {
746 DfuTargetPrivate *priv = GET_PRIVATE (target);
747 GBytes *data_in;
748 guint8 buf[5];
749
750 /* invalid */
751 if (!dfu_device_has_dfuse_support (priv->device)) {
752 g_set_error_literal (error,
753 FWUPD_ERROR,
754 FWUPD_ERROR_NOT_SUPPORTED,
755 "only supported for DfuSe targets");
756 return FALSE;
757 }
758
759 /* format buffer */
760 buf[0] = DFU_CMD_DFUSE_ERASE;
761 memcpy (buf + 1, &address, 4);
762 data_in = g_bytes_new_static (buf, sizeof(buf));
763 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
764 g_prefix_error (error, "cannot erase address 0x%x: ", address);
765 return FALSE;
766 }
767
768 /* 2nd check required to get error code */
769 g_debug ("doing actual check status");
770 return dfu_target_check_status (target, cancellable, error);
771 }
772
773 #if 0
774
775 /**
776 * dfu_target_mass_erase:
777 * @target: a #DfuTarget
778 * @cancellable: a #GCancellable, or %NULL
779 * @error: a #GError, or %NULL
780 *
781 * Mass erases the device clearing all SRAM and EEPROM memory.
782 *
783 * This may not be supported on all devices, a better way of doing this action
784 * is to enable read protection and then doing dfu_target_read_unprotect().
785 *
786 * IMPORTANT: This only works on DfuSe-capable devices from ST.
787 *
788 * Return value: %TRUE for success
789 **/
790 static gboolean
791 dfu_target_mass_erase (DfuTarget *target,
792 GCancellable *cancellable,
793 GError **error)
794 {
795 DfuTargetPrivate *priv = GET_PRIVATE (target);
796 GBytes *data_in;
797 guint8 buf[1];
798
799 /* invalid */
800 if (!dfu_device_has_dfuse_support (priv->device)) {
801 g_set_error_literal (error,
802 FWUPD_ERROR,
803 FWUPD_ERROR_NOT_SUPPORTED,
804 "only supported for DfuSe targets");
805 return FALSE;
806 }
807
808 /* format buffer */
809 buf[0] = DFU_CMD_DFUSE_ERASE;
810 data_in = g_bytes_new_static (buf, sizeof(buf));
811 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
812 g_prefix_error (error, "cannot mass-erase: ");
813 return FALSE;
814 }
815
816 /* 2nd check required to get error code */
817 return dfu_target_check_status (target, cancellable, error);
818 }
819
820 /**
821 * dfu_target_read_unprotect:
822 * @target: a #DfuTarget
823 * @cancellable: a #GCancellable, or %NULL
824 * @error: a #GError, or %NULL
825 *
826 * Turns of read protection on the device, clearing all SRAM and EEPROM memory.
827 *
828 * IMPORTANT: This only works on DfuSe-capable devices from ST.
829 *
830 * Return value: %TRUE for success
831 **/
832 static gboolean
833 dfu_target_read_unprotect (DfuTarget *target,
834 GCancellable *cancellable,
835 GError **error)
836 {
837 DfuTargetPrivate *priv = GET_PRIVATE (target);
838 GBytes *data_in;
839 guint8 buf[5];
840
841 /* invalid */
842 if (!dfu_device_has_dfuse_support (priv->device)) {
843 g_set_error_literal (error,
844 FWUPD_ERROR,
845 FWUPD_ERROR_NOT_SUPPORTED,
846 "only supported for DfuSe targets");
847 return FALSE;
848 }
849
850 /* format buffer */
851 buf[0] = DFU_CMD_DFUSE_READ_UNPROTECT;
852 memcpy (buf + 1, &address, 4);
853 data_in = g_bytes_new_static (buf, sizeof(buf));
854 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
855 g_prefix_error (error, "cannot read-unprotect: ");
856 return FALSE;
857 }
858
859 /* for ST devices, the action only occurs when we do GetStatus */
860 return dfu_target_check_status (target, cancellable, error);
861 }
862
863 #endif
864
865 GBytes *
866 dfu_target_upload_chunk (DfuTarget *target, guint8 index,
867 GCancellable *cancellable, GError **error)
868 {
869 DfuTargetPrivate *priv = GET_PRIVATE (target);
870 g_autoptr(GError) error_local = NULL;
871 guint8 *buf;
872 gsize actual_length;
873 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
874
875 buf = g_new0 (guint8, transfer_size);
876 if (!g_usb_device_control_transfer (dfu_device_get_usb_dev (priv->device),
877 G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST,
878 G_USB_DEVICE_REQUEST_TYPE_CLASS,
879 G_USB_DEVICE_RECIPIENT_INTERFACE,
880 DFU_REQUEST_UPLOAD,
881 index,
882 dfu_device_get_interface (priv->device),
883 buf, (gsize) transfer_size,
884 &actual_length,
885 dfu_device_get_timeout (priv->device),
886 cancellable,
887 &error_local)) {
888 /* refresh the error code */
889 dfu_device_error_fixup (priv->device, cancellable, &error_local);
890 g_set_error (error,
891 FWUPD_ERROR,
892 FWUPD_ERROR_NOT_SUPPORTED,
893 "cannot upload data: %s",
894 error_local->message);
895 return NULL;
896 }
897
898 return g_bytes_new_take (buf, actual_length);
899 }
900
901 static void
902 dfu_target_set_action (DfuTarget *target, FwupdStatus action)
903 {
904 DfuTargetPrivate *priv = GET_PRIVATE (target);
905
906 /* unchanged */
907 if (priv->old_action == action)
908 return;
909 if (priv->old_action != FWUPD_STATUS_IDLE &&
910 action != FWUPD_STATUS_IDLE) {
911 g_debug ("ignoring action %s as %s already set and not idle",
912 fwupd_status_to_string (action),
913 fwupd_status_to_string (priv->old_action));
914 return;
915 }
916 g_debug ("setting action %s", fwupd_status_to_string (action));
917 g_signal_emit (target, signals[SIGNAL_ACTION_CHANGED], 0, action);
918 priv->old_action = action;
919 }
920
921 static void
922 dfu_target_set_percentage_raw (DfuTarget *target, guint percentage)
923 {
924 DfuTargetPrivate *priv = GET_PRIVATE (target);
925 if (percentage == priv->old_percentage)
926 return;
927 g_debug ("setting percentage %u%% of %s",
928 percentage, fwupd_status_to_string (priv->old_action));
929 g_signal_emit (target,
930 signals[SIGNAL_PERCENTAGE_CHANGED],
931 0, percentage);
932 priv->old_percentage = percentage;
933 }
934
935 static void
936 dfu_target_set_percentage (DfuTarget *target, guint value, guint total)
937 {
938 guint percentage;
939
940 g_return_if_fail (total > 0);
941
942 percentage = (value * 100) / total;
943 if (percentage >= 100)
944 return;
945 dfu_target_set_percentage_raw (target, percentage);
946 }
947
948 static GBytes *
949 _g_bytes_array_join (GPtrArray *chunks)
950 {
951 gsize total_size = 0;
952 guint32 offset = 0;
953 guint8 *buffer;
954
955 /* get the size of all the chunks */
956 for (guint i = 0; i < chunks->len; i++) {
957 GBytes *chunk_tmp = g_ptr_array_index (chunks, i);
958 total_size += g_bytes_get_size (chunk_tmp);
959 }
960
961 /* copy them into a buffer */
962 buffer = g_malloc0 (total_size);
963 for (guint i = 0; i < chunks->len; i++) {
964 const guint8 *chunk_data;
965 gsize chunk_size = 0;
966 GBytes *chunk_tmp = g_ptr_array_index (chunks, i);
967 chunk_data = g_bytes_get_data (chunk_tmp, &chunk_size);
968 if (chunk_size == 0)
969 continue;
970 memcpy (buffer + offset, chunk_data, chunk_size);
971 offset += chunk_size;
972 }
973 return g_bytes_new_take (buffer, total_size);
974 }
975
976 static DfuElement *
977 dfu_target_upload_element_dfuse (DfuTarget *target,
978 guint32 address,
979 gsize expected_size,
980 gsize maximum_size,
981 GCancellable *cancellable,
982 GError **error)
983 {
984 DfuTargetPrivate *priv = GET_PRIVATE (target);
985 DfuSector *sector;
986 DfuElement *element = NULL;
987 GBytes *chunk_tmp;
988 guint32 offset = address;
989 guint percentage_size = expected_size > 0 ? expected_size : maximum_size;
990 gsize total_size = 0;
991 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
992 g_autoptr(GBytes) contents = NULL;
993 g_autoptr(GBytes) contents_truncated = NULL;
994 g_autoptr(GPtrArray) chunks = NULL;
995
996 /* for DfuSe devices we need to handle the address manually */
997 sector = dfu_target_get_sector_for_addr (target, offset);
998 if (sector == NULL) {
999 g_set_error (error,
1000 FWUPD_ERROR,
1001 FWUPD_ERROR_NOT_SUPPORTED,
1002 "no memory sector at 0x%04x",
1003 (guint) offset);
1004 return NULL;
1005 }
1006 g_debug ("using sector %u for read of %x",
1007 dfu_sector_get_id (sector),
1008 offset);
1009 if (!dfu_sector_has_cap (sector, DFU_SECTOR_CAP_READABLE)) {
1010 g_set_error (error,
1011 FWUPD_ERROR,
1012 FWUPD_ERROR_NOT_SUPPORTED,
1013 "memory sector at 0x%04x is not readble",
1014 (guint) offset);
1015 return NULL;
1016 }
1017
1018 /* update UI */
1019 dfu_target_set_action (target, FWUPD_STATUS_DEVICE_READ);
1020
1021 /* manually set the sector address */
1022 g_debug ("setting DfuSe address to 0x%04x", (guint) offset);
1023 if (!dfu_target_set_address (target,
1024 offset,
1025 cancellable,
1026 error))
1027 return NULL;
1028
1029 /* abort back to IDLE */
1030 if (!dfu_device_abort (priv->device, cancellable, error))
1031 return NULL;
1032
1033 /* get all the chunks from the hardware */
1034 chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
1035 for (guint idx = 0; idx < G_MAXUINT16; idx++) {
1036 guint32 chunk_size;
1037
1038 /* read chunk of data -- ST uses wBlockNum=0 for DfuSe commands
1039 * and wBlockNum=1 is reserved */
1040 chunk_tmp = dfu_target_upload_chunk (target,
1041 (guint8) (idx + 2),
1042 cancellable,
1043 error);
1044 if (chunk_tmp == NULL)
1045 return NULL;
1046
1047 /* add to array */
1048 chunk_size = (guint32) g_bytes_get_size (chunk_tmp);
1049 g_debug ("got #%04x chunk @0x%x of size %" G_GUINT32_FORMAT,
1050 idx, offset, chunk_size);
1051 g_ptr_array_add (chunks, chunk_tmp);
1052 total_size += chunk_size;
1053 offset += chunk_size;
1054
1055 /* update UI */
1056 if (chunk_size > 0)
1057 dfu_target_set_percentage (target, total_size, percentage_size);
1058
1059 /* detect short write as EOF */
1060 if (chunk_size < transfer_size)
1061 break;
1062
1063 /* more data than we needed */
1064 if (maximum_size > 0 && total_size > maximum_size)
1065 break;
1066 }
1067
1068 /* abort back to IDLE */
1069 if (dfu_device_has_dfuse_support (priv->device)) {
1070 if (!dfu_device_abort (priv->device, cancellable, error))
1071 return NULL;
1072 }
1073
1074 /* check final size */
1075 if (expected_size > 0) {
1076 if (total_size < expected_size) {
1077 g_set_error (error,
1078 FWUPD_ERROR,
1079 FWUPD_ERROR_INVALID_FILE,
1080 "invalid size, got %" G_GSIZE_FORMAT ", "
1081 "expected %" G_GSIZE_FORMAT ,
1082 total_size, expected_size);
1083 return NULL;
1084 }
1085 }
1086
1087 /* done */
1088 dfu_target_set_percentage_raw (target, 100);
1089 dfu_target_set_action (target, FWUPD_STATUS_IDLE);
1090
1091 /* create new image */
1092 contents = _g_bytes_array_join (chunks);
1093 if (expected_size > 0)
1094 contents_truncated = g_bytes_new_from_bytes (contents, 0, expected_size);
1095 else
1096 contents_truncated = g_bytes_ref (contents);
1097 element = dfu_element_new ();
1098 dfu_element_set_contents (element, contents_truncated);
1099 dfu_element_set_address (element, address);
1100 return element;
1101 }
1102
1103 static DfuElement *
1104 dfu_target_upload_element_dfu (DfuTarget *target,
1105 guint32 address,
1106 gsize expected_size,
1107 gsize maximum_size,
1108 GCancellable *cancellable,
1109 GError **error)
1110 {
1111 DfuTargetPrivate *priv = GET_PRIVATE (target);
1112 DfuElement *element = NULL;
1113 GBytes *chunk_tmp;
1114 guint32 offset = 0;
1115 guint percentage_size = expected_size > 0 ? expected_size : maximum_size;
1116 gsize total_size = 0;
1117 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1118 g_autoptr(GBytes) contents = NULL;
1119 g_autoptr(GPtrArray) chunks = NULL;
1120
1121 /* update UI */
1122 dfu_target_set_action (target, FWUPD_STATUS_DEVICE_READ);
1123
1124 /* get all the chunks from the hardware */
1125 chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref);
1126 for (guint idx = 0; idx < G_MAXUINT16; idx++) {
1127 guint32 chunk_size;
1128
1129 /* read chunk of data */
1130 chunk_tmp = dfu_target_upload_chunk (target,
1131 (guint8) idx,
1132 cancellable,
1133 error);
1134 if (chunk_tmp == NULL)
1135 return NULL;
1136
1137 /* keep a sum of all the chunks */
1138 chunk_size = (guint32) g_bytes_get_size (chunk_tmp);
1139 total_size += chunk_size;
1140 offset += chunk_size;
1141
1142 /* add to array */
1143 g_debug ("got #%04x chunk of size %" G_GUINT32_FORMAT,
1144 idx, chunk_size);
1145 g_ptr_array_add (chunks, chunk_tmp);
1146
1147 /* update UI */
1148 if (chunk_size > 0)
1149 dfu_target_set_percentage (target, total_size, percentage_size);
1150
1151 /* detect short write as EOF */
1152 if (chunk_size < transfer_size)
1153 break;
1154 }
1155
1156 /* check final size */
1157 if (expected_size > 0) {
1158 if (total_size != expected_size) {
1159 g_set_error (error,
1160 FWUPD_ERROR,
1161 FWUPD_ERROR_INVALID_FILE,
1162 "invalid size, got %" G_GSIZE_FORMAT ", "
1163 "expected %" G_GSIZE_FORMAT ,
1164 total_size, expected_size);
1165 return NULL;
1166 }
1167 }
1168
1169 /* done */
1170 dfu_target_set_percentage_raw (target, 100);
1171 dfu_target_set_action (target, FWUPD_STATUS_IDLE);
1172
1173 /* create new image */
1174 contents = _g_bytes_array_join (chunks);
1175 element = dfu_element_new ();
1176 dfu_element_set_contents (element, contents);
1177 return element;
1178 }
1179
1180 static DfuElement *
1181 dfu_target_upload_element (DfuTarget *target,
1182 guint32 address,
1183 gsize expected_size,
1184 gsize maximum_size,
1185 GCancellable *cancellable,
1186 GError **error)
1187 {
1188 DfuTargetPrivate *priv = GET_PRIVATE (target);
1189 if (dfu_device_has_dfuse_support (priv->device)) {
1190 return dfu_target_upload_element_dfuse (target,
1191 address,
1192 expected_size,
1193 maximum_size,
1194 cancellable,
1195 error);
1196 }
1197 return dfu_target_upload_element_dfu (target,
1198 address,
1199 expected_size,
1200 maximum_size,
1201 cancellable,
1202 error);
1203 }
1204
1205 static guint32
1206 dfu_target_get_size_of_zone (DfuTarget *target, guint16 zone)
1207 {
1208 DfuTargetPrivate *priv = GET_PRIVATE (target);
1209 guint32 len = 0;
1210 for (guint i = 0; i < priv->sectors->len; i++) {
1211 DfuSector *sector = g_ptr_array_index (priv->sectors, i);
1212 if (dfu_sector_get_zone (sector) != zone)
1213 continue;
1214 len += dfu_sector_get_size (sector);
1215 }
1216 return len;
1217 }
1218
1219 /**
1220 * dfu_target_upload:
1221 * @target: a #DfuTarget
1222 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1223 * @cancellable: a #GCancellable, or %NULL
1224 * @error: a #GError, or %NULL
1225 *
1226 * Uploads firmware from the target to the host.
1227 *
1228 * Return value: (transfer full): the uploaded image, or %NULL for error
1229 **/
1230 DfuImage *
1231 dfu_target_upload (DfuTarget *target,
1232 DfuTargetTransferFlags flags,
1233 GCancellable *cancellable,
1234 GError **error)
1235 {
1236 DfuTargetPrivate *priv = GET_PRIVATE (target);
1237 DfuSector *sector;
1238 guint16 zone_cur;
1239 guint32 zone_size = 0;
1240 guint32 zone_last = G_MAXUINT;
1241 g_autoptr(DfuImage) image = NULL;
1242
1243 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
1244 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1245
1246 /* ensure populated */
1247 if (!dfu_target_setup (target, error))
1248 return NULL;
1249
1250 /* can the target do this? */
1251 if (!dfu_device_can_upload (priv->device)) {
1252 g_set_error_literal (error,
1253 FWUPD_ERROR,
1254 FWUPD_ERROR_NOT_SUPPORTED,
1255 "target cannot do uploading");
1256 return NULL;
1257 }
1258
1259 /* use correct alt */
1260 if (!dfu_target_use_alt_setting (target, error))
1261 return NULL;
1262
1263 /* no open?! */
1264 if (priv->sectors->len == 0) {
1265 g_set_error_literal (error,
1266 FWUPD_ERROR,
1267 FWUPD_ERROR_NOT_SUPPORTED,
1268 "no sectors defined for target");
1269 return NULL;
1270 }
1271
1272 /* create a new image */
1273 image = dfu_image_new ();
1274 dfu_image_set_name (image, priv->alt_name);
1275 dfu_image_set_alt_setting (image, priv->alt_setting);
1276
1277 /* get all the sectors for the device */
1278 for (guint i = 0; i < priv->sectors->len; i++) {
1279 g_autoptr(DfuElement) element = NULL;
1280
1281 /* only upload to the start of any zone:sector */
1282 sector = g_ptr_array_index (priv->sectors, i);
1283 zone_cur = dfu_sector_get_zone (sector);
1284 if (zone_cur == zone_last)
1285 continue;
1286
1287 /* get the size of the entire continous zone */
1288 zone_size = dfu_target_get_size_of_zone (target, zone_cur);
1289 zone_last = zone_cur;
1290
1291 /* get the first element from the hardware */
1292 g_debug ("starting upload from 0x%08x (0x%04x)",
1293 dfu_sector_get_address (sector),
1294 zone_size);
1295 element = dfu_target_upload_element (target,
1296 dfu_sector_get_address (sector),
1297 0, /* expected */
1298 zone_size, /* maximum */
1299 cancellable,
1300 error);
1301 if (element == NULL)
1302 return NULL;
1303
1304 /* this element was uploaded okay */
1305 dfu_image_add_element (image, element);
1306 }
1307
1308 /* do host reset */
1309 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
1310 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
1311 if (!dfu_device_attach (priv->device, error))
1312 return NULL;
1313 }
1314
1315 /* boot to runtime */
1316 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
1317 g_debug ("booting to runtime");
1318 if (!dfu_device_wait_for_replug (priv->device,
1319 DFU_DEVICE_REPLUG_TIMEOUT,
1320 cancellable,
1321 error))
1322 return NULL;
1323 }
1324
1325 /* success */
1326 return g_object_ref (image);
1327 }
1328
1329 static gchar *
1330 _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2)
1331 {
1332 const guint8 *data1;
1333 const guint8 *data2;
1334 gsize length1;
1335 gsize length2;
1336
1337 data1 = g_bytes_get_data (bytes1, &length1);
1338 data2 = g_bytes_get_data (bytes2, &length2);
1339
1340 /* not the same length */
1341 if (length1 != length2) {
1342 return g_strdup_printf ("got %" G_GSIZE_FORMAT " bytes, "
1343 "expected %" G_GSIZE_FORMAT,
1344 length1, length2);
1345 }
1346
1347 /* return 00 01 02 03 */
1348 for (guint i = 0; i < length1; i++) {
1349 if (data1[i] != data2[i]) {
1350 return g_strdup_printf ("got 0x%02x, expected 0x%02x @ 0x%04x",
1351 data1[i], data2[i], i);
1352 }
1353 }
1354 return NULL;
1355 }
1356
1357 static gboolean
1358 dfu_target_download_element_dfu (DfuTarget *target,
1359 DfuElement *element,
1360 DfuTargetTransferFlags flags,
1361 GCancellable *cancellable,
1362 GError **error)
1363 {
1364 DfuTargetPrivate *priv = GET_PRIVATE (target);
1365 GBytes *bytes;
1366 guint nr_chunks;
1367 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1368
1369 /* round up as we have to transfer incomplete blocks */
1370 bytes = dfu_element_get_contents (element);
1371 nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) /
1372 (gdouble) transfer_size);
1373 if (nr_chunks == 0) {
1374 g_set_error_literal (error,
1375 FWUPD_ERROR,
1376 FWUPD_ERROR_INVALID_FILE,
1377 "zero-length firmware");
1378 return FALSE;
1379 }
1380 dfu_target_set_action (target, FWUPD_STATUS_DEVICE_WRITE);
1381 for (guint i = 0; i < nr_chunks + 1; i++) {
1382 gsize length;
1383 guint32 offset;
1384 g_autoptr(GBytes) bytes_tmp = NULL;
1385
1386 /* caclulate the offset into the element data */
1387 offset = i * transfer_size;
1388
1389 /* we have to write one final zero-sized chunk for EOF */
1390 if (i < nr_chunks) {
1391 length = g_bytes_get_size (bytes) - offset;
1392 if (length > transfer_size)
1393 length = transfer_size;
1394 bytes_tmp = g_bytes_new_from_bytes (bytes, offset, length);
1395 } else {
1396 bytes_tmp = g_bytes_new (NULL, 0);
1397 }
1398 g_debug ("writing #%04x chunk of size %" G_GSIZE_FORMAT,
1399 i, g_bytes_get_size (bytes_tmp));
1400 if (!dfu_target_download_chunk (target,
1401 (guint8) i,
1402 bytes_tmp,
1403 cancellable,
1404 error))
1405 return FALSE;
1406
1407 /* update UI */
1408 dfu_target_set_percentage (target, offset, g_bytes_get_size (bytes));
1409 }
1410
1411 /* done */
1412 dfu_target_set_percentage_raw (target, 100);
1413 dfu_target_set_action (target, FWUPD_STATUS_IDLE);
1414
1415 /* success */
1416 return TRUE;
1417 }
1418
1419 static gboolean
1420 dfu_target_download_element_dfuse (DfuTarget *target,
1421 DfuElement *element,
1422 DfuTargetTransferFlags flags,
1423 GCancellable *cancellable,
1424 GError **error)
1425 {
1426 DfuTargetPrivate *priv = GET_PRIVATE (target);
1427 DfuSector *sector;
1428 GBytes *bytes;
1429 guint nr_chunks;
1430 guint zone_last = G_MAXUINT;
1431 guint16 transfer_size = dfu_device_get_transfer_size (priv->device);
1432 g_autoptr(GPtrArray) sectors_array = NULL;
1433 g_autoptr(GHashTable) sectors_hash = NULL;
1434
1435 /* round up as we have to transfer incomplete blocks */
1436 bytes = dfu_element_get_contents (element);
1437 nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) /
1438 (gdouble) transfer_size);
1439 if (nr_chunks == 0) {
1440 g_set_error_literal (error,
1441 FWUPD_ERROR,
1442 FWUPD_ERROR_INVALID_FILE,
1443 "zero-length firmware");
1444 return FALSE;
1445 }
1446
1447 /* 1st pass: work out which sectors need erasing */
1448 sectors_array = g_ptr_array_new ();
1449 sectors_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
1450 for (guint i = 0; i < nr_chunks; i++) {
1451 guint32 offset_dev;
1452
1453 /* for DfuSe devices we need to handle the erase and setting
1454 * the sectory address manually */
1455 offset_dev = dfu_element_get_address (element) + (i * transfer_size);
1456 sector = dfu_target_get_sector_for_addr (target, offset_dev);
1457 if (sector == NULL) {
1458 g_set_error (error,
1459 FWUPD_ERROR,
1460 FWUPD_ERROR_NOT_SUPPORTED,
1461 "no memory sector at 0x%04x",
1462 (guint) offset_dev);
1463 return FALSE;
1464 }
1465 if (!dfu_sector_has_cap (sector, DFU_SECTOR_CAP_WRITEABLE)) {
1466 g_set_error (error,
1467 FWUPD_ERROR,
1468 FWUPD_ERROR_NOT_SUPPORTED,
1469 "memory sector at 0x%04x is not writable",
1470 (guint) offset_dev);
1471 return FALSE;
1472 }
1473
1474 /* if it's erasable and not yet blanked */
1475 if (dfu_sector_has_cap (sector, DFU_SECTOR_CAP_ERASEABLE) &&
1476 g_hash_table_lookup (sectors_hash, sector) == NULL) {
1477 g_hash_table_insert (sectors_hash,
1478 sector,
1479 GINT_TO_POINTER (1));
1480 g_ptr_array_add (sectors_array, sector);
1481 g_debug ("marking sector 0x%04x-%04x to be erased",
1482 dfu_sector_get_address (sector),
1483 dfu_sector_get_address (sector) + dfu_sector_get_size (sector));
1484 }
1485 }
1486
1487 /* 2nd pass: actually erase sectors */
1488 dfu_target_set_action (target, FWUPD_STATUS_DEVICE_ERASE);
1489 for (guint i = 0; i < sectors_array->len; i++) {
1490 sector = g_ptr_array_index (sectors_array, i);
1491 g_debug ("erasing sector at 0x%04x",
1492 dfu_sector_get_address (sector));
1493 if (!dfu_target_erase_address (target,
1494 dfu_sector_get_address (sector),
1495 cancellable,
1496 error))
1497 return FALSE;
1498 dfu_target_set_percentage (target, i + 1, sectors_array->len);
1499 }
1500 dfu_target_set_percentage_raw (target, 100);
1501 dfu_target_set_action (target, FWUPD_STATUS_IDLE);
1502
1503 /* 3rd pass: write data */
1504 dfu_target_set_action (target, FWUPD_STATUS_DEVICE_WRITE);
1505 for (guint i = 0; i < nr_chunks; i++) {
1506 gsize length;
1507 guint32 offset;
1508 guint32 offset_dev;
1509 g_autoptr(GBytes) bytes_tmp = NULL;
1510
1511 /* caclulate the offset into the element data */
1512 offset = i * transfer_size;
1513 offset_dev = dfu_element_get_address (element) + offset;
1514
1515 /* for DfuSe devices we need to set the address manually */
1516 sector = dfu_target_get_sector_for_addr (target, offset_dev);
1517 g_assert (sector != NULL);
1518
1519 /* manually set the sector address */
1520 if (dfu_sector_get_zone (sector) != zone_last) {
1521 g_debug ("setting address to 0x%04x",
1522 (guint) offset_dev);
1523 if (!dfu_target_set_address (target,
1524 (guint32) offset_dev,
1525 cancellable,
1526 error))
1527 return FALSE;
1528 zone_last = dfu_sector_get_zone (sector);
1529 }
1530
1531 /* we have to write one final zero-sized chunk for EOF */
1532 length = g_bytes_get_size (bytes) - offset;
1533 if (length > transfer_size)
1534 length = transfer_size;
1535 bytes_tmp = g_bytes_new_from_bytes (bytes, offset, length);
1536 g_debug ("writing sector at 0x%04x (0x%" G_GSIZE_FORMAT ")",
1537 offset_dev,
1538 g_bytes_get_size (bytes_tmp));
1539 /* ST uses wBlockNum=0 for DfuSe commands and wBlockNum=1 is reserved */
1540 if (!dfu_target_download_chunk (target,
1541 (guint8) (i + 2),
1542 bytes_tmp,
1543 cancellable,
1544 error))
1545 return FALSE;
1546
1547 /* getting the status moves the state machine to DNLOAD-IDLE */
1548 if (!dfu_target_check_status (target, cancellable, error))
1549 return FALSE;
1550
1551 /* update UI */
1552 dfu_target_set_percentage (target, offset, g_bytes_get_size (bytes));
1553 }
1554
1555 /* done */
1556 dfu_target_set_percentage_raw (target, 100);
1557 dfu_target_set_action (target, FWUPD_STATUS_IDLE);
1558
1559 /* success */
1560 return TRUE;
1561 }
1562
1563 static gboolean
1564 dfu_target_download_element (DfuTarget *target,
1565 DfuElement *element,
1566 DfuTargetTransferFlags flags,
1567 GCancellable *cancellable,
1568 GError **error)
1569 {
1570 DfuTargetPrivate *priv = GET_PRIVATE (target);
1571
1572 /* DfuSe specific */
1573 if (dfu_device_has_dfuse_support (priv->device)) {
1574 if (!dfu_target_download_element_dfuse (target,
1575 element,
1576 flags,
1577 cancellable,
1578 error))
1579 return FALSE;
1580 } else {
1581 if (!dfu_target_download_element_dfu (target,
1582 element,
1583 flags,
1584 cancellable,
1585 error))
1586 return FALSE;
1587 }
1588
1589 /* verify */
1590 if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY) {
1591 GBytes *bytes;
1592 GBytes *bytes_tmp;
1593 g_autoptr(DfuElement) element_tmp = NULL;
1594 dfu_target_set_action (target, FWUPD_STATUS_DEVICE_VERIFY);
1595 bytes = dfu_element_get_contents (element);
1596 element_tmp = dfu_target_upload_element (target,
1597 dfu_element_get_address (element),
1598 g_bytes_get_size (bytes),
1599 g_bytes_get_size (bytes),
1600 cancellable,
1601 error);
1602 if (element_tmp == NULL)
1603 return FALSE;
1604 bytes_tmp = dfu_element_get_contents (element_tmp);
1605 if (g_bytes_compare (bytes_tmp, bytes) != 0) {
1606 g_autofree gchar *bytes_cmp_str = NULL;
1607 bytes_cmp_str = _g_bytes_compare_verbose (bytes_tmp, bytes);
1608 g_set_error (error,
1609 FWUPD_ERROR,
1610 FWUPD_ERROR_READ,
1611 "verify failed: %s",
1612 bytes_cmp_str);
1613 return FALSE;
1614 }
1615 dfu_target_set_action (target, FWUPD_STATUS_IDLE);
1616 }
1617
1618 return TRUE;
1619 }
1620
1621 /**
1622 * dfu_target_download:
1623 * @target: a #DfuTarget
1624 * @image: a #DfuImage
1625 * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY
1626 * @cancellable: a #GCancellable, or %NULL
1627 * @error: a #GError, or %NULL
1628 *
1629 * Downloads firmware from the host to the target, optionally verifying
1630 * the transfer.
1631 *
1632 * Return value: %TRUE for success
1633 **/
1634 gboolean
1635 dfu_target_download (DfuTarget *target, DfuImage *image,
1636 DfuTargetTransferFlags flags,
1637 GCancellable *cancellable,
1638 GError **error)
1639 {
1640 DfuTargetPrivate *priv = GET_PRIVATE (target);
1641 GPtrArray *elements;
1642 gboolean ret;
1643
1644 g_return_val_if_fail (DFU_IS_TARGET (target), FALSE);
1645 g_return_val_if_fail (DFU_IS_IMAGE (image), FALSE);
1646 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1647
1648 /* ensure populated */
1649 if (!dfu_target_setup (target, error))
1650 return FALSE;
1651
1652 /* can the target do this? */
1653 if (!dfu_device_can_download (priv->device)) {
1654 g_set_error_literal (error,
1655 FWUPD_ERROR,
1656 FWUPD_ERROR_NOT_SUPPORTED,
1657 "target cannot do downloading");
1658 return FALSE;
1659 }
1660
1661 /* use correct alt */
1662 if (!dfu_target_use_alt_setting (target, error))
1663 return FALSE;
1664
1665 /* download all elements in the image to the device */
1666 elements = dfu_image_get_elements (image);
1667 if (elements->len == 0) {
1668 g_set_error_literal (error,
1669 FWUPD_ERROR,
1670 FWUPD_ERROR_INVALID_FILE,
1671 "no image elements");
1672 return FALSE;
1673 }
1674 for (guint i = 0; i < elements->len; i++) {
1675 DfuElement *element = dfu_image_get_element (image, (guint8) i);
1676 g_debug ("downloading element at 0x%04x",
1677 dfu_element_get_address (element));
1678
1679 /* auto-detect missing firmware address -- this assumes
1680 * that the first target is the main program memory and that
1681 * there is only one element in the firmware file */
1682 if (flags & DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC &&
1683 dfu_element_get_address (element) == 0x0 &&
1684 elements->len == 1 &&
1685 priv->sectors->len > 0) {
1686 DfuSector *sector = g_ptr_array_index (priv->sectors, 0);
1687 g_debug ("fixing up firmware address from 0x0 to 0x%x",
1688 dfu_sector_get_address (sector));
1689 dfu_element_set_address (element, dfu_sector_get_address (sector));
1690 }
1691
1692 /* download to device */
1693 ret = dfu_target_download_element (target,
1694 element,
1695 flags,
1696 cancellable,
1697 error);
1698 if (!ret)
1699 return FALSE;
1700 }
1701
1702 /* attempt to switch back to runtime */
1703 if ((flags & DFU_TARGET_TRANSFER_FLAG_ATTACH) > 0 ||
1704 (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) > 0) {
1705 if (!dfu_device_attach (priv->device, error))
1706 return FALSE;
1707 }
1708
1709 /* boot to runtime */
1710 if (flags & DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME) {
1711 g_debug ("booting to runtime to set auto-boot");
1712 if (!dfu_device_wait_for_replug (priv->device,
1713 DFU_DEVICE_REPLUG_TIMEOUT,
1714 cancellable,
1715 error))
1716 return FALSE;
1717 }
1718
1719 /* success */
1720 return TRUE;
1721 }
1722
1723 #if 0
1724 static gboolean
1725 dfu_target_get_commands (DfuTarget *target,
1726 GCancellable *cancellable,
1727 GError **error)
1728 {
1729 GBytes *data_in;
1730 GBytes *data_out;
1731 guint8 buf[1];
1732
1733 /* invalid */
1734 if (!dfu_device_has_dfuse_support (priv->device)) {
1735 g_set_error_literal (error,
1736 FWUPD_ERROR,
1737 FWUPD_ERROR_NOT_SUPPORTED,
1738 "only supported for DfuSe targets");
1739 return FALSE;
1740 }
1741
1742 /* format buffer */
1743 buf[0] = DFU_CMD_DFUSE_GET_COMMAND;
1744 data_in = g_bytes_new_static (buf, sizeof(buf));
1745 if (!dfu_target_download_chunk (target, 0, data_in, cancellable, error)) {
1746 g_prefix_error (error, "cannot get DfuSe commands: ");
1747 return FALSE;
1748 }
1749
1750 /* return results */
1751 data_out = dfu_target_upload_chunk (target, 0, cancellable, error);
1752 if (data_out == NULL)
1753 return FALSE;
1754
1755 // N bytes,
1756 // each byte is the command code
1757
1758 // FIXME: parse?
1759 return TRUE;
1760 }
1761 #endif
1762
1763 /**
1764 * dfu_target_get_alt_setting:
1765 * @target: a #DfuTarget
1766 *
1767 * Gets the alternate setting to use for this interface.
1768 *
1769 * Return value: the alternative setting, typically zero
1770 **/
1771 guint8
1772 dfu_target_get_alt_setting (DfuTarget *target)
1773 {
1774 DfuTargetPrivate *priv = GET_PRIVATE (target);
1775 g_return_val_if_fail (DFU_IS_TARGET (target), 0xff);
1776 return priv->alt_setting;
1777 }
1778
1779 /**
1780 * dfu_target_get_alt_name:
1781 * @target: a #DfuTarget
1782 * @error: a #GError, or %NULL
1783 *
1784 * Gets the alternate setting name to use for this interface.
1785 *
1786 * Return value: the alternative setting name, typically %NULL
1787 **/
1788 const gchar *
1789 dfu_target_get_alt_name (DfuTarget *target, GError **error)
1790 {
1791 DfuTargetPrivate *priv = GET_PRIVATE (target);
1792 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
1793
1794 /* ensure populated */
1795 if (!dfu_target_setup (target, error))
1796 return NULL;
1797
1798 /* nothing */
1799 if (priv->alt_name == NULL) {
1800 g_set_error_literal (error,
1801 FWUPD_ERROR,
1802 FWUPD_ERROR_NOT_FOUND,
1803 "no alt-name");
1804 return NULL;
1805 }
1806
1807 return priv->alt_name;
1808 }
1809
1810 /**
1811 * dfu_target_get_alt_name_for_display:
1812 * @target: a #DfuTarget
1813 * @error: a #GError, or %NULL
1814 *
1815 * Gets the alternate setting name to use for this interface that can be
1816 * shown on the display.
1817 *
1818 * Return value: the alternative setting name
1819 **/
1820 const gchar *
1821 dfu_target_get_alt_name_for_display (DfuTarget *target, GError **error)
1822 {
1823 DfuTargetPrivate *priv = GET_PRIVATE (target);
1824 g_return_val_if_fail (DFU_IS_TARGET (target), NULL);
1825
1826 /* ensure populated */
1827 if (!dfu_target_setup (target, error))
1828 return NULL;
1829
1830 /* nothing */
1831 if (priv->alt_name_for_display == NULL) {
1832 g_set_error_literal (error,
1833 FWUPD_ERROR,
1834 FWUPD_ERROR_NOT_FOUND,
1835 "no alt-name");
1836 return NULL;
1837 }
1838
1839 return priv->alt_name_for_display;
1840 }
1841
1842 /**
1843 * dfu_target_get_cipher_kind:
1844 * @target: a #DfuTarget
1845 *
1846 * Gets the cipher used for data sent to this interface.
1847 *
1848 * Return value: the cipher, typically %DFU_CIPHER_KIND_NONE
1849 **/
1850 DfuCipherKind
1851 dfu_target_get_cipher_kind (DfuTarget *target)
1852 {
1853 DfuTargetPrivate *priv = GET_PRIVATE (target);
1854 g_return_val_if_fail (DFU_IS_TARGET (target), 0);
1855 return priv->cipher_kind;
1856 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __DFU_TARGET_H
22 #define __DFU_TARGET_H
23
24 #include <glib-object.h>
25 #include <gio/gio.h>
26 #include <gusb.h>
27
28 #include "dfu-common.h"
29 #include "dfu-image.h"
30
31 #include "fwupd-enums.h"
32
33 G_BEGIN_DECLS
34
35 #define DFU_TYPE_TARGET (dfu_target_get_type ())
36 G_DECLARE_DERIVABLE_TYPE (DfuTarget, dfu_target, DFU, TARGET, GUsbDevice)
37
38 struct _DfuTargetClass
39 {
40 GUsbDeviceClass parent_class;
41 void (*percentage_changed) (DfuTarget *target,
42 guint percentage);
43 void (*action_changed) (DfuTarget *target,
44 FwupdStatus action);
45 /*< private >*/
46 /* Padding for future expansion */
47 void (*_dfu_target_reserved1) (void);
48 void (*_dfu_target_reserved2) (void);
49 void (*_dfu_target_reserved3) (void);
50 void (*_dfu_target_reserved4) (void);
51 void (*_dfu_target_reserved5) (void);
52 void (*_dfu_target_reserved6) (void);
53 void (*_dfu_target_reserved7) (void);
54 void (*_dfu_target_reserved8) (void);
55 };
56
57 /**
58 * DfuTargetTransferFlags:
59 * @DFU_TARGET_TRANSFER_FLAG_NONE: No flags set
60 * @DFU_TARGET_TRANSFER_FLAG_VERIFY: Verify the download once complete
61 * @DFU_TARGET_TRANSFER_FLAG_DETACH: If required, detach from runtime mode
62 * @DFU_TARGET_TRANSFER_FLAG_ATTACH: Attach the device back to runtime after completion
63 * @DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME: Wait for runtime to load after completion
64 * @DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID: Allow downloading images with wildcard VIDs
65 * @DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID: Allow downloading images with wildcard PIDs
66 * @DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER: Allow any cipher kinds to be downloaded
67 * @DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC: Automatically detect the address to use
68 *
69 * The optional flags used for transfering firmware.
70 **/
71 typedef enum {
72 DFU_TARGET_TRANSFER_FLAG_NONE = 0,
73 DFU_TARGET_TRANSFER_FLAG_VERIFY = (1 << 0),
74 DFU_TARGET_TRANSFER_FLAG_DETACH = (1 << 1),
75 DFU_TARGET_TRANSFER_FLAG_ATTACH = (1 << 2),
76 DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME = (1 << 3),
77 DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID = (1 << 4),
78 DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID = (1 << 5),
79 DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER = (1 << 6),
80 DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC = (1 << 7),
81 /*< private >*/
82 DFU_TARGET_TRANSFER_FLAG_LAST
83 } DfuTargetTransferFlags;
84
85 GPtrArray *dfu_target_get_sectors (DfuTarget *target);
86 guint8 dfu_target_get_alt_setting (DfuTarget *target);
87 const gchar *dfu_target_get_alt_name (DfuTarget *target,
88 GError **error);
89 const gchar *dfu_target_get_alt_name_for_display (DfuTarget *target,
90 GError **error);
91 DfuImage *dfu_target_upload (DfuTarget *target,
92 DfuTargetTransferFlags flags,
93 GCancellable *cancellable,
94 GError **error);
95 gboolean dfu_target_download (DfuTarget *target,
96 DfuImage *image,
97 DfuTargetTransferFlags flags,
98 GCancellable *cancellable,
99 GError **error);
100 DfuCipherKind dfu_target_get_cipher_kind (DfuTarget *target);
101
102 G_END_DECLS
103
104 #endif /* __DFU_TARGET_H */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "config.h"
22
23 #include <libintl.h>
24 #include <locale.h>
25 #include <stdlib.h>
26 #include <glib/gi18n.h>
27 #include <glib-unix.h>
28 #include <appstream-glib.h>
29
30 #include "dfu-cipher-xtea.h"
31 #include "dfu-context.h"
32 #include "dfu-device-private.h"
33 #include "dfu-patch.h"
34 #include "dfu-sector.h"
35
36 #include "fu-device-locker.h"
37 #include "fu-progressbar.h"
38
39 #include "fwupd-error.h"
40
41 typedef struct {
42 GCancellable *cancellable;
43 GPtrArray *cmd_array;
44 gboolean force;
45 gchar *device_vid_pid;
46 guint16 transfer_size;
47 FuProgressbar *progressbar;
48 } DfuToolPrivate;
49
50 static void
51 dfu_tool_print_indent (const gchar *title, const gchar *message, guint indent)
52 {
53 for (gsize i = 0; i < indent; i++)
54 g_print (" ");
55 g_print ("%s:", title);
56 for (gsize i = strlen (title) + indent; i < 15; i++)
57 g_print (" ");
58 g_print ("%s\n", message);
59 }
60
61 static void
62 dfu_tool_private_free (DfuToolPrivate *priv)
63 {
64 if (priv == NULL)
65 return;
66 g_free (priv->device_vid_pid);
67 g_object_unref (priv->cancellable);
68 if (priv->cmd_array != NULL)
69 g_ptr_array_unref (priv->cmd_array);
70 g_free (priv);
71 }
72 G_DEFINE_AUTOPTR_CLEANUP_FUNC(DfuToolPrivate, dfu_tool_private_free)
73
74 typedef gboolean (*FuUtilPrivateCb) (DfuToolPrivate *util,
75 gchar **values,
76 GError **error);
77
78 typedef struct {
79 gchar *name;
80 gchar *arguments;
81 gchar *description;
82 FuUtilPrivateCb callback;
83 } FuUtilItem;
84
85 static void
86 dfu_tool_item_free (FuUtilItem *item)
87 {
88 g_free (item->name);
89 g_free (item->arguments);
90 g_free (item->description);
91 g_free (item);
92 }
93
94 static gint
95 dfu_tool_sort_command_name_cb (FuUtilItem **item1, FuUtilItem **item2)
96 {
97 return g_strcmp0 ((*item1)->name, (*item2)->name);
98 }
99
100 static void
101 dfu_tool_add (GPtrArray *array,
102 const gchar *name,
103 const gchar *arguments,
104 const gchar *description,
105 FuUtilPrivateCb callback)
106 {
107 g_auto(GStrv) names = NULL;
108
109 g_return_if_fail (name != NULL);
110 g_return_if_fail (description != NULL);
111 g_return_if_fail (callback != NULL);
112
113 /* add each one */
114 names = g_strsplit (name, ",", -1);
115 for (guint i = 0; names[i] != NULL; i++) {
116 FuUtilItem *item = g_new0 (FuUtilItem, 1);
117 item->name = g_strdup (names[i]);
118 if (i == 0) {
119 item->description = g_strdup (description);
120 } else {
121 /* TRANSLATORS: this is a command alias, e.g. 'get-devices' */
122 item->description = g_strdup_printf (_("Alias to %s"),
123 names[0]);
124 }
125 item->arguments = g_strdup (arguments);
126 item->callback = callback;
127 g_ptr_array_add (array, item);
128 }
129 }
130
131 static gchar *
132 dfu_tool_get_descriptions (GPtrArray *array)
133 {
134 gsize len;
135 const gsize max_len = 31;
136 FuUtilItem *item;
137 GString *string;
138
139 /* print each command */
140 string = g_string_new ("");
141 for (guint i = 0; i < array->len; i++) {
142 item = g_ptr_array_index (array, i);
143 g_string_append (string, " ");
144 g_string_append (string, item->name);
145 len = strlen (item->name) + 2;
146 if (item->arguments != NULL) {
147 g_string_append (string, " ");
148 g_string_append (string, item->arguments);
149 len += strlen (item->arguments) + 1;
150 }
151 if (len < max_len) {
152 for (guint j = len; j < max_len + 1; j++)
153 g_string_append_c (string, ' ');
154 g_string_append (string, item->description);
155 g_string_append_c (string, '\n');
156 } else {
157 g_string_append_c (string, '\n');
158 for (guint j = 0; j < max_len + 1; j++)
159 g_string_append_c (string, ' ');
160 g_string_append (string, item->description);
161 g_string_append_c (string, '\n');
162 }
163 }
164
165 /* remove trailing newline */
166 if (string->len > 0)
167 g_string_set_size (string, string->len - 1);
168
169 return g_string_free (string, FALSE);
170 }
171
172 static gboolean
173 dfu_tool_run (DfuToolPrivate *priv,
174 const gchar *command,
175 gchar **values,
176 GError **error)
177 {
178 /* find command */
179 for (guint i = 0; i < priv->cmd_array->len; i++) {
180 FuUtilItem *item = g_ptr_array_index (priv->cmd_array, i);
181 if (g_strcmp0 (item->name, command) == 0)
182 return item->callback (priv, values, error);
183 }
184
185 /* not found */
186 g_set_error_literal (error,
187 FWUPD_ERROR,
188 FWUPD_ERROR_INTERNAL,
189 /* TRANSLATORS: error message */
190 _("Command not found"));
191 return FALSE;
192 }
193
194 static DfuDevice *
195 dfu_tool_get_defalt_device (DfuToolPrivate *priv, GError **error)
196 {
197 DfuDevice *device;
198 g_autoptr(DfuContext) dfu_context = NULL;
199
200 /* get all the DFU devices */
201 dfu_context = dfu_context_new ();
202 dfu_context_enumerate (dfu_context, NULL);
203
204 /* we specified it manually */
205 if (priv->device_vid_pid != NULL) {
206 gchar *tmp;
207 guint64 pid;
208 guint64 vid;
209
210 /* parse */
211 vid = g_ascii_strtoull (priv->device_vid_pid, &tmp, 16);
212 if (vid == 0 || vid > G_MAXUINT16) {
213 g_set_error_literal (error,
214 FWUPD_ERROR,
215 FWUPD_ERROR_INTERNAL,
216 "Invalid format of VID:PID");
217 return NULL;
218 }
219 if (tmp[0] != ':') {
220 g_set_error_literal (error,
221 FWUPD_ERROR,
222 FWUPD_ERROR_INTERNAL,
223 "Invalid format of VID:PID");
224 return NULL;
225 }
226 pid = g_ascii_strtoull (tmp + 1, NULL, 16);
227 if (pid == 0 || pid > G_MAXUINT16) {
228 g_set_error_literal (error,
229 FWUPD_ERROR,
230 FWUPD_ERROR_INTERNAL,
231 "Invalid format of VID:PID");
232 return NULL;
233 }
234
235 /* find device */
236 device = dfu_context_get_device_by_vid_pid (dfu_context,
237 (guint16) vid,
238 (guint16) pid,
239 error);
240 if (device == NULL)
241 return NULL;
242 } else {
243 /* auto-detect first device */
244 device = dfu_context_get_device_default (dfu_context, error);
245 if (device == NULL)
246 return NULL;
247 }
248
249 /* this has to be added to the device so we can deal with detach */
250 g_object_set_data_full (G_OBJECT (device), "DfuContext",
251 g_object_ref (dfu_context),
252 (GDestroyNotify) g_object_unref);
253 return device;
254 }
255
256 static gboolean
257 dfu_tool_set_vendor (DfuToolPrivate *priv, gchar **values, GError **error)
258 {
259 guint64 tmp;
260 g_autoptr(DfuFirmware) firmware = NULL;
261 g_autoptr(GFile) file = NULL;
262
263 /* check args */
264 if (g_strv_length (values) < 2) {
265 g_set_error_literal (error,
266 FWUPD_ERROR,
267 FWUPD_ERROR_INTERNAL,
268 "Invalid arguments, expected FILE VID"
269 " -- e.g. `firmware.dfu 273f");
270 return FALSE;
271 }
272
273 /* open */
274 file = g_file_new_for_path (values[0]);
275 firmware = dfu_firmware_new ();
276 if (!dfu_firmware_parse_file (firmware, file,
277 DFU_FIRMWARE_PARSE_FLAG_NONE,
278 priv->cancellable,
279 error)) {
280 return FALSE;
281 }
282
283 /* parse VID */
284 tmp = g_ascii_strtoull (values[1], NULL, 16);
285 if (tmp == 0 || tmp > G_MAXUINT16) {
286 g_set_error (error,
287 FWUPD_ERROR,
288 FWUPD_ERROR_INTERNAL,
289 "Failed to parse VID '%s'",
290 values[1]);
291 return FALSE;
292 }
293 dfu_firmware_set_vid (firmware, (guint16) tmp);
294
295 /* write out new file */
296 return dfu_firmware_write_file (firmware,
297 file,
298 priv->cancellable,
299 error);
300 }
301
302 static gboolean
303 dfu_tool_set_product (DfuToolPrivate *priv, gchar **values, GError **error)
304 {
305 guint64 tmp;
306 g_autoptr(DfuFirmware) firmware = NULL;
307 g_autoptr(GFile) file = NULL;
308
309 /* check args */
310 if (g_strv_length (values) < 2) {
311 g_set_error_literal (error,
312 FWUPD_ERROR,
313 FWUPD_ERROR_INTERNAL,
314 "Invalid arguments, expected FILE PID"
315 " -- e.g. `firmware.dfu 1004");
316 return FALSE;
317 }
318
319 /* open */
320 file = g_file_new_for_path (values[0]);
321 firmware = dfu_firmware_new ();
322 if (!dfu_firmware_parse_file (firmware, file,
323 DFU_FIRMWARE_PARSE_FLAG_NONE,
324 priv->cancellable,
325 error)) {
326 return FALSE;
327 }
328
329 /* parse VID */
330 tmp = g_ascii_strtoull (values[1], NULL, 16);
331 if (tmp == 0 || tmp > G_MAXUINT16) {
332 g_set_error (error,
333 FWUPD_ERROR,
334 FWUPD_ERROR_INTERNAL,
335 "Failed to parse PID '%s'", values[1]);
336 return FALSE;
337 }
338 dfu_firmware_set_pid (firmware, (guint16) tmp);
339
340 /* write out new file */
341 return dfu_firmware_write_file (firmware,
342 file,
343 priv->cancellable,
344 error);
345 }
346
347 static guint16
348 dfu_tool_parse_release_uint16 (const gchar *version, GError **error)
349 {
350 gchar *endptr = NULL;
351 guint64 tmp_lsb, tmp_msb;
352 g_auto(GStrv) split = g_strsplit (version, ".", -1);
353
354 /* check if valid */
355 if (g_strv_length (split) != 2) {
356 g_set_error_literal (error,
357 FWUPD_ERROR,
358 FWUPD_ERROR_INTERNAL,
359 "invalid format, expected 'major.minor'");
360 return 0xffff;
361 }
362
363 /* parse MSB & LSB */
364 tmp_msb = g_ascii_strtoull (split[0], &endptr, 10);
365 if (tmp_msb > 0xff || endptr[0] != '\0') {
366 g_set_error (error,
367 FWUPD_ERROR,
368 FWUPD_ERROR_INTERNAL,
369 "Failed to parse version '%s'",
370 version);
371 return 0xffff;
372 }
373 tmp_lsb = g_ascii_strtoull (split[1], &endptr, 10);
374 if (tmp_lsb > 0xff || endptr[0] != '\0') {
375 g_set_error (error,
376 FWUPD_ERROR,
377 FWUPD_ERROR_INTERNAL,
378 "Failed to parse version '%s'",
379 version);
380 return 0xffff;
381 }
382 return (tmp_msb << 8) + tmp_lsb;
383 }
384
385 static gboolean
386 dfu_tool_set_release (DfuToolPrivate *priv, gchar **values, GError **error)
387 {
388 gchar *endptr = NULL;
389 guint64 tmp;
390 g_autoptr(DfuFirmware) firmware = NULL;
391 g_autoptr(GFile) file = NULL;
392
393 /* check args */
394 if (g_strv_length (values) < 2) {
395 g_set_error_literal (error,
396 FWUPD_ERROR,
397 FWUPD_ERROR_INTERNAL,
398 "Invalid arguments, expected FILE RELEASE"
399 " -- e.g. `firmware.dfu ffff");
400 return FALSE;
401 }
402
403 /* open */
404 file = g_file_new_for_path (values[0]);
405 firmware = dfu_firmware_new ();
406 if (!dfu_firmware_parse_file (firmware, file,
407 DFU_FIRMWARE_PARSE_FLAG_NONE,
408 priv->cancellable,
409 error)) {
410 return FALSE;
411 }
412
413 /* parse release */
414 tmp = g_ascii_strtoull (values[1], &endptr, 16);
415 if (tmp > G_MAXUINT16 || endptr[0] != '\0') {
416 tmp = dfu_tool_parse_release_uint16 (values[1], error);
417 if (tmp == 0xffff)
418 return FALSE;
419 }
420 dfu_firmware_set_release (firmware, (guint16) tmp);
421
422 /* write out new file */
423 return dfu_firmware_write_file (firmware,
424 file,
425 priv->cancellable,
426 error);
427 }
428
429 static GBytes *
430 dfu_tool_parse_hex_string (const gchar *val, GError **error)
431 {
432 gsize result_size;
433 g_autofree guint8 *result = NULL;
434
435 /* sanity check */
436 if (val == NULL) {
437 g_set_error_literal (error,
438 FWUPD_ERROR,
439 FWUPD_ERROR_INTERNAL,
440 "nothing to parse");
441 return NULL;
442 }
443
444 /* parse each hex byte */
445 result_size = strlen (val) / 2;
446 result = g_malloc (result_size);
447 for (guint i = 0; i < result_size; i++) {
448 gchar buf[3] = { "xx" };
449 gchar *endptr = NULL;
450 guint64 tmp;
451
452 /* copy two bytes and parse as hex */
453 memcpy (buf, val + (i * 2), 2);
454 tmp = g_ascii_strtoull (buf, &endptr, 16);
455 if (tmp > 0xff || endptr[0] != '\0') {
456 g_set_error (error,
457 FWUPD_ERROR,
458 FWUPD_ERROR_INTERNAL,
459 "failed to parse '%s'", val);
460 return NULL;
461 }
462 result[i] = tmp;
463 }
464 return g_bytes_new (result, result_size);
465 }
466
467 static guint
468 dfu_tool_bytes_replace (GBytes *data, GBytes *search, GBytes *replace)
469 {
470 gsize data_sz;
471 gsize replace_sz;
472 gsize search_sz;
473 guint8 *data_buf;
474 guint8 *replace_buf;
475 guint8 *search_buf;
476 guint cnt = 0;
477
478 data_buf = (gpointer) g_bytes_get_data (data, &data_sz);
479 search_buf = (gpointer) g_bytes_get_data (search, &search_sz);
480 replace_buf = (gpointer) g_bytes_get_data (replace, &replace_sz);
481
482 g_return_val_if_fail (search_sz == replace_sz, FALSE);
483
484 /* find and replace each one */
485 for (gsize i = 0; i < data_sz - search_sz; i++) {
486 if (memcmp (data_buf + i, search_buf, search_sz) == 0) {
487 g_print ("Replacing %" G_GSIZE_FORMAT " bytes @0x%04x\n",
488 replace_sz, (guint) i);
489 memcpy (data_buf + i, replace_buf, replace_sz);
490 i += replace_sz;
491 cnt++;
492 }
493 }
494 return cnt;
495 }
496
497 static gboolean
498 dfu_tool_patch_dump (DfuToolPrivate *priv, gchar **values, GError **error)
499 {
500 gsize sz = 0;
501 g_autofree gchar *data = NULL;
502 g_autofree gchar *str = NULL;
503 g_autoptr(DfuPatch) patch = NULL;
504 g_autoptr(GBytes) blob = NULL;
505
506 if (g_strv_length (values) != 1) {
507 g_set_error_literal (error,
508 FWUPD_ERROR,
509 FWUPD_ERROR_INTERNAL,
510 "Invalid arguments, expected FILE.bdiff");
511 return FALSE;
512 }
513
514 /* load file */
515 if (!g_file_get_contents (values[0], &data, &sz, error))
516 return FALSE;
517 blob = g_bytes_new (data, sz);
518
519 /* dump the patch to disk */
520 patch = dfu_patch_new ();
521 if (!dfu_patch_import (patch, blob, error))
522 return FALSE;
523 str = dfu_patch_to_string (patch);
524 g_print ("%s\n", str);
525
526 /* success */
527 return TRUE;
528 }
529
530 static gboolean
531 dfu_tool_patch_apply (DfuToolPrivate *priv, gchar **values, GError **error)
532 {
533 DfuPatchApplyFlags flags = DFU_PATCH_APPLY_FLAG_NONE;
534 const gchar *data_new;
535 gsize sz_diff = 0;
536 gsize sz_new = 0;
537 gsize sz_old = 0;
538 g_autofree gchar *data_diff = NULL;
539 g_autofree gchar *data_old = NULL;
540 g_autoptr(DfuPatch) patch = NULL;
541 g_autoptr(GBytes) blob_diff = NULL;
542 g_autoptr(GBytes) blob_new = NULL;
543 g_autoptr(GBytes) blob_old = NULL;
544
545 if (g_strv_length (values) != 3) {
546 g_set_error_literal (error,
547 FWUPD_ERROR,
548 FWUPD_ERROR_INTERNAL,
549 "Invalid arguments, expected OLD.bin OUT.bdiff NEW.bin");
550 return FALSE;
551 }
552
553 /* allow the user to shoot themselves in the foot */
554 if (priv->force)
555 flags |= DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM;
556
557 if (!g_file_get_contents (values[0], &data_old, &sz_old, error))
558 return FALSE;
559 blob_old = g_bytes_new (data_old, sz_old);
560 if (!g_file_get_contents (values[1], &data_diff, &sz_diff, error))
561 return FALSE;
562 blob_diff = g_bytes_new (data_diff, sz_diff);
563 patch = dfu_patch_new ();
564 if (!dfu_patch_import (patch, blob_diff, error))
565 return FALSE;
566 blob_new = dfu_patch_apply (patch, blob_old, flags, error);
567 if (blob_new == NULL)
568 return FALSE;
569
570 /* save to disk */
571 data_new = g_bytes_get_data (blob_new, &sz_new);
572 return g_file_set_contents (values[2], data_new, sz_new, error);
573 }
574
575 static gboolean
576 dfu_tool_patch_create (DfuToolPrivate *priv, gchar **values, GError **error)
577 {
578 const gchar *data_diff;
579 gsize sz_diff = 0;
580 gsize sz_new = 0;
581 gsize sz_old = 0;
582 g_autofree gchar *data_new = NULL;
583 g_autofree gchar *data_old = NULL;
584 g_autoptr(DfuPatch) patch = NULL;
585 g_autoptr(GBytes) blob_diff = NULL;
586 g_autoptr(GBytes) blob_new = NULL;
587 g_autoptr(GBytes) blob_old = NULL;
588
589 if (g_strv_length (values) != 3) {
590 g_set_error_literal (error,
591 FWUPD_ERROR,
592 FWUPD_ERROR_INTERNAL,
593 "Invalid arguments, expected OLD.bin NEW.bin OUT.bdiff");
594 return FALSE;
595 }
596
597 /* read files */
598 if (!g_file_get_contents (values[0], &data_old, &sz_old, error))
599 return FALSE;
600 blob_old = g_bytes_new (data_old, sz_old);
601 if (!g_file_get_contents (values[1], &data_new, &sz_new, error))
602 return FALSE;
603 blob_new = g_bytes_new (data_new, sz_new);
604
605 /* create patch */
606 patch = dfu_patch_new ();
607 if (!dfu_patch_create (patch, blob_old, blob_new, error))
608 return FALSE;
609 blob_diff = dfu_patch_export (patch, error);
610 if (blob_diff == NULL)
611 return FALSE;
612
613 /* save to disk */
614 data_diff = g_bytes_get_data (blob_diff, &sz_diff);
615 return g_file_set_contents (values[2], data_diff, sz_diff, error);
616 }
617
618 static gboolean
619 dfu_tool_replace_data (DfuToolPrivate *priv, gchar **values, GError **error)
620 {
621 GPtrArray *images;
622 guint cnt = 0;
623 g_autoptr(DfuFirmware) firmware = NULL;
624 g_autoptr(GFile) file = NULL;
625 g_autoptr(GBytes) data_search = NULL;
626 g_autoptr(GBytes) data_replace = NULL;
627
628 /* check args */
629 if (g_strv_length (values) < 3) {
630 g_set_error_literal (error,
631 FWUPD_ERROR,
632 FWUPD_ERROR_INTERNAL,
633 "Invalid arguments, expected FILE SEARCH REPLACE"
634 " -- e.g. `firmware.dfu deadbeef beefdead");
635 return FALSE;
636 }
637
638 /* open */
639 file = g_file_new_for_path (values[0]);
640 firmware = dfu_firmware_new ();
641 if (!dfu_firmware_parse_file (firmware, file,
642 DFU_FIRMWARE_PARSE_FLAG_NONE,
643 priv->cancellable,
644 error)) {
645 return FALSE;
646 }
647
648 /* parse hex values */
649 data_search = dfu_tool_parse_hex_string (values[1], error);
650 if (data_search == NULL)
651 return FALSE;
652 data_replace = dfu_tool_parse_hex_string (values[2], error);
653 if (data_replace == NULL)
654 return FALSE;
655 if (g_bytes_get_size (data_search) != g_bytes_get_size (data_replace)) {
656 g_set_error_literal (error,
657 FWUPD_ERROR,
658 FWUPD_ERROR_INTERNAL,
659 "search and replace were different sizes");
660 return FALSE;
661 }
662
663 /* get each data segment */
664 images = dfu_firmware_get_images (firmware);
665 for (guint i = 0; i < images->len; i++) {
666 DfuImage *image = g_ptr_array_index (images, i);
667 GPtrArray *elements = dfu_image_get_elements (image);
668 for (guint j = 0; j < elements->len; j++) {
669 DfuElement *element = g_ptr_array_index (elements, j);
670 GBytes *contents = dfu_element_get_contents (element);
671 if (contents == NULL)
672 continue;
673 cnt += dfu_tool_bytes_replace (contents, data_search, data_replace);
674 }
675 }
676
677 /* nothing done */
678 if (cnt == 0) {
679 g_set_error_literal (error,
680 FWUPD_ERROR,
681 FWUPD_ERROR_INTERNAL,
682 "search string was not found");
683 return FALSE;
684 }
685
686 /* write out new file */
687 return dfu_firmware_write_file (firmware,
688 file,
689 priv->cancellable,
690 error);
691 }
692
693 static gboolean
694 dfu_tool_set_target_size (DfuToolPrivate *priv, gchar **values, GError **error)
695 {
696 DfuElement *element;
697 DfuImage *image;
698 gchar *endptr;
699 guint64 padding_char = 0x00;
700 guint64 target_size;
701 g_autoptr(DfuFirmware) firmware = NULL;
702 g_autoptr(GFile) file = NULL;
703
704 /* check args */
705 if (g_strv_length (values) < 2) {
706 g_set_error_literal (error,
707 FWUPD_ERROR,
708 FWUPD_ERROR_INTERNAL,
709 "Invalid arguments, expected FILE SIZE [VAL]"
710 " -- e.g. `firmware.dfu 8000 ff");
711 return FALSE;
712 }
713
714 /* open */
715 file = g_file_new_for_path (values[0]);
716 firmware = dfu_firmware_new ();
717 if (!dfu_firmware_parse_file (firmware, file,
718 DFU_FIRMWARE_PARSE_FLAG_NONE,
719 priv->cancellable,
720 error)) {
721 return FALSE;
722 }
723
724 /* doesn't make sense for DfuSe */
725 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) {
726 g_set_error (error,
727 FWUPD_ERROR,
728 FWUPD_ERROR_INTERNAL,
729 "Cannot pad DfuSe image, try DFU");
730 return FALSE;
731 }
732
733 /* parse target size */
734 target_size = g_ascii_strtoull (values[1], &endptr, 16);
735 if (target_size > 0xffff || endptr[0] != '\0') {
736 g_set_error (error,
737 FWUPD_ERROR,
738 FWUPD_ERROR_INTERNAL,
739 "Failed to parse target size '%s'",
740 values[1]);
741 return FALSE;
742 }
743
744 /* parse padding value */
745 if (g_strv_length (values) > 3) {
746 padding_char = g_ascii_strtoull (values[2], &endptr, 16);
747 if (padding_char > 0xff || endptr[0] != '\0') {
748 g_set_error (error,
749 FWUPD_ERROR,
750 FWUPD_ERROR_INTERNAL,
751 "Failed to parse padding value '%s'",
752 values[2]);
753 return FALSE;
754 }
755 }
756
757 /* this has to exist */
758 if (target_size > 0) {
759 image = dfu_firmware_get_image_default (firmware);
760 g_assert (image != NULL);
761 element = dfu_image_get_element (image, 0);
762 dfu_element_set_padding_value (element, (guint8) padding_char);
763 dfu_element_set_target_size (element, (guint32) target_size);
764 }
765
766 /* write out new file */
767 return dfu_firmware_write_file (firmware,
768 file,
769 priv->cancellable,
770 error);
771 }
772
773 static gboolean
774 dfu_tool_set_address (DfuToolPrivate *priv, gchar **values, GError **error)
775 {
776 DfuElement *element;
777 DfuFirmwareFormat firmware_format;
778 DfuImage *image;
779 gchar *endptr;
780 guint64 address;
781 g_autoptr(DfuFirmware) firmware = NULL;
782 g_autoptr(GFile) file = NULL;
783
784 /* check args */
785 if (g_strv_length (values) < 2) {
786 g_set_error_literal (error,
787 FWUPD_ERROR,
788 FWUPD_ERROR_INTERNAL,
789 "Invalid arguments, expected FILE ADDR"
790 " -- e.g. `firmware.dfu 8000");
791 return FALSE;
792 }
793
794 /* open */
795 file = g_file_new_for_path (values[0]);
796 firmware = dfu_firmware_new ();
797 if (!dfu_firmware_parse_file (firmware, file,
798 DFU_FIRMWARE_PARSE_FLAG_NONE,
799 priv->cancellable,
800 error)) {
801 return FALSE;
802 }
803
804 /* only makes sense for DfuSe */
805 firmware_format = dfu_firmware_get_format (firmware);
806 if (firmware_format != DFU_FIRMWARE_FORMAT_DFUSE) {
807 g_set_error (error,
808 FWUPD_ERROR,
809 FWUPD_ERROR_INTERNAL,
810 "Cannot set address of %s image, try DfuSe",
811 dfu_firmware_format_to_string (firmware_format));
812 return FALSE;
813 }
814
815 /* parse address */
816 address = g_ascii_strtoull (values[1], &endptr, 16);
817 if (address > G_MAXUINT32 || endptr[0] != '\0') {
818 g_set_error (error,
819 FWUPD_ERROR,
820 FWUPD_ERROR_INTERNAL,
821 "Failed to parse address '%s'",
822 values[1]);
823 return FALSE;
824 }
825
826 /* this has to exist */
827 if (address > 0) {
828 image = dfu_firmware_get_image_default (firmware);
829 g_assert (image != NULL);
830 element = dfu_image_get_element (image, 0);
831 dfu_element_set_address (element, (guint32) address);
832 }
833
834 /* write out new file */
835 return dfu_firmware_write_file (firmware,
836 file,
837 priv->cancellable,
838 error);
839 }
840
841 static gboolean
842 dfu_tool_set_metadata (DfuToolPrivate *priv, gchar **values, GError **error)
843 {
844 g_autoptr(DfuFirmware) firmware = NULL;
845 g_autoptr(GFile) file = NULL;
846
847 /* check args */
848 if (g_strv_length (values) < 3) {
849 g_set_error_literal (error,
850 FWUPD_ERROR,
851 FWUPD_ERROR_INTERNAL,
852 "Invalid arguments, expected FILE KEY VALUE"
853 " -- e.g. `firmware.dfu Licence GPL-2.0+");
854 return FALSE;
855 }
856
857 /* open */
858 file = g_file_new_for_path (values[0]);
859 firmware = dfu_firmware_new ();
860 if (!dfu_firmware_parse_file (firmware, file,
861 DFU_FIRMWARE_PARSE_FLAG_NONE,
862 priv->cancellable,
863 error)) {
864 return FALSE;
865 }
866
867 /* doesn't make sense for non-DFU */
868 if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_RAW) {
869 g_set_error (error,
870 FWUPD_ERROR,
871 FWUPD_ERROR_INTERNAL,
872 "Only possible on DFU/DfuSe images, try convert");
873 return FALSE;
874 }
875
876 /* set metadata */
877 dfu_firmware_set_metadata (firmware, values[1], values[2]);
878
879 /* write out new file */
880 return dfu_firmware_write_file (firmware,
881 file,
882 priv->cancellable,
883 error);
884 }
885
886 static gboolean
887 dfu_tool_set_alt_setting (DfuToolPrivate *priv, gchar **values, GError **error)
888 {
889 DfuImage *image;
890 guint64 tmp;
891 g_autoptr(DfuFirmware) firmware = NULL;
892 g_autoptr(GFile) file = NULL;
893
894 /* check args */
895 if (g_strv_length (values) < 2) {
896 g_set_error_literal (error,
897 FWUPD_ERROR,
898 FWUPD_ERROR_INTERNAL,
899 "Invalid arguments, expected FILE ALT-ID"
900 " -- e.g. `firmware.dfu 1");
901 return FALSE;
902 }
903
904 /* open */
905 file = g_file_new_for_path (values[0]);
906 firmware = dfu_firmware_new ();
907 if (!dfu_firmware_parse_file (firmware, file,
908 DFU_FIRMWARE_PARSE_FLAG_NONE,
909 priv->cancellable,
910 error)) {
911 return FALSE;
912 }
913
914 /* doesn't make sense for non-DfuSe */
915 if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) {
916 g_set_error (error,
917 FWUPD_ERROR,
918 FWUPD_ERROR_INTERNAL,
919 "Only possible on DfuSe images, try convert");
920 return FALSE;
921 }
922
923 /* parse VID */
924 tmp = g_ascii_strtoull (values[1], NULL, 10);
925 if (tmp == 0 || tmp > G_MAXUINT8) {
926 g_set_error (error,
927 FWUPD_ERROR,
928 FWUPD_ERROR_INTERNAL,
929 "Failed to parse alternative setting '%s'",
930 values[1]);
931 return FALSE;
932 }
933 image = dfu_firmware_get_image_default (firmware);
934 if (image == NULL) {
935 g_set_error (error,
936 FWUPD_ERROR,
937 FWUPD_ERROR_INTERNAL,
938 "found no image '%s'", values[1]);
939 return FALSE;
940 }
941 dfu_image_set_alt_setting (image, (guint8) tmp);
942
943 /* write out new file */
944 return dfu_firmware_write_file (firmware,
945 file,
946 priv->cancellable,
947 error);
948 }
949
950 static gboolean
951 dfu_tool_set_alt_setting_name (DfuToolPrivate *priv, gchar **values, GError **error)
952 {
953 DfuImage *image;
954 g_autoptr(DfuFirmware) firmware = NULL;
955 g_autoptr(GFile) file = NULL;
956
957 /* check args */
958 if (g_strv_length (values) < 2) {
959 g_set_error_literal (error,
960 FWUPD_ERROR,
961 FWUPD_ERROR_INTERNAL,
962 "Invalid arguments, expected FILE ALT-NAME"
963 " -- e.g. `firmware.dfu ST");
964 return FALSE;
965 }
966
967 /* open */
968 file = g_file_new_for_path (values[0]);
969 firmware = dfu_firmware_new ();
970 if (!dfu_firmware_parse_file (firmware, file,
971 DFU_FIRMWARE_PARSE_FLAG_NONE,
972 priv->cancellable,
973 error)) {
974 return FALSE;
975 }
976
977 /* doesn't make sense for non-DfuSe */
978 if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) {
979 g_set_error (error,
980 FWUPD_ERROR,
981 FWUPD_ERROR_INTERNAL,
982 "Only possible on DfuSe images, try convert");
983 return FALSE;
984 }
985
986 /* parse VID */
987 image = dfu_firmware_get_image_default (firmware);
988 if (image == NULL) {
989 g_set_error (error,
990 FWUPD_ERROR,
991 FWUPD_ERROR_INTERNAL,
992 "found no image '%s'", values[1]);
993 return FALSE;
994 }
995 dfu_image_set_name (image, values[1]);
996
997 /* write out new file */
998 return dfu_firmware_write_file (firmware,
999 file,
1000 priv->cancellable,
1001 error);
1002 }
1003
1004 static gboolean
1005 dfu_tool_merge (DfuToolPrivate *priv, gchar **values, GError **error)
1006 {
1007 guint16 pid = 0xffff;
1008 guint16 rel = 0xffff;
1009 guint16 vid = 0xffff;
1010 g_autofree gchar *str_debug = NULL;
1011 g_autoptr(DfuFirmware) firmware = NULL;
1012 g_autoptr(GFile) file = NULL;
1013
1014 /* check args */
1015 if (g_strv_length (values) < 3) {
1016 g_set_error_literal (error,
1017 FWUPD_ERROR,
1018 FWUPD_ERROR_INTERNAL,
1019 "Invalid arguments, expected "
1020 "FILE-OUT FILE1 FILE2 [FILE3...]"
1021 " -- e.g. `combined.dfu lib.dfu app.dfu`");
1022 return FALSE;
1023 }
1024
1025 /* parse source files */
1026 firmware = dfu_firmware_new ();
1027 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFUSE);
1028 for (guint i = 1; values[i] != NULL; i++) {
1029 GPtrArray *images;
1030 g_autoptr(GFile) file_tmp = NULL;
1031 g_autoptr(DfuFirmware) firmware_tmp = NULL;
1032
1033 /* open up source */
1034 file_tmp = g_file_new_for_path (values[i]);
1035 firmware_tmp = dfu_firmware_new ();
1036 if (!dfu_firmware_parse_file (firmware_tmp, file_tmp,
1037 DFU_FIRMWARE_PARSE_FLAG_NONE,
1038 priv->cancellable,
1039 error)) {
1040 return FALSE;
1041 }
1042
1043 /* check same vid:pid:rel */
1044 if (vid != 0xffff &&
1045 dfu_firmware_get_vid (firmware_tmp) != vid) {
1046 g_set_error (error,
1047 FWUPD_ERROR,
1048 FWUPD_ERROR_INVALID_FILE,
1049 "Vendor ID was already set as "
1050 "0x%04x, %s is 0x%04x",
1051 vid, values[i],
1052 dfu_firmware_get_vid (firmware_tmp));
1053 return FALSE;
1054 }
1055 if (pid != 0xffff &&
1056 dfu_firmware_get_pid (firmware_tmp) != pid) {
1057 g_set_error (error,
1058 FWUPD_ERROR,
1059 FWUPD_ERROR_INVALID_FILE,
1060 "Product ID was already set as "
1061 "0x%04x, %s is 0x%04x",
1062 pid, values[i],
1063 dfu_firmware_get_pid (firmware_tmp));
1064 return FALSE;
1065 }
1066 if (rel != 0xffff &&
1067 dfu_firmware_get_release (firmware_tmp) != rel) {
1068 g_set_error (error,
1069 FWUPD_ERROR,
1070 FWUPD_ERROR_INVALID_FILE,
1071 "Release was already set as "
1072 "0x%04x, %s is 0x%04x",
1073 rel, values[i],
1074 dfu_firmware_get_release (firmware_tmp));
1075 return FALSE;
1076 }
1077
1078 /* add all images to destination */
1079 images = dfu_firmware_get_images (firmware_tmp);
1080 for (guint j = 0; j < images->len; j++) {
1081 DfuImage *image;
1082 guint8 alt_id;
1083
1084 /* verify the alt-setting does not already exist */
1085 image = g_ptr_array_index (images, j);
1086 alt_id = dfu_image_get_alt_setting (image);
1087 g_print ("Adding alternative setting ID of 0x%02x\n",
1088 alt_id);
1089 if (dfu_firmware_get_image (firmware, alt_id) != NULL) {
1090 if (!priv->force) {
1091 g_set_error (error,
1092 FWUPD_ERROR,
1093 FWUPD_ERROR_INVALID_FILE,
1094 "The alternative setting ID "
1095 "of 0x%02x has already been added",
1096 alt_id);
1097 return FALSE;
1098 }
1099 g_print ("WARNING: The alternative setting "
1100 "ID of 0x%02x has already been added\n",
1101 alt_id);
1102 }
1103
1104 /* add to destination */
1105 dfu_firmware_add_image (firmware, image);
1106 }
1107
1108 /* save last IDs */
1109 vid = dfu_firmware_get_vid (firmware_tmp);
1110 pid = dfu_firmware_get_pid (firmware_tmp);
1111 rel = dfu_firmware_get_release (firmware_tmp);
1112 }
1113
1114 /* print the new object */
1115 str_debug = dfu_firmware_to_string (firmware);
1116 g_print ("New merged file:\n%s\n", str_debug);
1117
1118 /* write out new file */
1119 file = g_file_new_for_path (values[0]);
1120 return dfu_firmware_write_file (firmware,
1121 file,
1122 priv->cancellable,
1123 error);
1124 }
1125
1126 static gboolean
1127 dfu_tool_convert (DfuToolPrivate *priv, gchar **values, GError **error)
1128 {
1129 DfuFirmwareFormat format;
1130 guint argc = g_strv_length (values);
1131 g_autofree gchar *str_debug = NULL;
1132 g_autoptr(DfuFirmware) firmware = NULL;
1133 g_autoptr(GFile) file_in = NULL;
1134 g_autoptr(GFile) file_out = NULL;
1135
1136 /* check args */
1137 if (argc != 3) {
1138 g_set_error_literal (error,
1139 FWUPD_ERROR,
1140 FWUPD_ERROR_INTERNAL,
1141 "Invalid arguments, expected "
1142 "FORMAT FILE-IN FILE-OUT"
1143 " -- e.g. `dfu firmware.hex firmware.dfu`");
1144 return FALSE;
1145 }
1146
1147 /* parse file */
1148 file_in = g_file_new_for_path (values[1]);
1149 file_out = g_file_new_for_path (values[2]);
1150 firmware = dfu_firmware_new ();
1151 if (!dfu_firmware_parse_file (firmware, file_in,
1152 DFU_FIRMWARE_PARSE_FLAG_NONE,
1153 priv->cancellable,
1154 error)) {
1155 return FALSE;
1156 }
1157
1158 /* set output format */
1159 format = dfu_firmware_format_from_string (values[0]);
1160 dfu_firmware_set_format (firmware, format);
1161 if (format == DFU_FIRMWARE_FORMAT_UNKNOWN) {
1162 g_autoptr(GString) tmp = g_string_new (NULL);
1163 for (guint i = 1; i < DFU_FIRMWARE_FORMAT_LAST; i++) {
1164 if (tmp->len > 0)
1165 g_string_append (tmp, "|");
1166 g_string_append (tmp, dfu_firmware_format_to_string (i));
1167 }
1168 g_set_error (error,
1169 FWUPD_ERROR,
1170 FWUPD_ERROR_INTERNAL,
1171 "unknown format '%s', expected [%s]",
1172 values[0], tmp->str);
1173 return FALSE;
1174 }
1175
1176 /* print the new object */
1177 str_debug = dfu_firmware_to_string (firmware);
1178 g_debug ("DFU: %s", str_debug);
1179
1180 /* write out new file */
1181 return dfu_firmware_write_file (firmware,
1182 file_out,
1183 priv->cancellable,
1184 error);
1185 }
1186
1187 static gboolean
1188 dfu_tool_attach (DfuToolPrivate *priv, gchar **values, GError **error)
1189 {
1190 g_autoptr(DfuDevice) device = NULL;
1191 g_autoptr(FuDeviceLocker) locker = NULL;
1192
1193 device = dfu_tool_get_defalt_device (priv, error);
1194 if (device == NULL)
1195 return FALSE;
1196 locker = fu_device_locker_new_full (device,
1197 (FuDeviceLockerFunc) dfu_device_open,
1198 (FuDeviceLockerFunc) dfu_device_close,
1199 error);
1200 if (locker == NULL)
1201 return FALSE;
1202 return dfu_device_attach (device, error);
1203 }
1204
1205 static void
1206 fu_tool_percentage_changed_cb (DfuDevice *device,
1207 guint percentage,
1208 DfuToolPrivate *priv)
1209 {
1210 fu_progressbar_update (priv->progressbar, FWUPD_STATUS_UNKNOWN, percentage);
1211 }
1212
1213 static void
1214 fu_tool_action_changed_cb (DfuDevice *device,
1215 FwupdStatus action,
1216 DfuToolPrivate *priv)
1217 {
1218 fu_progressbar_update (priv->progressbar, action, 0);
1219 }
1220
1221 static gboolean
1222 dfu_tool_read_alt (DfuToolPrivate *priv, gchar **values, GError **error)
1223 {
1224 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_NONE;
1225 g_autofree gchar *str_debug = NULL;
1226 g_autoptr(DfuDevice) device = NULL;
1227 g_autoptr(DfuFirmware) firmware = NULL;
1228 g_autoptr(DfuImage) image = NULL;
1229 g_autoptr(DfuTarget) target = NULL;
1230 g_autoptr(FuDeviceLocker) locker = NULL;
1231 g_autoptr(GFile) file = NULL;
1232
1233 /* check args */
1234 if (g_strv_length (values) < 2) {
1235 g_set_error_literal (error,
1236 FWUPD_ERROR,
1237 FWUPD_ERROR_INTERNAL,
1238 "Invalid arguments, expected "
1239 "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID");
1240 return FALSE;
1241 }
1242
1243 /* open correct device */
1244 device = dfu_tool_get_defalt_device (priv, error);
1245 if (device == NULL)
1246 return FALSE;
1247 if (priv->transfer_size > 0)
1248 dfu_device_set_transfer_size (device, priv->transfer_size);
1249 locker = fu_device_locker_new_full (device,
1250 (FuDeviceLockerFunc) dfu_device_open,
1251 (FuDeviceLockerFunc) dfu_device_close,
1252 error);
1253 if (locker == NULL)
1254 return FALSE;
1255
1256 /* set up progress */
1257 g_signal_connect (device, "action-changed",
1258 G_CALLBACK (fu_tool_action_changed_cb), priv);
1259 g_signal_connect (device, "percentage-changed",
1260 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1261
1262 /* APP -> DFU */
1263 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1264 g_debug ("detaching");
1265 if (!dfu_device_detach (device, priv->cancellable, error))
1266 return FALSE;
1267 if (!dfu_device_wait_for_replug (device,
1268 DFU_DEVICE_REPLUG_TIMEOUT,
1269 priv->cancellable,
1270 error))
1271 return FALSE;
1272
1273 /* put back in same state */
1274 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1275 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1276 }
1277
1278 /* transfer */
1279 target = dfu_device_get_target_by_alt_name (device,
1280 values[1],
1281 NULL);
1282 if (target == NULL) {
1283 gchar *endptr;
1284 guint64 tmp = g_ascii_strtoull (values[1], &endptr, 10);
1285 if (tmp > 0xff || endptr[0] != '\0') {
1286 g_set_error (error,
1287 FWUPD_ERROR,
1288 FWUPD_ERROR_INTERNAL,
1289 "Failed to parse alt-setting '%s'",
1290 values[1]);
1291 return FALSE;
1292 }
1293 target = dfu_device_get_target_by_alt_setting (device,
1294 (guint8) tmp,
1295 error);
1296 if (target == NULL)
1297 return FALSE;
1298 }
1299
1300 /* do transfer */
1301 image = dfu_target_upload (target, flags, priv->cancellable, error);
1302 if (image == NULL)
1303 return FALSE;
1304
1305 /* create new firmware object */
1306 firmware = dfu_firmware_new ();
1307 dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU);
1308 dfu_firmware_set_vid (firmware, dfu_device_get_runtime_vid (device));
1309 dfu_firmware_set_pid (firmware, dfu_device_get_runtime_pid (device));
1310 dfu_firmware_add_image (firmware, image);
1311
1312 /* save file */
1313 file = g_file_new_for_path (values[0]);
1314 if (!dfu_firmware_write_file (firmware,
1315 file,
1316 priv->cancellable,
1317 error))
1318 return FALSE;
1319
1320 /* print the new object */
1321 str_debug = dfu_firmware_to_string (firmware);
1322 g_debug ("DFU: %s", str_debug);
1323
1324 /* success */
1325 g_print ("%u bytes successfully uploaded from device\n",
1326 dfu_image_get_size (image));
1327 return TRUE;
1328 }
1329
1330 static gboolean
1331 dfu_tool_read (DfuToolPrivate *priv, gchar **values, GError **error)
1332 {
1333 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_NONE;
1334 g_autofree gchar *str_debug = NULL;
1335 g_autoptr(DfuDevice) device = NULL;
1336 g_autoptr(DfuFirmware) firmware = NULL;
1337 g_autoptr(FuDeviceLocker) locker = NULL;
1338 g_autoptr(GFile) file = NULL;
1339
1340 /* check args */
1341 if (g_strv_length (values) < 1) {
1342 g_set_error_literal (error,
1343 FWUPD_ERROR,
1344 FWUPD_ERROR_INTERNAL,
1345 "Invalid arguments, expected FILENAME");
1346 return FALSE;
1347 }
1348
1349 /* open correct device */
1350 device = dfu_tool_get_defalt_device (priv, error);
1351 if (device == NULL)
1352 return FALSE;
1353 locker = fu_device_locker_new_full (device,
1354 (FuDeviceLockerFunc) dfu_device_open,
1355 (FuDeviceLockerFunc) dfu_device_close,
1356 error);
1357 if (locker == NULL)
1358 return FALSE;
1359
1360 /* optional reset */
1361 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1362 flags |= DFU_TARGET_TRANSFER_FLAG_DETACH;
1363 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1364 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1365 }
1366
1367 /* transfer */
1368 g_signal_connect (device, "action-changed",
1369 G_CALLBACK (fu_tool_action_changed_cb), priv);
1370 g_signal_connect (device, "percentage-changed",
1371 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1372 firmware = dfu_device_upload (device,
1373 flags,
1374 priv->cancellable,
1375 error);
1376 if (firmware == NULL)
1377 return FALSE;
1378
1379 /* save file */
1380 file = g_file_new_for_path (values[0]);
1381 if (!dfu_firmware_write_file (firmware,
1382 file,
1383 priv->cancellable,
1384 error))
1385 return FALSE;
1386
1387 /* print the new object */
1388 str_debug = dfu_firmware_to_string (firmware);
1389 g_debug ("DFU: %s", str_debug);
1390
1391 /* success */
1392 g_print ("%u bytes successfully uploaded from device\n",
1393 dfu_firmware_get_size (firmware));
1394 return TRUE;
1395 }
1396
1397 static gchar *
1398 dfu_tool_get_device_string (DfuToolPrivate *priv, DfuDevice *device)
1399 {
1400 GUsbDevice *dev;
1401 g_autoptr(FuDeviceLocker) locker = NULL;
1402
1403 /* open if required, and get status */
1404 dev = dfu_device_get_usb_dev (device);
1405 if (dev == NULL) {
1406 return g_strdup_printf ("%04x:%04x [%s]",
1407 dfu_device_get_runtime_vid (device),
1408 dfu_device_get_runtime_pid (device),
1409 "removed");
1410 }
1411 if (!dfu_device_is_open (device)) {
1412 g_autoptr(GError) error = NULL;
1413 locker = fu_device_locker_new_full (device,
1414 (FuDeviceLockerFunc) dfu_device_open,
1415 (FuDeviceLockerFunc) dfu_device_close,
1416 &error);
1417 if (locker == NULL) {
1418 return g_strdup_printf ("%04x:%04x [%s]",
1419 g_usb_device_get_vid (dev),
1420 g_usb_device_get_pid (dev),
1421 error->message);
1422 }
1423 }
1424 return g_strdup_printf ("%04x:%04x [%s:%s]",
1425 g_usb_device_get_vid (dev),
1426 g_usb_device_get_pid (dev),
1427 dfu_state_to_string (dfu_device_get_state (device)),
1428 dfu_status_to_string (dfu_device_get_status (device)));
1429 }
1430
1431 static void
1432 dfu_tool_device_added_cb (DfuContext *context,
1433 DfuDevice *device,
1434 gpointer user_data)
1435 {
1436 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
1437 g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device);
1438 /* TRANSLATORS: this is when a device is hotplugged */
1439 dfu_tool_print_indent (_("Added"), tmp, 0);
1440 }
1441
1442 static void
1443 dfu_tool_device_removed_cb (DfuContext *context,
1444 DfuDevice *device,
1445 gpointer user_data)
1446 {
1447 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
1448 g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device);
1449 /* TRANSLATORS: this is when a device is hotplugged */
1450 dfu_tool_print_indent (_("Removed"), tmp, 0);
1451 }
1452
1453 static void
1454 dfu_tool_device_changed_cb (DfuContext *context, DfuDevice *device, gpointer user_data)
1455 {
1456 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
1457 g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device);
1458 /* TRANSLATORS: this is when a device is hotplugged */
1459 dfu_tool_print_indent (_("Changed"), tmp, 0);
1460 }
1461
1462 static void
1463 dfu_tool_watch_cancelled_cb (GCancellable *cancellable, gpointer user_data)
1464 {
1465 GMainLoop *loop = (GMainLoop *) user_data;
1466 /* TRANSLATORS: this is when a device ctrl+c's a watch */
1467 g_print ("%s\n", _("Cancelled"));
1468 g_main_loop_quit (loop);
1469 }
1470
1471 static guint8 *
1472 dfu_tool_get_firmware_contents_default (DfuFirmware *firmware,
1473 gsize *length,
1474 GError **error)
1475 {
1476 DfuElement *element;
1477 DfuImage *image;
1478 GBytes *contents;
1479
1480 image = dfu_firmware_get_image_default (firmware);
1481 if (image == NULL) {
1482 g_set_error_literal (error,
1483 FWUPD_ERROR,
1484 FWUPD_ERROR_INTERNAL,
1485 "No default image");
1486 return NULL;
1487 }
1488 element = dfu_image_get_element (image, 0);
1489 if (element == NULL) {
1490 g_set_error_literal (error,
1491 FWUPD_ERROR,
1492 FWUPD_ERROR_INTERNAL,
1493 "No default element");
1494 return NULL;
1495 }
1496 contents = dfu_element_get_contents (element);
1497 if (contents == NULL) {
1498 g_set_error_literal (error,
1499 FWUPD_ERROR,
1500 FWUPD_ERROR_INTERNAL,
1501 "No image contents");
1502 return NULL;
1503 }
1504 return (guint8 *) g_bytes_get_data (contents, length);
1505 }
1506
1507 static gboolean
1508 dfu_tool_encrypt (DfuToolPrivate *priv, gchar **values, GError **error)
1509 {
1510 gsize len;
1511 guint8 *data;
1512 g_autoptr(DfuFirmware) firmware = NULL;
1513 g_autoptr(GFile) file_in = NULL;
1514 g_autoptr(GFile) file_out = NULL;
1515
1516 /* check args */
1517 if (g_strv_length (values) < 4) {
1518 g_set_error_literal (error,
1519 FWUPD_ERROR,
1520 FWUPD_ERROR_INTERNAL,
1521 "Invalid arguments, expected "
1522 "FILENAME-IN FILENAME-OUT TYPE KEY"
1523 " -- e.g. firmware.dfu firmware.xdfu xtea deadbeef");
1524 return FALSE;
1525 }
1526
1527 /* check extensions */
1528 if (!priv->force) {
1529 if (!g_str_has_suffix (values[0], ".dfu")) {
1530 g_set_error_literal (error,
1531 FWUPD_ERROR,
1532 FWUPD_ERROR_NOT_SUPPORTED,
1533 "Invalid filename, expected *.dfu");
1534 return FALSE;
1535 }
1536 if (!g_str_has_suffix (values[1], ".xdfu")) {
1537 g_set_error_literal (error,
1538 FWUPD_ERROR,
1539 FWUPD_ERROR_NOT_SUPPORTED,
1540 "Invalid filename, expected *.xdfu");
1541 return FALSE;
1542 }
1543 }
1544
1545 /* open */
1546 file_in = g_file_new_for_path (values[0]);
1547 firmware = dfu_firmware_new ();
1548 if (!dfu_firmware_parse_file (firmware, file_in,
1549 DFU_FIRMWARE_PARSE_FLAG_NONE,
1550 priv->cancellable,
1551 error)) {
1552 return FALSE;
1553 }
1554
1555 /* get data */
1556 data = dfu_tool_get_firmware_contents_default (firmware, &len, error);
1557 if (data == NULL)
1558 return FALSE;
1559
1560 /* check type */
1561 if (g_strcmp0 (values[2], "xtea") == 0) {
1562 if (!dfu_cipher_encrypt_xtea (values[3], data, (guint32) len, error))
1563 return FALSE;
1564 dfu_firmware_set_metadata (firmware,
1565 DFU_METADATA_KEY_CIPHER_KIND,
1566 "XTEA");
1567 } else {
1568 g_set_error (error,
1569 FWUPD_ERROR,
1570 FWUPD_ERROR_INTERNAL,
1571 "unknown type '%s', expected [xtea]",
1572 values[2]);
1573 return FALSE;
1574 }
1575
1576 /* write out new file */
1577 file_out = g_file_new_for_path (values[1]);
1578 g_debug ("wrote %s", values[1]);
1579 return dfu_firmware_write_file (firmware,
1580 file_out,
1581 priv->cancellable,
1582 error);
1583 }
1584
1585 static gboolean
1586 dfu_tool_decrypt (DfuToolPrivate *priv, gchar **values, GError **error)
1587 {
1588 gsize len;
1589 guint8 *data;
1590 g_autoptr(DfuFirmware) firmware = NULL;
1591 g_autoptr(GFile) file_in = NULL;
1592 g_autoptr(GFile) file_out = NULL;
1593
1594 /* check args */
1595 if (g_strv_length (values) < 4) {
1596 g_set_error_literal (error,
1597 FWUPD_ERROR,
1598 FWUPD_ERROR_INTERNAL,
1599 "Invalid arguments, expected "
1600 "FILENAME-IN FILENAME-OUT TYPE KEY"
1601 " -- e.g. firmware.xdfu firmware.dfu xtea deadbeef");
1602 return FALSE;
1603 }
1604
1605 /* check extensions */
1606 if (!priv->force) {
1607 if (!g_str_has_suffix (values[0], ".xdfu")) {
1608 g_set_error_literal (error,
1609 FWUPD_ERROR,
1610 FWUPD_ERROR_NOT_SUPPORTED,
1611 "Invalid filename, expected *.xdfu");
1612 return FALSE;
1613 }
1614 if (!g_str_has_suffix (values[1], ".dfu")) {
1615 g_set_error_literal (error,
1616 FWUPD_ERROR,
1617 FWUPD_ERROR_NOT_SUPPORTED,
1618 "Invalid filename, expected *.dfu");
1619 return FALSE;
1620 }
1621 }
1622
1623 /* open */
1624 file_in = g_file_new_for_path (values[0]);
1625 firmware = dfu_firmware_new ();
1626 if (!dfu_firmware_parse_file (firmware, file_in,
1627 DFU_FIRMWARE_PARSE_FLAG_NONE,
1628 priv->cancellable,
1629 error)) {
1630 return FALSE;
1631 }
1632
1633 /* get data */
1634 data = dfu_tool_get_firmware_contents_default (firmware, &len, error);
1635 if (data == NULL)
1636 return FALSE;
1637
1638 /* check type */
1639 if (g_strcmp0 (values[2], "xtea") == 0) {
1640 if (!dfu_cipher_decrypt_xtea (values[3], data, (guint32) len, error))
1641 return FALSE;
1642 dfu_firmware_remove_metadata (firmware,
1643 DFU_METADATA_KEY_CIPHER_KIND);
1644 } else {
1645 g_set_error (error,
1646 FWUPD_ERROR,
1647 FWUPD_ERROR_INTERNAL,
1648 "unknown type '%s', expected [xtea]",
1649 values[2]);
1650 return FALSE;
1651 }
1652
1653 /* write out new file */
1654 file_out = g_file_new_for_path (values[1]);
1655 g_debug ("wrote %s", values[1]);
1656 return dfu_firmware_write_file (firmware,
1657 file_out,
1658 priv->cancellable,
1659 error);
1660 }
1661
1662 static gboolean
1663 dfu_tool_watch (DfuToolPrivate *priv, gchar **values, GError **error)
1664 {
1665 g_autoptr(DfuContext) dfu_context = NULL;
1666 g_autoptr(GMainLoop) loop = NULL;
1667 g_autoptr(GPtrArray) devices = NULL;
1668
1669 /* get all the DFU devices */
1670 dfu_context = dfu_context_new ();
1671 dfu_context_enumerate (dfu_context, NULL);
1672
1673 /* print what's already attached */
1674 devices = dfu_context_get_devices (dfu_context);
1675 for (guint i = 0; i < devices->len; i++) {
1676 DfuDevice *device = g_ptr_array_index (devices, i);
1677 dfu_tool_device_added_cb (dfu_context, device, priv);
1678 }
1679
1680 /* watch for any hotplugged device */
1681 loop = g_main_loop_new (NULL, FALSE);
1682 g_signal_connect (dfu_context, "device-added",
1683 G_CALLBACK (dfu_tool_device_added_cb), priv);
1684 g_signal_connect (dfu_context, "device-removed",
1685 G_CALLBACK (dfu_tool_device_removed_cb), priv);
1686 g_signal_connect (dfu_context, "device-changed",
1687 G_CALLBACK (dfu_tool_device_changed_cb), priv);
1688 g_signal_connect (priv->cancellable, "cancelled",
1689 G_CALLBACK (dfu_tool_watch_cancelled_cb), loop);
1690 g_main_loop_run (loop);
1691 return TRUE;
1692 }
1693
1694 static gboolean
1695 dfu_tool_dump (DfuToolPrivate *priv, gchar **values, GError **error)
1696 {
1697 DfuFirmwareParseFlags flags = DFU_FIRMWARE_PARSE_FLAG_NONE;
1698
1699 /* check args */
1700 if (g_strv_length (values) < 1) {
1701 g_set_error_literal (error,
1702 FWUPD_ERROR,
1703 FWUPD_ERROR_INTERNAL,
1704 "Invalid arguments, expected FILENAME");
1705 return FALSE;
1706 }
1707
1708 /* dump corrupt files */
1709 if (priv->force) {
1710 flags |= DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST;
1711 flags |= DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST;
1712 }
1713
1714 /* open files */
1715 for (guint i = 0; values[i] != NULL; i++) {
1716 g_autoptr(DfuFirmware) firmware = NULL;
1717 g_autoptr(GFile) file = NULL;
1718 g_autoptr(GError) error_local = NULL;
1719
1720 /* dump to screen */
1721 g_print ("Loading %s:\n", values[i]);
1722 firmware = dfu_firmware_new ();
1723 file = g_file_new_for_path (values[i]);
1724 if (!dfu_firmware_parse_file (firmware, file, flags,
1725 priv->cancellable,
1726 &error_local)) {
1727 g_print ("Failed to load firmware: %s\n",
1728 error_local->message);
1729 continue;
1730 }
1731 g_print ("%s\n", dfu_firmware_to_string (firmware));
1732 }
1733 return TRUE;
1734 }
1735
1736 static gboolean
1737 dfu_tool_write_alt (DfuToolPrivate *priv, gchar **values, GError **error)
1738 {
1739 DfuImage *image;
1740 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_VERIFY;
1741 g_autofree gchar *str_debug = NULL;
1742 g_autoptr(DfuDevice) device = NULL;
1743 g_autoptr(DfuFirmware) firmware = NULL;
1744 g_autoptr(DfuTarget) target = NULL;
1745 g_autoptr(FuDeviceLocker) locker = NULL;
1746 g_autoptr(GFile) file = NULL;
1747
1748 /* check args */
1749 if (g_strv_length (values) < 2) {
1750 g_set_error_literal (error,
1751 FWUPD_ERROR,
1752 FWUPD_ERROR_INTERNAL,
1753 "Invalid arguments, expected "
1754 "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID "
1755 "[IMAGE-ALT-NAME|IMAGE-ALT-ID]");
1756 return FALSE;
1757 }
1758
1759 /* open file */
1760 firmware = dfu_firmware_new ();
1761 file = g_file_new_for_path (values[0]);
1762 if (!dfu_firmware_parse_file (firmware, file,
1763 DFU_FIRMWARE_PARSE_FLAG_NONE,
1764 priv->cancellable, error))
1765 return FALSE;
1766
1767 /* open correct device */
1768 device = dfu_tool_get_defalt_device (priv, error);
1769 if (device == NULL)
1770 return FALSE;
1771 if (priv->transfer_size > 0)
1772 dfu_device_set_transfer_size (device, priv->transfer_size);
1773 locker = fu_device_locker_new_full (device,
1774 (FuDeviceLockerFunc) dfu_device_open,
1775 (FuDeviceLockerFunc) dfu_device_close,
1776 error);
1777 if (locker == NULL)
1778 return FALSE;
1779
1780 /* set up progress */
1781 g_signal_connect (device, "action-changed",
1782 G_CALLBACK (fu_tool_action_changed_cb), priv);
1783 g_signal_connect (device, "percentage-changed",
1784 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1785
1786 /* APP -> DFU */
1787 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1788 g_debug ("detaching");
1789 if (!dfu_device_detach (device, priv->cancellable, error))
1790 return FALSE;
1791 if (!dfu_device_wait_for_replug (device, 5000, priv->cancellable, error))
1792 return FALSE;
1793
1794 /* put back in same state */
1795 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1796 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1797 }
1798
1799 /* print the new object */
1800 str_debug = dfu_firmware_to_string (firmware);
1801 g_debug ("DFU: %s", str_debug);
1802
1803 /* get correct target on device */
1804 target = dfu_device_get_target_by_alt_name (device,
1805 values[1],
1806 NULL);
1807 if (target == NULL) {
1808 gchar *endptr;
1809 guint64 tmp = g_ascii_strtoull (values[1], &endptr, 10);
1810 if (tmp > 0xff || endptr[0] != '\0') {
1811 g_set_error (error,
1812 FWUPD_ERROR,
1813 FWUPD_ERROR_INTERNAL,
1814 "Failed to parse alt-setting '%s'",
1815 values[1]);
1816 return FALSE;
1817 }
1818 target = dfu_device_get_target_by_alt_setting (device,
1819 (guint8) tmp,
1820 error);
1821 if (target == NULL)
1822 return FALSE;
1823 }
1824
1825 /* allow overriding the firmware alt-setting */
1826 if (g_strv_length (values) > 2) {
1827 image = dfu_firmware_get_image_by_name (firmware, values[2]);
1828 if (image == NULL) {
1829 gchar *endptr;
1830 guint64 tmp = g_ascii_strtoull (values[2], &endptr, 10);
1831 if (tmp > 0xff || endptr[0] != '\0') {
1832 g_set_error (error,
1833 FWUPD_ERROR,
1834 FWUPD_ERROR_INTERNAL,
1835 "Failed to parse image alt-setting '%s'",
1836 values[2]);
1837 return FALSE;
1838 }
1839 image = dfu_firmware_get_image (firmware, (guint8) tmp);
1840 if (image == NULL) {
1841 g_set_error (error,
1842 FWUPD_ERROR,
1843 FWUPD_ERROR_INVALID_FILE,
1844 "could not locate image in firmware for %02x",
1845 (guint) tmp);
1846 return FALSE;
1847 }
1848 }
1849 } else {
1850 g_print ("WARNING: Using default firmware image\n");
1851 image = dfu_firmware_get_image_default (firmware);
1852 if (image == NULL) {
1853 g_set_error_literal (error,
1854 FWUPD_ERROR,
1855 FWUPD_ERROR_INVALID_FILE,
1856 "no default image");
1857 return FALSE;
1858 }
1859 }
1860
1861 /* allow forcing firmware kinds */
1862 if (priv->force) {
1863 flags |= DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER;
1864 }
1865
1866 /* transfer */
1867 if (!dfu_target_download (target,
1868 image,
1869 flags,
1870 priv->cancellable,
1871 error))
1872 return FALSE;
1873
1874 /* success */
1875 g_print ("%u bytes successfully downloaded to device\n",
1876 dfu_image_get_size (image));
1877 return TRUE;
1878 }
1879
1880 static gboolean
1881 dfu_tool_write (DfuToolPrivate *priv, gchar **values, GError **error)
1882 {
1883 DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_VERIFY;
1884 g_autofree gchar *str_debug = NULL;
1885 g_autoptr(DfuDevice) device = NULL;
1886 g_autoptr(DfuFirmware) firmware = NULL;
1887 g_autoptr(FuDeviceLocker) locker = NULL;
1888 g_autoptr(GFile) file = NULL;
1889
1890 /* check args */
1891 if (g_strv_length (values) < 1) {
1892 g_set_error_literal (error,
1893 FWUPD_ERROR,
1894 FWUPD_ERROR_INTERNAL,
1895 "Invalid arguments, expected FILENAME");
1896 return FALSE;
1897 }
1898
1899 /* open file */
1900 firmware = dfu_firmware_new ();
1901 file = g_file_new_for_path (values[0]);
1902 if (!dfu_firmware_parse_file (firmware, file,
1903 DFU_FIRMWARE_PARSE_FLAG_NONE,
1904 priv->cancellable, error))
1905 return FALSE;
1906
1907 /* open correct device */
1908 device = dfu_tool_get_defalt_device (priv, error);
1909 if (device == NULL)
1910 return FALSE;
1911 locker = fu_device_locker_new_full (device,
1912 (FuDeviceLockerFunc) dfu_device_open,
1913 (FuDeviceLockerFunc) dfu_device_close,
1914 error);
1915 if (locker == NULL)
1916 return FALSE;
1917
1918 /* print the new object */
1919 str_debug = dfu_firmware_to_string (firmware);
1920 g_debug ("DFU: %s", str_debug);
1921
1922 /* put in correct mode */
1923 if (dfu_device_get_mode (device) == DFU_MODE_RUNTIME) {
1924 flags |= DFU_TARGET_TRANSFER_FLAG_DETACH;
1925 flags |= DFU_TARGET_TRANSFER_FLAG_ATTACH;
1926 flags |= DFU_TARGET_TRANSFER_FLAG_WAIT_RUNTIME;
1927 }
1928
1929 /* allow wildcards */
1930 if (priv->force) {
1931 flags |= DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID;
1932 flags |= DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID;
1933 flags |= DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER;
1934 }
1935
1936 /* transfer */
1937 g_signal_connect (device, "action-changed",
1938 G_CALLBACK (fu_tool_action_changed_cb), priv);
1939 g_signal_connect (device, "percentage-changed",
1940 G_CALLBACK (fu_tool_percentage_changed_cb), priv);
1941 if (!dfu_device_download (device,
1942 firmware,
1943 flags,
1944 priv->cancellable,
1945 error))
1946 return FALSE;
1947
1948 /* success */
1949 g_print ("%u bytes successfully downloaded to device\n",
1950 dfu_firmware_get_size (firmware));
1951 return TRUE;
1952 }
1953
1954 static void
1955 dfu_tool_list_target (DfuTarget *target)
1956 {
1957 DfuCipherKind cipher_kind;
1958 GPtrArray *sectors;
1959 const gchar *tmp;
1960 g_autofree gchar *alt_id = NULL;
1961 g_autoptr(GError) error_local = NULL;
1962
1963 /* TRANSLATORS: the identifier name please */
1964 alt_id = g_strdup_printf ("%i", dfu_target_get_alt_setting (target));
1965 dfu_tool_print_indent (_("ID"), alt_id, 1);
1966
1967 /* this is optional */
1968 tmp = dfu_target_get_alt_name_for_display (target, &error_local);
1969 if (tmp != NULL) {
1970 /* TRANSLATORS: interface name, e.g. "Flash" */
1971 dfu_tool_print_indent (_("Name"), tmp, 2);
1972 } else if (!g_error_matches (error_local,
1973 FWUPD_ERROR,
1974 FWUPD_ERROR_NOT_FOUND)) {
1975 g_autofree gchar *str = NULL;
1976 str = g_strdup_printf ("Error: %s", error_local->message);
1977 dfu_tool_print_indent (_("Name"), str, 2);
1978 }
1979
1980 /* this is optional */
1981 cipher_kind = dfu_target_get_cipher_kind (target);
1982 if (cipher_kind != DFU_CIPHER_KIND_NONE) {
1983 /* TRANSLATORS: this is the encryption method used when writing */
1984 dfu_tool_print_indent (_("Cipher"),
1985 dfu_cipher_kind_to_string (cipher_kind),
1986 2);
1987 }
1988
1989 /* print sector information */
1990 sectors = dfu_target_get_sectors (target);
1991 for (guint i = 0; i < sectors->len; i++) {
1992 DfuSector *sector;
1993 g_autofree gchar *msg = NULL;
1994 g_autofree gchar *title = NULL;
1995 sector = g_ptr_array_index (sectors, i);
1996 msg = dfu_sector_to_string (sector);
1997 /* TRANSLATORS: these are areas of memory on the chip */
1998 title = g_strdup_printf ("%s 0x%02x", _("Region"), i);
1999 dfu_tool_print_indent (title, msg, 2);
2000 }
2001 }
2002
2003 static gboolean
2004 dfu_tool_list (DfuToolPrivate *priv, gchar **values, GError **error)
2005 {
2006 g_autoptr(DfuContext) dfu_context = NULL;
2007 g_autoptr(GPtrArray) devices = NULL;
2008
2009 /* get all the connected USB devices */
2010 dfu_context = dfu_context_new ();
2011 dfu_context_enumerate (dfu_context, NULL);
2012 devices = dfu_context_get_devices (dfu_context);
2013 for (guint i = 0; i < devices->len; i++) {
2014 DfuDevice *device = NULL;
2015 DfuTarget *target;
2016 GUsbDevice *dev;
2017 GPtrArray *dfu_targets;
2018 const gchar *tmp;
2019 guint16 transfer_size;
2020 g_autofree gchar *quirks = NULL;
2021 g_autofree gchar *version = NULL;
2022 g_autoptr(FuDeviceLocker) locker = NULL;
2023 g_autoptr(GError) error_local = NULL;
2024
2025 /* device specific */
2026 device = g_ptr_array_index (devices, i);
2027 dev = dfu_device_get_usb_dev (device);
2028 version = as_utils_version_from_uint16 (g_usb_device_get_release (dev),
2029 AS_VERSION_PARSE_FLAG_NONE);
2030 g_print ("%s %04x:%04x [v%s]:\n",
2031 /* TRANSLATORS: detected a DFU device */
2032 _("Found"),
2033 g_usb_device_get_vid (dev),
2034 g_usb_device_get_pid (dev),
2035 version);
2036
2037 tmp = dfu_version_to_string (dfu_device_get_version (device));
2038 if (tmp != NULL) {
2039 /* TRANSLATORS: DFU protocol version, e.g. 1.1 */
2040 dfu_tool_print_indent (_("Protocol"), tmp, 1);
2041 }
2042
2043 /* open */
2044 locker = fu_device_locker_new_full (device,
2045 (FuDeviceLockerFunc) dfu_device_open,
2046 (FuDeviceLockerFunc) dfu_device_close,
2047 &error_local);
2048 if (locker == NULL) {
2049 if (g_error_matches (error_local,
2050 FWUPD_ERROR,
2051 FWUPD_ERROR_PERMISSION_DENIED)) {
2052 /* TRANSLATORS: probably not run as root... */
2053 dfu_tool_print_indent (_("Status"), _("Unknown: permission denied"), 2);
2054 } else {
2055 /* TRANSLATORS: device has failed to report status */
2056 dfu_tool_print_indent (_("Status"), error_local->message, 2);
2057 }
2058 continue;
2059 }
2060
2061 tmp = dfu_device_get_display_name (device);
2062 if (tmp != NULL) {
2063 /* TRANSLATORS: device name, e.g. 'ColorHug2' */
2064 dfu_tool_print_indent (_("Name"), tmp, 1);
2065 }
2066
2067 tmp = dfu_device_get_serial_number (device);
2068 if (tmp != NULL) {
2069 /* TRANSLATORS: serial number, e.g. '00012345' */
2070 dfu_tool_print_indent (_("Serial"), tmp, 1);
2071 }
2072
2073 tmp = dfu_mode_to_string (dfu_device_get_mode (device));
2074 /* TRANSLATORS: device mode, e.g. runtime or DFU */
2075 dfu_tool_print_indent (_("Mode"), tmp, 1);
2076
2077 tmp = dfu_status_to_string (dfu_device_get_status (device));
2078 /* TRANSLATORS: device status, e.g. "OK" */
2079 dfu_tool_print_indent (_("Status"), tmp, 1);
2080
2081 tmp = dfu_state_to_string (dfu_device_get_state (device));
2082 /* TRANSLATORS: device state, i.e. appIDLE */
2083 dfu_tool_print_indent (_("State"), tmp, 1);
2084
2085 transfer_size = dfu_device_get_transfer_size (device);
2086 if (transfer_size > 0) {
2087 g_autofree gchar *str = NULL;
2088 str = g_format_size_full (transfer_size,
2089 G_FORMAT_SIZE_LONG_FORMAT);
2090 /* TRANSLATORS: transfer size in bytes */
2091 dfu_tool_print_indent (_("Transfer Size"), str, 1);
2092 }
2093
2094 /* quirks are NULL if none are set */
2095 quirks = dfu_device_get_quirks_as_string (device);
2096 if (quirks != NULL) {
2097 /* TRANSLATORS: device quirks, i.e. things that
2098 * it does that we have to work around */
2099 dfu_tool_print_indent (_("Quirks"), quirks, 1);
2100 }
2101
2102 /* list targets */
2103 dfu_targets = dfu_device_get_targets (device);
2104 for (guint j = 0; j < dfu_targets->len; j++) {
2105 target = g_ptr_array_index (dfu_targets, j);
2106 dfu_tool_list_target (target);
2107 }
2108 }
2109 return TRUE;
2110 }
2111
2112 static gboolean
2113 dfu_tool_detach (DfuToolPrivate *priv, gchar **values, GError **error)
2114 {
2115 g_autoptr(DfuDevice) device = NULL;
2116 g_autoptr(FuDeviceLocker) locker = NULL;
2117
2118 /* open correct device */
2119 device = dfu_tool_get_defalt_device (priv, error);
2120 if (device == NULL)
2121 return FALSE;
2122 if (priv->transfer_size > 0)
2123 dfu_device_set_transfer_size (device, priv->transfer_size);
2124
2125 /* detatch */
2126 locker = fu_device_locker_new_full (device,
2127 (FuDeviceLockerFunc) dfu_device_open,
2128 (FuDeviceLockerFunc) dfu_device_close,
2129 error);
2130 if (locker == NULL)
2131 return FALSE;
2132 return dfu_device_detach (device, priv->cancellable, error);
2133 }
2134
2135 static gboolean
2136 dfu_tool_sigint_cb (gpointer user_data)
2137 {
2138 DfuToolPrivate *priv = (DfuToolPrivate *) user_data;
2139 g_debug ("Handling SIGINT");
2140 g_cancellable_cancel (priv->cancellable);
2141 return FALSE;
2142 }
2143
2144 int
2145 main (int argc, char *argv[])
2146 {
2147 gboolean ret;
2148 gboolean verbose = FALSE;
2149 gboolean version = FALSE;
2150 g_autofree gchar *cmd_descriptions = NULL;
2151 g_autoptr(DfuToolPrivate) priv = g_new0 (DfuToolPrivate, 1);
2152 g_autoptr(GError) error = NULL;
2153 g_autoptr(GOptionContext) context = NULL;
2154 const GOptionEntry options[] = {
2155 { "version", '\0', 0, G_OPTION_ARG_NONE, &version,
2156 "Print the version number", NULL },
2157 { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
2158 "Print verbose debug statements", NULL },
2159 { "device", 'd', 0, G_OPTION_ARG_STRING, &priv->device_vid_pid,
2160 "Specify Vendor/Product ID(s) of DFU device", "VID:PID" },
2161 { "transfer-size", 't', 0, G_OPTION_ARG_STRING, &priv->transfer_size,
2162 "Specify the number of bytes per USB transfer", "BYTES" },
2163 { "force", '\0', 0, G_OPTION_ARG_NONE, &priv->force,
2164 "Force the action ignoring all warnings", NULL },
2165 { NULL}
2166 };
2167
2168 setlocale (LC_ALL, "");
2169
2170 bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
2171 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2172 textdomain (GETTEXT_PACKAGE);
2173
2174 /* add commands */
2175 priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_tool_item_free);
2176 dfu_tool_add (priv->cmd_array,
2177 "convert",
2178 NULL,
2179 /* TRANSLATORS: command description */
2180 _("Convert firmware to DFU format"),
2181 dfu_tool_convert);
2182 dfu_tool_add (priv->cmd_array,
2183 "merge",
2184 NULL,
2185 /* TRANSLATORS: command description */
2186 _("Merge multiple firmware files into one"),
2187 dfu_tool_merge);
2188 dfu_tool_add (priv->cmd_array,
2189 "set-vendor",
2190 NULL,
2191 /* TRANSLATORS: command description */
2192 _("Set vendor ID on firmware file"),
2193 dfu_tool_set_vendor);
2194 dfu_tool_add (priv->cmd_array,
2195 "set-product",
2196 NULL,
2197 /* TRANSLATORS: command description */
2198 _("Set product ID on firmware file"),
2199 dfu_tool_set_product);
2200 dfu_tool_add (priv->cmd_array,
2201 "set-address",
2202 NULL,
2203 /* TRANSLATORS: command description */
2204 _("Set element address on firmware file"),
2205 dfu_tool_set_address);
2206 dfu_tool_add (priv->cmd_array,
2207 "set-target-size",
2208 NULL,
2209 /* TRANSLATORS: command description */
2210 _("Set the firmware size for the target"),
2211 dfu_tool_set_target_size);
2212 dfu_tool_add (priv->cmd_array,
2213 "set-release",
2214 NULL,
2215 /* TRANSLATORS: command description */
2216 _("Set release version on firmware file"),
2217 dfu_tool_set_release);
2218 dfu_tool_add (priv->cmd_array,
2219 "set-alt-setting",
2220 NULL,
2221 /* TRANSLATORS: command description */
2222 _("Set alternative number on firmware file"),
2223 dfu_tool_set_alt_setting);
2224 dfu_tool_add (priv->cmd_array,
2225 "set-alt-setting-name",
2226 NULL,
2227 /* TRANSLATORS: command description */
2228 _("Set alternative name on firmware file"),
2229 dfu_tool_set_alt_setting_name);
2230 dfu_tool_add (priv->cmd_array,
2231 "attach",
2232 NULL,
2233 /* TRANSLATORS: command description */
2234 _("Attach DFU capable device back to runtime"),
2235 dfu_tool_attach);
2236 dfu_tool_add (priv->cmd_array,
2237 "read",
2238 NULL,
2239 /* TRANSLATORS: command description */
2240 _("Read firmware from device into a file"),
2241 dfu_tool_read);
2242 dfu_tool_add (priv->cmd_array,
2243 "read-alt",
2244 NULL,
2245 /* TRANSLATORS: command description */
2246 _("Read firmware from one partition into a file"),
2247 dfu_tool_read_alt);
2248 dfu_tool_add (priv->cmd_array,
2249 "write",
2250 NULL,
2251 /* TRANSLATORS: command description */
2252 _("Write firmware from file into device"),
2253 dfu_tool_write);
2254 dfu_tool_add (priv->cmd_array,
2255 "write-alt",
2256 NULL,
2257 /* TRANSLATORS: command description */
2258 _("Write firmware from file into one partition"),
2259 dfu_tool_write_alt);
2260 dfu_tool_add (priv->cmd_array,
2261 "list",
2262 NULL,
2263 /* TRANSLATORS: command description */
2264 _("List currently attached DFU capable devices"),
2265 dfu_tool_list);
2266 dfu_tool_add (priv->cmd_array,
2267 "detach",
2268 NULL,
2269 /* TRANSLATORS: command description */
2270 _("Detach currently attached DFU capable device"),
2271 dfu_tool_detach);
2272 dfu_tool_add (priv->cmd_array,
2273 "dump",
2274 NULL,
2275 /* TRANSLATORS: command description */
2276 _("Dump details about a firmware file"),
2277 dfu_tool_dump);
2278 dfu_tool_add (priv->cmd_array,
2279 "watch",
2280 NULL,
2281 /* TRANSLATORS: command description */
2282 _("Watch DFU devices being hotplugged"),
2283 dfu_tool_watch);
2284 dfu_tool_add (priv->cmd_array,
2285 "encrypt",
2286 NULL,
2287 /* TRANSLATORS: command description */
2288 _("Encrypt firmware data"),
2289 dfu_tool_encrypt);
2290 dfu_tool_add (priv->cmd_array,
2291 "decrypt",
2292 NULL,
2293 /* TRANSLATORS: command description */
2294 _("Decrypt firmware data"),
2295 dfu_tool_decrypt);
2296 dfu_tool_add (priv->cmd_array,
2297 "set-metadata",
2298 NULL,
2299 /* TRANSLATORS: command description */
2300 _("Sets metadata on a firmware file"),
2301 dfu_tool_set_metadata);
2302 dfu_tool_add (priv->cmd_array,
2303 "replace-data",
2304 NULL,
2305 /* TRANSLATORS: command description */
2306 _("Replace data in an existing firmware file"),
2307 dfu_tool_replace_data);
2308 dfu_tool_add (priv->cmd_array,
2309 "patch-create",
2310 NULL,
2311 /* TRANSLATORS: command description */
2312 _("Create a binary patch using two files"),
2313 dfu_tool_patch_create);
2314 dfu_tool_add (priv->cmd_array,
2315 "patch-apply",
2316 NULL,
2317 /* TRANSLATORS: command description */
2318 _("Apply a binary patch"),
2319 dfu_tool_patch_apply);
2320 dfu_tool_add (priv->cmd_array,
2321 "patch-dump",
2322 NULL,
2323 /* TRANSLATORS: command description */
2324 _("Dump information about a binary patch to the screen"),
2325 dfu_tool_patch_dump);
2326
2327 /* use animated progress bar */
2328 priv->progressbar = fu_progressbar_new ();
2329 fu_progressbar_set_length_percentage (priv->progressbar, 50);
2330 fu_progressbar_set_length_status (priv->progressbar, 20);
2331
2332 /* do stuff on ctrl+c */
2333 priv->cancellable = g_cancellable_new ();
2334 g_unix_signal_add_full (G_PRIORITY_DEFAULT,
2335 SIGINT,
2336 dfu_tool_sigint_cb,
2337 priv,
2338 NULL);
2339
2340 /* sort by command name */
2341 g_ptr_array_sort (priv->cmd_array,
2342 (GCompareFunc) dfu_tool_sort_command_name_cb);
2343
2344 /* get a list of the commands */
2345 context = g_option_context_new (NULL);
2346 cmd_descriptions = dfu_tool_get_descriptions (priv->cmd_array);
2347 g_option_context_set_summary (context, cmd_descriptions);
2348
2349 /* TRANSLATORS: DFU stands for device firmware update */
2350 g_set_application_name (_("DFU Utility"));
2351 g_option_context_add_main_entries (context, options, NULL);
2352 ret = g_option_context_parse (context, &argc, &argv, &error);
2353 if (!ret) {
2354 /* TRANSLATORS: the user didn't read the man page */
2355 g_print ("%s: %s\n", _("Failed to parse arguments"), error->message);
2356 return EXIT_FAILURE;
2357 }
2358
2359 /* set verbose? */
2360 if (verbose)
2361 g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
2362
2363 /* version */
2364 if (version) {
2365 g_print ("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
2366 return EXIT_SUCCESS;
2367 }
2368
2369 /* run the specified command */
2370 ret = dfu_tool_run (priv, argv[1], (gchar**) &argv[2], &error);
2371 if (!ret) {
2372 if (g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL)) {
2373 g_autofree gchar *tmp = NULL;
2374 tmp = g_option_context_get_help (context, TRUE, NULL);
2375 g_print ("%s\n\n%s", error->message, tmp);
2376 } else {
2377 g_print ("%s\n", error->message);
2378 }
2379 return EXIT_FAILURE;
2380 }
2381
2382 /* success/ */
2383 g_object_unref (priv->progressbar);
2384 return EXIT_SUCCESS;
2385 }
0 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
1 <!-- Please adjust the date whenever revising the manpage. -->
2 <!ENTITY date "<date>26 February,2015</date>">
3 <!ENTITY package "dfu-tool">
4 <!ENTITY gnu "<acronym>GNU</acronym>">
5 <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
6 ]>
7
8 <refentry>
9 <refentryinfo>
10 <address>
11 <email>richard@hughsie.com</email>;
12 </address>
13 <author>
14 <firstname>Richard</firstname>
15 <surname>Hughes</surname>
16 </author>
17 <copyright>
18 <year>2015</year>
19 <holder>Richard Hughes</holder>
20 </copyright>
21 &date;
22 </refentryinfo>
23 <refmeta>
24 <refentrytitle>dfu-tool</refentrytitle>
25 <manvolnum>1</manvolnum>
26 </refmeta>
27 <refnamediv>
28 <refname>&package;</refname>
29 <refpurpose>Device Firmware Upgrade Tool</refpurpose>
30 </refnamediv>
31 <refsynopsisdiv>
32 <cmdsynopsis>
33 <command>&package;</command>
34 <arg><option>--verbose</option></arg>
35 <arg><option>--version</option></arg>
36 <arg><option>--force</option></arg>
37 <arg><option>--device=VID:PID</option></arg>
38 <arg><option>--transfer-size=BYTES</option></arg>
39 </cmdsynopsis>
40 </refsynopsisdiv>
41 <refsect1>
42 <title>DESCRIPTION</title>
43 <para>
44 This manual page documents briefly the <command>&package;</command> command.
45 </para>
46 <para>
47 <command>&package;</command> allows a user to write various kinds of
48 firmware onto devices supporting the USB Device Firmware Upgrade protocol.
49 This tool can be used to switch the device from the normal runtime mode
50 to `DFU mode' which allows the user to read and write firmware.
51 Either the whole device can be written in one operation, or individual
52 `targets' can be specified with the alternative name or number.
53 </para>
54 <para>
55 All synchronous actions can be safely cancelled and on failure will return
56 errors with both a type and a full textual description.
57 <command>&package;</command> supports DFU 1.0, DFU 1.1 and the ST DfuSe
58 vendor extension, and handles many device `quirks' necessary for the
59 real-world implementations of <acronym>DFU</acronym>.
60 </para>
61 <para>
62 Additionally <command>&package;</command> can be used to convert firmware
63 from various different formats, or to modify details about the elements,
64 images and metadata contained inside the firmware file.
65 For example, you can easily convert DFU 1.1 firmware into the
66 vendor-specific DfuSe format, convert a Intel HEX file into a raw file
67 padded to a specific size, or add new copyright and licensing information
68 to an existing file.
69 Fields such as the vendor and product IDs can be changed, and the firmware
70 elements can be encrypted and decrypted using various different methods.
71 Merging two DfuSe files together is also possible, although specifying
72 different alt-setting numbers before merging is a good idea to avoid
73 confusion.
74 </para>
75 </refsect1>
76 <refsect1>
77 <title>OPTIONS</title>
78 <para>
79 This program follows the usual &gnu; command line syntax,
80 with long options starting with two dashes (<literal>-</literal>).
81 A summary of options is included below.
82 </para>
83 <variablelist>
84 <varlistentry>
85 <term>
86 <option>--help</option>
87 </term>
88 <listitem>
89 <para>Show summary of all the commands available for use.</para>
90 </listitem>
91 </varlistentry>
92 <varlistentry>
93 <term>
94 <option>--version</option>
95 </term>
96 <listitem>
97 <para>Show the version of <command>&package;</command> installed.</para>
98 </listitem>
99 </varlistentry>
100 <varlistentry>
101 <term>
102 <option>--verbose</option>
103 </term>
104 <listitem>
105 <para>Show extra debugging information.</para>
106 </listitem>
107 </varlistentry>
108 <varlistentry>
109 <term>
110 <option>--device=VID:PID</option>
111 </term>
112 <listitem>
113 <para>
114 If multiple DFU-capable devices are attached you can specify the
115 specific vendor and product ID of the DFU device you want to query.
116 </para>
117 </listitem>
118 </varlistentry>
119 <varlistentry>
120 <term>
121 <option>--transfer-size=BYTES</option>
122 </term>
123 <listitem>
124 <para>
125 Manually override the size of each USB transfer, which you may want
126 for unreliable hardware or when the device lies about the maximum
127 packet size it accepts.
128 </para>
129 </listitem>
130 </varlistentry>
131 <varlistentry>
132 <term>
133 <option>--force</option>
134 </term>
135 <listitem>
136 <para>
137 Force the operation, disregarding warnings or sanity checks like
138 file CRC and checksums.
139 This is useful if you really know what you are doing, or in the
140 specialised case of fuzz-testing the binary loaders.
141 </para>
142 </listitem>
143 </varlistentry>
144 </variablelist>
145 </refsect1>
146 <refsect1>
147 <title>DEVICE COMMANDS</title>
148 <para>
149 These commands are used to interface with DFU-capable devices.
150 </para>
151 <variablelist>
152 <varlistentry>
153 <term>
154 <option>list</option>
155 </term>
156 <listitem>
157 <para>
158 This command lists currently attached DFU capable devices.
159 Some devices do not support the official DFU <literal>runtime</literal>
160 mode and thus do not support auto-discovery using this command.
161 For those devices, putting the device into DFU mode manually (e.g. by
162 holding a button down when rebooting the device) will make it show
163 up here.
164 </para>
165 </listitem>
166 </varlistentry>
167 <varlistentry>
168 <term>
169 <option>detach</option>
170 </term>
171 <listitem>
172 <para>
173 This command detaches the currently attached DFU capable device into
174 a special programming mode.
175 Whilst the device is in this special <acronym>DFU</acronym> mode it
176 can not be used as a normal device.
177 For example, a printer will not accept documents when in DFU mode.
178 </para>
179 </listitem>
180 </varlistentry>
181 <varlistentry>
182 <term>
183 <option>attach</option>
184 </term>
185 <listitem>
186 <para>
187 This command attaches a DFU capable device back to runtime so it can
188 be used as a normal device.
189 Some devices do not support attaching, and need to be manually
190 disconnected and connected before changing modes.
191 </para>
192 </listitem>
193 </varlistentry>
194 <varlistentry>
195 <term>
196 <option>watch</option>
197 </term>
198 <listitem>
199 <para>
200 This command watches DFU devices being hotplugged and can be used to
201 verify <literal>libdfu</literal> matches up the runtime and DFU modes
202 when attaching and detaching.
203 Use <option>CTRL+C</option> to make this command quit.
204 </para>
205 </listitem>
206 </varlistentry>
207 <varlistentry>
208 <term>
209 <option>read FILENAME</option>
210 </term>
211 <listitem>
212 <para>
213 This command uploads all the firmware from device into a file.
214 If the device has multiple partitions exported as different alternative
215 sections then they will all be read into a multi-image DfuSe-format
216 file.
217 If you just want the contents of one partition, <option>read-alt</option>
218 is the command you want.
219 </para>
220 </listitem>
221 </varlistentry>
222 <varlistentry>
223 <term>
224 <option>read-alt FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID</option>
225 </term>
226 <listitem>
227 <para>
228 This command uploads firmware from one partition into a file.
229 You can specify the partition by either the ALT-ID or ALT-NAME if set.
230 </para>
231 <para>e.g. <command>&package; read-alt backup.dfu SRAM</command></para>
232 </listitem>
233 </varlistentry>
234 <varlistentry>
235 <term>
236 <option>write</option>
237 </term>
238 <listitem>
239 <para>
240 This command downloads firmware from a file into all possible
241 partitions of a device.
242 If you only want to write one partition, <option>write-alt</option>
243 is the command you want.
244 </para>
245 </listitem>
246 </varlistentry>
247 <varlistentry>
248 <term>
249 <option>write-alt FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID [IMAGE-ALT-NAME|IMAGE-ALT-ID]</option>
250 </term>
251 <listitem>
252 <para>
253 This command downloads firmware from the file into one partition.
254 You can specify the partition by either the ALT-ID or ALT-NAME if set.
255 </para>
256 <para>e.g. <command>&package; write-alt sram.dfu SRAM __SRAM</command></para>
257 </listitem>
258 </varlistentry>
259 </variablelist>
260 </refsect1>
261 <refsect1>
262 <title>FIRMWARE COMMANDS</title>
263 <para>
264 These commands are used to read and modify existing firmware files.
265 </para>
266 <variablelist>
267 <varlistentry>
268 <term>
269 <option>dump FILENAME</option>
270 </term>
271 <listitem>
272 <para>
273 This command dumps all know details about a firmware file.
274 The complete memory map is shown, along with any metadata or vendor
275 information about the firmware file.
276 </para>
277 </listitem>
278 </varlistentry>
279 <varlistentry>
280 <term>
281 <option>convert FORMAT FILE-IN FILE-OUT [SIZE]</option>
282 </term>
283 <listitem>
284 <para>
285 This command converts the firmware from one format to another, optionally
286 padding to a certain size.
287 Possible values for the destination <option>FORMAT</option> include:
288 <literal>raw</literal>, <literal>ihex</literal>,
289 <literal>dfu</literal> and <literal>dfuse</literal>.
290 The <option>FILE-IN</option> and <option>FILE-OUT</option> values can
291 be the same if the source file is to be overwritten.
292 Although padding increases the file size with no apparent advantages
293 it can be used to support devices that do not store the runtime image
294 size and where validation of the written firmware is required.
295 </para>
296 <para>e.g. <command>&package; convert dfu firmware.hex firmware.dfu 8000</command></para>
297 </listitem>
298 </varlistentry>
299 <varlistentry>
300 <term>
301 <option>encrypt FILENAME-IN FILENAME-OUT TYPE KEY</option>
302 </term>
303 <listitem>
304 <para>
305 This command encrypts firmware data.
306 Only the image contents are actually modified, the DFU footer and
307 DfuSe header are left unaltered.
308 Possible values for the destination <option>TYPE</option> include:
309 <literal>xtea</literal> and <literal>nop</literal>.
310 If the <option>KEY</option> is not of the required length it is used
311 as an input to a hash function which can produce a key of the
312 required size.
313 </para>
314 <para>e.g. <command>&package; encrypt firmware.dfu firmware.xdfu xtea deadbeef</command></para>
315 </listitem>
316 </varlistentry>
317 <varlistentry>
318 <term>
319 <option>decrypt FILENAME-IN FILENAME-OUT TYPE KEY</option>
320 </term>
321 <listitem>
322 <para>
323 This command decrypts firmware data.
324 Only the image contents are actually modified, the DFU footer and
325 DfuSe header are left unaltered.
326 Possible values for the destination <option>TYPE</option> include:
327 <literal>xtea</literal> and <literal>nop</literal>.
328 If the <option>KEY</option> is not of the required length it is used
329 as an input to a hash function which can produce a key of the
330 required size.
331 </para>
332 <para>e.g. <command>&package; decrypt firmware.xdfu firmware.dfu xtea deadbeef</command></para>
333 </listitem>
334 </varlistentry>
335 <varlistentry>
336 <term>
337 <option>merge FILE-OUT FILE1 FILE2 [FILE3...]</option>
338 </term>
339 <listitem>
340 <para>
341 This command merges multiple firmware files into one file.
342 Although you can merge files with the same ALT-ID or ALT-NAME this
343 probably isn't what you want to do.
344 </para>
345 <para>e.g. <command>&package; merge combined.dfu lib.dfu app.dfu</command></para>
346 </listitem>
347 </varlistentry>
348 <varlistentry>
349 <term>
350 <option>set-alt-setting FILE ALT-ID</option>
351 </term>
352 <listitem>
353 <para>
354 This command modifies the alternative number on firmware file.
355 </para>
356 <para>e.g. <command>&package; set-alt-setting firmware.dfu 1</command></para>
357 </listitem>
358 </varlistentry>
359 <varlistentry>
360 <term>
361 <option>set-alt-setting-name</option>
362 </term>
363 <listitem>
364 <para>
365 This command modifies the alternative name on firmware file.
366 </para>
367 <para>e.g. <command>&package; set-alt-setting-name firmware.dfu SRAM</command></para>
368 </listitem>
369 </varlistentry>
370 <varlistentry>
371 <term>
372 <option>set-metadata FILE KEY VALUE</option>
373 </term>
374 <listitem>
375 <para>
376 This command adds or modifies existing metadata on a firmware file.
377 NOTE: There is only very limited metadata storage space in DFU files,
378 so keys and values should be kept as short as possible.
379 In particular, the <literal>License</literal> value should be
380 specified in SPDX format.
381 </para>
382 <para>e.g. <command>&package; set-metadata firmware.dfu Licence GPL-2.0+</command></para>
383 </listitem>
384 </varlistentry>
385 <varlistentry>
386 <term>
387 <option>set-vendor FILE VID</option>
388 </term>
389 <listitem>
390 <para>
391 This command sets vendor ID on a firmware file that will be used to
392 match specific devices.
393 Values of <literal>ffff</literal> will match any device vendor.
394 </para>
395 <para>e.g. <command>&package; set-vendor firmware.dfu 273f</command></para>
396 </listitem>
397 </varlistentry>
398 <varlistentry>
399 <term>
400 <option>set-product FILE PID</option>
401 </term>
402 <listitem>
403 <para>
404 This command sets the product ID on a firmware file that will be used to
405 match specific devices.
406 Values of <literal>ffff</literal> will match any device product.
407 </para>
408 <para>e.g. <command>&package; set-product firmware.dfu 1004</command></para>
409 </listitem>
410 </varlistentry>
411 <varlistentry>
412 <term>
413 <option>set-release FILE RELEASE</option>
414 </term>
415 <listitem>
416 <para>
417 This command sets the release version on firmware file that will be used to
418 match specific devices.
419 Values of <literal>ffff</literal> will match any device release.
420 </para>
421 <para>e.g. <command>&package; set-release firmware.dfu ffff</command></para>
422 </listitem>
423 </varlistentry>
424 </variablelist>
425 </refsect1>
426 <refsect1>
427 <title>AUTHOR</title>
428 <para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
429 </para>
430 </refsect1>
431 </refentry>
432
433 <!-- Keep this comment at the end of the file
434 Local variables:
435 mode: sgml
436 sgml-omittag:t
437 sgml-shorttag:t
438 sgml-minimize-attributes:nil
439 sgml-always-quote-attributes:t
440 sgml-indent-step:2
441 sgml-indent-data:t
442 sgml-parent-document:nil
443 sgml-default-dtd-file:nil
444 sgml-exposed-tags:nil
445 sgml-local-catalogs:nil
446 sgml-local-ecat-files:nil
447 End:
448 -->
2121 #include "config.h"
2222
2323 #include <appstream-glib.h>
24 #include <libdfu/dfu.h>
2524
2625 #include "fu-plugin.h"
2726 #include "fu-plugin-vfuncs.h"
27
28 #include "dfu-context.h"
2829
2930 struct FuPluginData {
3031 DfuContext *context;
109110 }
110111 }
111112
113 static gboolean
114 dfu_device_open_no_refresh (DfuDevice *device, GError **error)
115 {
116 return dfu_device_open_full (device, DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH,
117 NULL, error);
118 }
119
112120 static void
113121 fu_plugin_dfu_device_added_cb (DfuContext *ctx,
114122 DfuDevice *device,
119127 g_autoptr(AsProfile) profile = as_profile_new ();
120128 g_autoptr(AsProfileTask) ptask = NULL;
121129 g_autoptr(FuDevice) dev = NULL;
130 g_autoptr(FuDeviceLocker) locker = NULL;
122131 g_autoptr(GError) error = NULL;
123132
124133 platform_id = dfu_device_get_platform_id (device);
144153 }
145154
146155 /* open device to get display name */
147 if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NO_AUTO_REFRESH,
148 NULL, &error)) {
156 locker = fu_device_locker_new_full (device,
157 (FuDeviceLockerFunc) dfu_device_open_no_refresh,
158 (FuDeviceLockerFunc) dfu_device_close,
159 &error);
160 if (locker == NULL) {
149161 g_warning ("Failed to open DFU device: %s", error->message);
150162 return;
151163 }
153165 if (display_name != NULL)
154166 fu_device_set_name (dev, display_name);
155167
156 /* we're done here */
157 if (!dfu_device_close (device, &error))
158 g_debug ("Failed to close %s: %s", platform_id, error->message);
168 /* this is a guess and can be overridden in the metainfo file */
169 fu_device_add_icon (dev, "drive-harddisk-usb");
159170
160171 /* attempt to add */
161172 fu_plugin_device_add (plugin, dev);
217228 DfuDevice *device;
218229 const gchar *platform_id;
219230 g_autoptr(DfuFirmware) dfu_firmware = NULL;
231 g_autoptr(FuDeviceLocker) locker = NULL;
220232 g_autoptr(GError) error_local = NULL;
221233
222234 /* get device */
234246 }
235247
236248 /* open it */
237 if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE,
238 NULL, &error_local)) {
249 locker = fu_device_locker_new_full (device,
250 (FuDeviceLockerFunc) dfu_device_open,
251 (FuDeviceLockerFunc) dfu_device_close,
252 &error_local);
253 if (locker == NULL) {
239254 g_set_error (error,
240255 FWUPD_ERROR,
241256 FWUPD_ERROR_INTERNAL,
262277 return FALSE;
263278
264279 /* we're done */
265 if (!dfu_device_close (device, &error_local)) {
266 g_set_error_literal (error,
267 FWUPD_ERROR,
268 FWUPD_ERROR_INTERNAL,
269 error_local->message);
270 return FALSE;
271 }
272280 fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE);
273281 return TRUE;
274282 }
284292 DfuDevice *device;
285293 const gchar *platform_id;
286294 g_autoptr(DfuFirmware) dfu_firmware = NULL;
295 g_autoptr(FuDeviceLocker) locker = NULL;
287296 g_autoptr(GError) error_local = NULL;
288297 GChecksumType checksum_types[] = {
289298 G_CHECKSUM_SHA1,
305314 }
306315
307316 /* open it */
308 if (!dfu_device_open (device, DFU_DEVICE_OPEN_FLAG_NONE,
309 NULL, &error_local)) {
317 locker = fu_device_locker_new_full (device,
318 (FuDeviceLockerFunc) dfu_device_open,
319 (FuDeviceLockerFunc) dfu_device_close,
320 &error_local);
321 if (locker == NULL) {
310322 g_set_error (error,
311323 FWUPD_ERROR,
312324 FWUPD_ERROR_INTERNAL,
328340 error);
329341 if (dfu_firmware == NULL)
330342 return FALSE;
331
332 /* we're done */
333 if (!dfu_device_close (device, &error_local)) {
334 g_set_error_literal (error,
335 FWUPD_ERROR,
336 FWUPD_ERROR_INTERNAL,
337 error_local->message);
338 return FALSE;
339 }
340343
341344 /* get the checksum */
342345 blob_fw = dfu_firmware_write_data (dfu_firmware, error);
0 :044000003DEF20F080
1 :10400800FACF01F0FBCF02F0E9CF03F0EACF04F0DA
2 :10401800E1CF05F0E2CF06F0D9CF07F0DACF08F00C
3 :10402800F3CF09F0F4CF0AF0F6CF0BF0F7CF0CF08E
4 :10403800F8CF0DF0F5CF0EF00EC0F5FF0DC0F8FF6C
5 :104048000CC0F7FF0BC0F6FF0AC0F4FF09C0F3FF6E
6 :1040580008C0DAFF07C0D9FF06C0E2FF05C0E1FFCC
7 :1040680004C0EAFF03C0E9FF02C0FBFF01C0FAFF7A
8 :1040780011003FEF20F0000142EF20F03DEF20F06B
9 :00000001FF
0 Fuzzing
1 =======
2
3 CC=afl-gcc meson --default-library=static ../
4 AFL_HARDEN=1 ninja
5 afl-fuzz -m 300 -i fuzzing -o findings ./plugins/dfu/dfu-tool --force dump @@
6 afl-fuzz -m 300 -i fuzzing-patch-dump -o findings ./plugins/dfu/dfu-tool --force patch-dump @@
7
8 Generating
9 ----------
10
11 mkdir -p fuzzing-patch-dump
12 echo -n hello > complete-replace.old
13 echo -n XXXXX > complete-replace.new
14 ./plugins/dfu/dfu-tool patch-create complete-replace.old complete-replace.new fuzzing-patch-dump/complete-replace.bdiff
15
16 echo -n helloworldhelloworldhelloworldhelloworld > grow-two-chunks.old
17 echo -n XelloXorldhelloworldhelloworldhelloworlXXX > grow-two-chunks.new
18 ./plugins/dfu/dfu-tool patch-create grow-two-chunks.old grow-two-chunks.new fuzzing-patch-dump/grow-two-chunks.bdiff
00 cargs = ['-DG_LOG_DOMAIN="FuPluginDfu"']
1
2 dfu = static_library(
3 'dfu',
4 sources : [
5 'dfu-cipher-xtea.c',
6 'dfu-common.c',
7 'dfu-context.c',
8 'dfu-device.c',
9 'dfu-element.c',
10 'dfu-firmware.c',
11 'dfu-format-dfu.c',
12 'dfu-format-dfuse.c',
13 'dfu-format-ihex.c',
14 'dfu-format-metadata.c',
15 'dfu-format-raw.c',
16 'dfu-image.c',
17 'dfu-patch.c',
18 'dfu-sector.c',
19 'dfu-target.c',
20 ],
21 dependencies : [
22 appstream_glib,
23 giounix,
24 libm,
25 gusb,
26 ],
27 c_args : cargs,
28 include_directories : [
29 include_directories('../..'),
30 include_directories('../../libfwupd'),
31 include_directories('../../src'),
32 ],
33 )
134
235 shared_module('fu_plugin_dfu',
336 sources : [
1851 dfu,
1952 ],
2053 )
54
55 executable(
56 'dfu-tool',
57 sources : [
58 'dfu-tool.c',
59 ],
60 include_directories : [
61 include_directories('..'),
62 include_directories('../..'),
63 include_directories('../../src'),
64 include_directories('../../libfwupd'),
65 ],
66 dependencies : [
67 appstream_glib,
68 giounix,
69 libm,
70 gusb,
71 ],
72 link_with : [
73 dfu,
74 fwupd,
75 libfwupdprivate,
76 ],
77 c_args : cargs,
78 install : true,
79 install_dir : get_option('bindir')
80 )
81
82 if get_option('enable-man')
83 docbook2man = find_program('docbook2man')
84 custom_target('dfu-tool-man',
85 input : 'dfu-tool.sgml',
86 output : 'dfu-tool.1',
87 command : [
88 docbook2man, '@INPUT@',
89 '--output', meson.current_build_dir(),
90 ],
91 install : true,
92 install_dir : join_paths(get_option('mandir'), 'man1'),
93 )
94 endif
95
96 if get_option('enable-tests')
97 testdatadir = join_paths(meson.current_source_dir(), 'tests')
98 cargs += '-DTESTDATADIR="' + testdatadir + '"'
99 e = executable(
100 'dfu-self-test',
101 sources : [
102 'dfu-self-test.c'
103 ],
104 include_directories : [
105 include_directories('..'),
106 include_directories('../..'),
107 include_directories('../../libfwupd'),
108 ],
109 dependencies : [
110 appstream_glib,
111 gio,
112 gusb,
113 libm,
114 ],
115 link_with : [
116 dfu,
117 fwupd,
118 libfwupdprivate,
119 ],
120 c_args : cargs
121 )
122 test('dfu-self-test', e)
123 endif
0 :044000003DEF20F080
1 :10400800FACF01F0FBCF02F0E9CF03F0EACF04F0DA
2 :10401800E1CF05F0E2CF06F0D9CF07F0DACF08F00C
3 :10402800F3CF09F0F4CF0AF0F6CF0BF0F7CF0CF08E
4 :10403800F8CF0DF0F5CF0EF00EC0F5FF0DC0F8FF6C
5 :104048000CC0F7FF0BC0F6FF0AC0F4FF09C0F3FF6E
6 :1040580008C0DAFF07C0D9FF06C0E2FF05C0E1FFCC
7 :1040680004C0EAFF03C0E9FF02C0FBFF01C0FAFF7A
8 :1040780011003FEF20F0000142EF20F03DEF20F06B
9 :00000001FF
3030 {
3131 FuDeviceEbitdoKind kind;
3232 GUsbDevice *usb_device;
33 FuDeviceLocker *usb_device_locker;
3334 guint32 serial[9];
3435 } FuDeviceEbitdoPrivate;
3536
107108 FuDeviceEbitdo *device = FU_DEVICE_EBITDO (object);
108109 FuDeviceEbitdoPrivate *priv = GET_PRIVATE (device);
109110
111 if (priv->usb_device_locker != NULL)
112 g_object_unref (priv->usb_device_locker);
110113 if (priv->usb_device != NULL)
111114 g_object_unref (priv->usb_device);
112115
342345 gdouble tmp;
343346 guint32 version_tmp = 0;
344347 guint32 serial_tmp[9];
345 guint i;
348 g_autoptr(FuDeviceLocker) locker = NULL;
349
350 /* already open */
351 if (priv->usb_device_locker != NULL)
352 return TRUE;
346353
347354 g_debug ("opening %s", fu_device_ebitdo_kind_to_string (priv->kind));
348 if (!g_usb_device_open (priv->usb_device, error))
355 locker = fu_device_locker_new (priv->usb_device, error);
356 if (locker == NULL)
349357 return FALSE;
350358 if (!g_usb_device_claim_interface (priv->usb_device, 0, /* 0 = idx? */
351359 G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
352360 error)) {
353 g_usb_device_close (priv->usb_device, NULL);
354361 return FALSE;
355362 }
356363
362369 0,
363370 NULL, 0, /* in */
364371 error)) {
365 g_usb_device_close (priv->usb_device, NULL);
366372 return FALSE;
367373 }
368374 if (!fu_device_ebitdo_receive (device,
369375 (guint8 *) &version_tmp,
370376 sizeof(version_tmp),
371377 error)) {
372 g_usb_device_close (priv->usb_device, NULL);
373378 return FALSE;
374379 }
375380 tmp = (gdouble) GUINT32_FROM_LE (version_tmp);
384389 FU_EBITDO_PKT_CMD_FW_GET_VERSION,
385390 NULL, 0, /* in */
386391 error)) {
387 g_usb_device_close (priv->usb_device, NULL);
388392 return FALSE;
389393 }
390394 if (!fu_device_ebitdo_receive (device,
391395 (guint8 *) &version_tmp,
392396 sizeof(version_tmp),
393397 error)) {
394 g_usb_device_close (priv->usb_device, NULL);
395398 return FALSE;
396399 }
397400 tmp = (gdouble) GUINT32_FROM_LE (version_tmp);
404407 0x00, /* cmd */
405408 NULL, 0,
406409 error)) {
407 g_usb_device_close (priv->usb_device, NULL);
408410 return FALSE;
409411 }
410412 memset (serial_tmp, 0x00, sizeof (serial_tmp));
411413 if (!fu_device_ebitdo_receive (device,
412414 (guint8 *) &serial_tmp, sizeof(serial_tmp),
413415 error)) {
414 g_usb_device_close (priv->usb_device, NULL);
415 return FALSE;
416 }
417 for (i = 0; i < 9; i++)
416 return FALSE;
417 }
418 for (guint i = 0; i < 9; i++)
418419 priv->serial[i] = GUINT32_FROM_LE (serial_tmp[i]);
419420
421 /* success */
422 priv->usb_device_locker = g_steal_pointer (&locker);
420423 return TRUE;
421424 }
422425
424427 fu_device_ebitdo_close (FuDeviceEbitdo *device, GError **error)
425428 {
426429 FuDeviceEbitdoPrivate *priv = GET_PRIVATE (device);
427 if (!g_usb_device_close (priv->usb_device, error))
428 return FALSE;
430 g_clear_object (&priv->usb_device_locker);
429431 return TRUE;
430432 }
431433
446448 FuEbitdoFirmwareHeader *hdr;
447449 const guint8 *payload_data;
448450 const guint chunk_sz = 32;
449 guint32 offset;
450451 guint32 payload_len;
451452 guint32 serial_new[3];
452 guint i;
453453 g_autoptr(GError) error_local = NULL;
454454 const guint32 app_key_index[16] = {
455455 0x186976e5, 0xcac67acd, 0x38f27fee, 0x0a4948f1,
484484 }
485485
486486 /* check if this is firmware */
487 for (i = 0; i < 4; i++) {
487 for (guint i = 0; i < 4; i++) {
488488 if (hdr->reserved[i] != 0x0) {
489489 g_set_error (error,
490490 G_IO_ERROR,
521521 /* flash the firmware in 32 byte blocks */
522522 payload_data = g_bytes_get_data (fw, NULL);
523523 payload_data += sizeof(FuEbitdoFirmwareHeader);
524 for (offset = 0; offset < payload_len; offset += chunk_sz) {
524 for (guint32 offset = 0; offset < payload_len; offset += chunk_sz) {
525525 if (g_getenv ("FU_EBITDO_DEBUG") != NULL) {
526526 g_debug ("writing %u bytes to 0x%04x of 0x%04x",
527527 chunk_sz, offset, payload_len);
620620 name = g_strdup_printf ("%s Gamepad",
621621 fu_device_ebitdo_kind_to_string (priv->kind));
622622 fu_device_set_name (FU_DEVICE (device), name);
623 fu_device_set_summary (FU_DEVICE (device),
624 "A resdesigned classic game controller");
623625 fu_device_set_vendor (FU_DEVICE (device), "8bitdo");
624626
625627 /* set vendor ID */
660662 {
661663 FuDeviceEbitdo *device;
662664 FuDeviceEbitdoPrivate *priv;
663 guint j;
664665 const FuEbitdoVidPid vidpids[] = {
665666 /* legacy VIDs */
666667 { 0x0483, 0x5750, FU_DEVICE_EBITDO_KIND_BOOTLOADER },
684685 };
685686
686687 /* set kind */
687 for (j = 0; vidpids[j].vid != 0x0000; j++) {
688 for (guint j = 0; vidpids[j].vid != 0x0000; j++) {
688689 if (g_usb_device_get_vid (usb_device) != vidpids[j].vid)
689690 continue;
690691 if (g_usb_device_get_pid (usb_device) != vidpids[j].pid)
3939 main (int argc, char **argv)
4040 {
4141 gsize len;
42 guint i;
4342 g_autofree guint8 *data = NULL;
4443 g_autoptr(FuDeviceEbitdo) dev = NULL;
44 g_autoptr(FuDeviceLocker) locker = NULL;
4545 g_autoptr(GBytes) fw = NULL;
4646 g_autoptr(GError) error = NULL;
4747 g_autoptr(GPtrArray) devices = NULL;
6363 }
6464 g_usb_context_enumerate (usb_ctx);
6565 devices = g_usb_context_get_devices (usb_ctx);
66 for (i = 0; i < devices->len; i++) {
66 for (guint i = 0; i < devices->len; i++) {
6767 GUsbDevice *usb_dev_tmp = g_ptr_array_index (devices, i);
6868 g_autoptr(FuDeviceEbitdo) dev_tmp = fu_device_ebitdo_new (usb_dev_tmp);
6969 if (dev_tmp != NULL) {
7979 }
8080
8181 /* open device */
82 if (!fu_device_ebitdo_open (dev, &error)) {
82 locker = fu_device_locker_new_full (dev,
83 (FuDeviceLockerFunc) fu_device_ebitdo_open,
84 (FuDeviceLockerFunc) fu_device_ebitdo_close,
85 &error);
86 if (locker == NULL) {
8387 g_print ("Failed to open USB device: %s\n", error->message);
8488 return 1;
8589 }
8690 g_print ("Device Firmware Ver: %s\n",
8791 fu_device_get_version (FU_DEVICE (dev)));
8892 g_print ("Device Verification ID:\n");
89 for (i = 0; i < 9; i++)
93 for (guint i = 0; i < 9; i++)
9094 g_print ("\t%u = 0x%08x\n", i, fu_device_ebitdo_get_serial(dev)[i]);
9195
9296 /* not in bootloader mode, so print what to do */
132136 return 1;
133137 }
134138
135 /* close device */
136 if (!fu_device_ebitdo_close (dev, &error)) {
137 g_print ("Failed to close USB device: %s\n", error->message);
138 return 1;
139 }
140
141139 /* success */
142140 g_print ("Now turn off the controller with the power button.\n");
143141
3737 g_autofree gchar *runtime_id = NULL;
3838 g_autoptr(AsProfile) profile = as_profile_new ();
3939 g_autoptr(AsProfileTask) ptask = NULL;
40 g_autoptr(FuDeviceLocker) locker = NULL;
4041 g_autoptr(FuDeviceEbitdo) dev = NULL;
4142
4243 /* ignore hubs */
5758 }
5859 fu_device_set_id (dev, platform_id);
5960
61 /* add a hardcoded icon name */
62 fu_device_add_icon (dev, "input-gaming");
63
6064 /* open the device */
61 if (!fu_device_ebitdo_open (dev, error))
65 locker = fu_device_locker_new_full (dev,
66 (FuDeviceLockerFunc) fu_device_ebitdo_open,
67 (FuDeviceLockerFunc) fu_device_ebitdo_close,
68 error);
69 if (locker == NULL)
6270 return FALSE;
6371 ebitdo_kind = fu_device_ebitdo_get_kind (dev);
64
65 /* close the device */
66 if (!fu_device_ebitdo_close (dev, error))
67 return FALSE;
6872
6973 /* only the bootloader can do the update */
7074 runtime_id = g_strdup_printf ("%s-runtime", platform_id);
109113 {
110114 GUsbContext *usb_ctx = fu_plugin_get_usb_context (plugin);
111115 const gchar *platform_id;
116 g_autoptr(FuDeviceLocker) locker = NULL;
112117 g_autoptr(FuDeviceEbitdo) ebitdo_dev = FU_DEVICE_EBITDO (dev);
113118 g_autoptr(GUsbDevice) usb_device = NULL;
114119
128133 }
129134
130135 /* write the firmware */
131 if (!fu_device_ebitdo_open (ebitdo_dev, error))
136 locker = fu_device_locker_new_full (ebitdo_dev,
137 (FuDeviceLockerFunc) fu_device_ebitdo_open,
138 (FuDeviceLockerFunc) fu_device_ebitdo_close,
139 error);
140 if (locker == NULL)
132141 return FALSE;
133142 fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE);
134143 if (!fu_device_ebitdo_write_firmware (ebitdo_dev, blob_fw,
136145 error))
137146 return FALSE;
138147 fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_RESTART);
139 if (!fu_device_ebitdo_close (ebitdo_dev, error))
140 return FALSE;
141148
142149 /* success */
143150 return TRUE;
0 subdir('altos')
10 subdir('dfu')
21 subdir('ebitdo')
32 subdir('raspberrypi')
65 subdir('udev')
76 subdir('unifying')
87 subdir('upower')
9 subdir('usb')
8
9 if get_option('enable-altos')
10 subdir('altos')
11 endif
1012
1113 if get_option('enable-amt')
1214 subdir('amt')
1416
1517 if get_option('enable-thunderbolt') and udev.found()
1618 subdir('thunderbolt')
19 subdir('thunderbolt-power')
1720 endif
1821
1922 if get_option('enable-colorhug')
3235 subdir('uefi')
3336 endif
3437
38 if get_option('enable-usb-fallback')
39 subdir('usb')
40 endif
41
217217 fu_device_set_id (device, "raspberry-pi");
218218 fu_device_add_guid (device, "raspberrypi");
219219 fu_device_set_name (device, "Raspberry Pi");
220 fu_device_set_vendor (device, "Raspberry Pi Foundation");
221 fu_device_set_summary (device, "A tiny and affordable computer");
222 fu_device_add_icon (device, "computer");
220223 fu_device_add_flag (device, FWUPD_DEVICE_FLAG_INTERNAL);
221224 fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
222225 fu_device_add_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC);
4343 g_autoptr(AsProfile) profile = as_profile_new ();
4444 g_autoptr(AsProfileTask) ptask = NULL;
4545 g_autoptr(FuDevice) dev = NULL;
46 g_autoptr(FuDeviceLocker) locker = NULL;
4647 g_autoptr(GError) error_local = NULL;
4748
4849 /* not the right kind of device */
6667 }
6768
6869 /* get exclusive access */
69 if (!g_usb_device_open (usb_device, &error_local)) {
70 locker = fu_device_locker_new (usb_device, &error_local);
71 if (locker == NULL) {
7072 g_warning ("failed to open device: %s", error_local->message);
7173 return;
7274 }
7476 G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
7577 &error_local)) {
7678 g_warning ("failed to claim interface: %s", error_local->message);
77 g_usb_device_close (usb_device, NULL);
7879 return;
7980 }
8081
9697 &error_local);
9798 if (!ret) {
9899 g_debug ("failed to do control transfer: %s", error_local->message);
99 g_usb_device_close (usb_device, NULL);
100100 return;
101101 }
102102 if (actual_len != 32) {
113113 &error_local);
114114 if (!ret) {
115115 g_debug ("failed to do EP1 transfer: %s", error_local->message);
116 g_usb_device_close (usb_device, NULL);
117116 return;
118117 }
119118 if (actual_len != 32) {
120119 g_warning ("only read %" G_GSIZE_FORMAT "bytes", actual_len);
121 g_usb_device_close (usb_device, NULL);
122120 return;
123121 }
124122
126124 dev = fu_device_new ();
127125 fu_device_set_id (dev, platform_id);
128126 fu_device_set_name (dev, "SteelSeries Rival 100");
127 fu_device_set_vendor (dev, "SteelSeries");
128 fu_device_set_summary (dev, "An optical gaming mouse");
129 fu_device_add_icon (dev, "input-mouse");
129130 version = g_strdup_printf ("%i.%i.%i",
130131 data[0], data[1], data[2]);
131132 fu_device_set_version (dev, version);
141142 G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
142143 &error_local)) {
143144 g_warning ("failed to release interface: %s", error_local->message);
144 g_usb_device_close (usb_device, NULL);
145145 return;
146146 }
147 if (!g_usb_device_close (usb_device, &error_local))
148 g_debug ("Failed to close: %s", error_local->message);
149147 fu_plugin_device_add (plugin, dev);
150148 fu_plugin_cache_add (plugin, platform_id, dev);
151149 }
116116 fu_device_set_id (dev, dev_id_str);
117117 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
118118 fu_device_set_name (dev, name);
119 fu_device_set_vendor (dev, "Synaptics");
120 fu_device_set_summary (dev, "Multi-Stream Transport Device");
121 fu_device_add_icon (dev, "computer");
119122 fu_device_set_version (dev, synapticsmst_device_get_version (device));
120123 fu_device_add_guid (dev, guid_str);
121124
133136 g_autofree gchar *dev_id_str = NULL;
134137 FuDevice *fu_dev = NULL;
135138 const gchar *aux_node;
136 guint8 layer = 0;
137 guint16 rad = 0;
138 guint8 j;
139139
140140 aux_node = synapticsmst_device_get_aux_node (device);
141141 if (!synapticsmst_device_open (device, error)) {
145145 return FALSE;
146146 }
147147
148 for (j = 0; j < 2; j++) {
149 layer = synapticsmst_device_get_layer (device) + 1;
150 rad = synapticsmst_device_get_rad (device) | (j << (2 * (layer - 1)));
148 for (guint8 j = 0; j < 2; j++) {
149 guint8 layer = synapticsmst_device_get_layer (device) + 1;
150 guint16 rad = synapticsmst_device_get_rad (device) | (j << (2 * (layer - 1)));
151151 dev_id_str = g_strdup_printf ("MST-REMOTE-%s-%u-%u",
152152 aux_node, layer, rad);
153153 fu_dev = fu_plugin_cache_lookup (plugin, dev_id_str);
9494 const gchar *description,
9595 FuUtilPrivateCb callback)
9696 {
97 guint i;
98 FuUtilItem *item;
99 g_auto (GStrv) names = NULL;
97 g_auto(GStrv) names = NULL;
10098
10199 g_return_if_fail (name != NULL);
102100 g_return_if_fail (description != NULL);
104102
105103 /* add each one */
106104 names = g_strsplit (name, ",", -1);
107 for (i = 0; names[i] != NULL; i++) {
108 item = g_new0 (FuUtilItem, 1);
105 for (guint i = 0; names[i] != NULL; i++) {
106 FuUtilItem *item = g_new0 (FuUtilItem, 1);
109107 item->name = g_strdup (names[i]);
110108 if (i == 0) {
111109 item->description = g_strdup (description);
123121 static gchar *
124122 synapticsmst_tool_get_descriptions (GPtrArray *array)
125123 {
126 guint i;
127 gsize j;
128124 gsize len;
129125 const gsize max_len = 31;
130 FuUtilItem *item;
131 GString *string;
126 GString *str;
132127
133128 /* print each command */
134 string = g_string_new ("");
135 for (i = 0; i < array->len; i++) {
136 item = g_ptr_array_index (array, i);
137 g_string_append (string, " ");
138 g_string_append (string, item->name);
129 str = g_string_new ("");
130 for (guint i = 0; i < array->len; i++) {
131 FuUtilItem *item = g_ptr_array_index (array, i);
132 g_string_append (str, " ");
133 g_string_append (str, item->name);
139134 len = strlen (item->name) + 2;
140135 if (item->arguments != NULL) {
141 g_string_append (string, " ");
142 g_string_append (string, item->arguments);
136 g_string_append (str, " ");
137 g_string_append (str, item->arguments);
143138 len += strlen (item->arguments) + 1;
144139 }
145140 if (len < max_len) {
146 for (j = len; j < max_len + 1; j++)
147 g_string_append_c (string, ' ');
148 g_string_append (string, item->description);
149 g_string_append_c (string, '\n');
141 for (gsize j = len; j < max_len + 1; j++)
142 g_string_append_c (str, ' ');
143 g_string_append (str, item->description);
144 g_string_append_c (str, '\n');
150145 } else {
151 g_string_append_c (string, '\n');
152 for (j = 0; j < max_len + 1; j++)
153 g_string_append_c (string, ' ');
154 g_string_append (string, item->description);
155 g_string_append_c (string, '\n');
146 g_string_append_c (str, '\n');
147 for (gsize j = 0; j < max_len + 1; j++)
148 g_string_append_c (str, ' ');
149 g_string_append (str, item->description);
150 g_string_append_c (str, '\n');
156151 }
157152 }
158153
159154 /* remove trailing newline */
160 if (string->len > 0)
161 g_string_set_size (string, string->len - 1);
162
163 return g_string_free (string, FALSE);
155 if (str->len > 0)
156 g_string_set_size (str, str->len - 1);
157
158 return g_string_free (str, FALSE);
164159 }
165160
166161 static gboolean
343338 guint8 device_index,
344339 GError **error)
345340 {
346 guint i;
347 FuUtilItem *item;
348
349341 /* find command */
350 for (i = 0; i < priv->cmd_array->len; i++) {
351 item = g_ptr_array_index (priv->cmd_array, i);
342 for (guint i = 0; i < priv->cmd_array->len; i++) {
343 FuUtilItem *item = g_ptr_array_index (priv->cmd_array, i);
352344 if (g_strcmp0 (item->name, command) == 0)
353345 return item->callback (priv, values, device_index, error);
354346 }
4242 }
4343
4444 gboolean
45 fu_plugin_startup (FuPlugin *plugin, GError **error)
46 {
47 if (g_getenv ("FWUPD_TESTS") == NULL) {
48 g_set_error (error,
49 FWUPD_ERROR,
50 FWUPD_ERROR_NOT_FOUND,
51 "Test plugin is only used for continuous integration");
52 return FALSE;
53 }
54 g_debug ("startup");
55 return TRUE;
56 }
57
58 gboolean
5945 fu_plugin_coldplug (FuPlugin *plugin, GError **error)
6046 {
6147 g_autoptr(FuDevice) device = NULL;
6349 fu_device_set_id (device, "FakeDevice");
6450 fu_device_add_guid (device, "b585990a-003e-5270-89d5-3705a17f9a43");
6551 fu_device_set_name (device, "Integrated_Webcam(TM)");
52 fu_device_add_icon (device, "preferences-desktop-keyboard");
6653 fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
67 fu_device_set_description (device, "A fake webcam");
54 fu_device_set_summary (device, "A fake webcam");
6855 fu_device_set_vendor (device, "ACME Corp.");
6956 fu_device_set_vendor_id (device, "USB:0x046D");
7057 fu_device_set_version_bootloader (device, "0.1.2");
230230 } else {
231231 fu_device_set_name (dev, name);
232232 }
233 }
234 if (is_host) {
235 fu_device_set_summary (dev, "Unmatched performance for high-speed I/O");
236 fu_device_add_icon (dev, "computer");
237 } else {
238 fu_device_add_icon (dev, "audio-card");
233239 }
234240
235241 vendor = g_udev_device_get_sysfs_attr (device, "vendor_name");
220220 static void
221221 mock_tree_dump (const MockTree *node, int level)
222222 {
223 guint i;
224223 if (node->path) {
225224 g_debug ("%*s * %s [%s] at %s", level, " ",
226225 node->device->name, node->uuid, node->path);
233232 node->device->name, node->uuid, node->sysfs_id);
234233 }
235234
236 for (i = 0; i < node->children->len; i++) {
235 for (guint i = 0; i < node->children->len; i++) {
237236 const MockTree *child = g_ptr_array_index (node->children, i);
238237 mock_tree_dump (child, level + 2);
239238 }
290289 MockTreePredicate predicate,
291290 gpointer data)
292291 {
293 guint i;
294
295292 if (predicate (node, data))
296293 return node;
297294
298 for (i = 0; i < node->children->len; i++) {
295 for (guint i = 0; i < node->children->len; i++) {
299296 const MockTree *child;
300297 const MockTree *match;
301298
629626 mock_tree_detach (MockTree *node)
630627 {
631628 UMockdevTestbed *bed;
632 guint i;
633629
634630 if (mock_tree_node_is_detached (node, NULL))
635631 return;
636632
637 for (i = 0; i < node->children->len; i++) {
633 for (guint i = 0; i < node->children->len; i++) {
638634 MockTree *child = g_ptr_array_index (node->children, i);
639635 mock_tree_detach (child);
640636 g_free (child->sysfs_parent);
0 /* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Dell Inc.
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "config.h"
22
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <gio/gio.h>
26 #include <glib.h>
27 #include <glib/gstdio.h>
28 #include <gudev/gudev.h>
29
30 #include "fu-plugin-vfuncs.h"
31 #include "fu-device-metadata.h"
32
33 #ifndef HAVE_GUDEV_232
34 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
35 #endif
36
37 /* empirically measured amount of time for the TBT device to come and go */
38 #define TBT_NEW_DEVICE_TIMEOUT 2 /* s */
39
40 struct FuPluginData {
41 GUdevClient *udev;
42 gchar *force_path;
43 gboolean needs_forcepower;
44 guint timeout_id;
45 };
46
47 static void
48 fu_plugin_thunderbolt_power_get_path (FuPlugin *plugin)
49 {
50 FuPluginData *data = fu_plugin_get_data (plugin);
51 g_autoptr(GList) devices = NULL;
52 const gchar *basepath;
53 const gchar *driver;
54
55 /* in case driver went away */
56 if (data->force_path != NULL) {
57 g_free (data->force_path);
58 data->force_path = NULL;
59 }
60
61 devices = g_udev_client_query_by_subsystem (data->udev, "wmi");
62 for (GList* l = devices; l != NULL; l = l->next) {
63 g_autofree gchar *built_path = NULL;
64 GUdevDevice *device = l->data;
65
66 /* only supports intel-wmi-thunderbolt for now */
67 driver = g_udev_device_get_driver (device);
68 if (g_strcmp0 (driver, "intel-wmi-thunderbolt") != 0)
69 continue;
70
71 /* check for the attribute to be loaded */
72 basepath = g_udev_device_get_sysfs_path (device);
73 if (basepath == NULL)
74 continue;
75 built_path = g_build_path ("/", basepath,
76 "force_power", NULL);
77 if (g_file_test (built_path, G_FILE_TEST_IS_REGULAR)) {
78 data->force_path = g_steal_pointer (&built_path);
79 g_debug ("Detected force power support at %s",
80 data->force_path);
81 break;
82 }
83 }
84 g_list_foreach (devices, (GFunc) g_object_unref, NULL);
85 }
86
87 static gboolean
88 fu_plugin_thunderbolt_power_supported (FuPlugin *plugin)
89 {
90 FuPluginData *data = fu_plugin_get_data (plugin);
91 return data->force_path != NULL;
92 }
93
94 static gboolean
95 fu_plugin_thunderbolt_power_set (FuPlugin *plugin, gboolean enable,
96 GError **error)
97 {
98 FuPluginData *data = fu_plugin_get_data (plugin);
99 gint fd;
100 gint ret;
101
102 if (!fu_plugin_thunderbolt_power_supported (plugin)) {
103 g_set_error (error,
104 FWUPD_ERROR,
105 FWUPD_ERROR_NOT_SUPPORTED,
106 "unable to set power to %d (missing kernel support)",
107 enable);
108 return FALSE;
109 }
110 g_debug ("Setting force power to %d", enable);
111 fd = g_open (data->force_path, O_WRONLY);
112 if (fd == -1) {
113 g_set_error (error,
114 FWUPD_ERROR,
115 FWUPD_ERROR_INTERNAL,
116 "failed to open %s", data->force_path);
117 return FALSE;
118 }
119 ret = write (fd, enable ? "1" : "0", 1);
120 if (ret < 1) {
121 g_set_error (error, G_IO_ERROR,
122 g_io_error_from_errno (errno),
123 "could not write to force_power': %s",
124 g_strerror (errno));
125 g_close (fd, NULL);
126 return FALSE;
127 }
128 return g_close (fd, error);
129 }
130
131 static gboolean
132 fu_plugin_thunderbolt_power_reset_cb (gpointer user_data)
133 {
134 FuPlugin *plugin = FU_PLUGIN (user_data);
135 FuPluginData *data = fu_plugin_get_data (plugin);
136
137 if (!fu_plugin_thunderbolt_power_set (plugin, FALSE, NULL))
138 g_warning ("failed to reset thunderbolt power");
139 data->timeout_id = 0;
140 return FALSE;
141 }
142
143 static gboolean
144 udev_uevent_cb (GUdevClient *udev,
145 const gchar *action,
146 GUdevDevice *device,
147 gpointer user_data)
148 {
149 FuPlugin *plugin = FU_PLUGIN(user_data);
150
151 if (action == NULL)
152 return TRUE;
153
154 g_debug ("uevent for %s: %s", g_udev_device_get_sysfs_path (device), action);
155
156 /* intel-wmi-thunderbolt has been loaded/unloaded */
157 if (g_str_equal (action, "change")) {
158 fu_plugin_thunderbolt_power_get_path (plugin);
159 if (fu_plugin_thunderbolt_power_supported (plugin)) {
160 fu_plugin_set_enabled (plugin, TRUE);
161 fu_plugin_recoldplug (plugin);
162 } else {
163 fu_plugin_set_enabled (plugin, FALSE);
164 }
165 }
166
167 return TRUE;
168 }
169
170 /* virtual functions */
171
172 void
173 fu_plugin_init (FuPlugin *plugin)
174 {
175 FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
176 const gchar *subsystems[] = { "wmi", NULL };
177
178 data->udev = g_udev_client_new (subsystems);
179 g_signal_connect (data->udev, "uevent",
180 G_CALLBACK (udev_uevent_cb), plugin);
181 /* initially set to true, will wait for a device_register to reset */
182 data->needs_forcepower = TRUE;
183
184 /* determines whether to run device_registered */
185 fu_plugin_thunderbolt_power_get_path (plugin);
186
187 /* make sure it's tried to coldplug */
188 fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "thunderbolt");
189 }
190
191 void
192 fu_plugin_destroy (FuPlugin *plugin)
193 {
194 FuPluginData *data = fu_plugin_get_data (plugin);
195 if (data->timeout_id != 0)
196 g_source_remove (data->timeout_id);
197 g_object_unref (data->udev);
198 g_free (data->force_path);
199 }
200
201 void
202 fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device)
203 {
204 FuPluginData *data = fu_plugin_get_data (plugin);
205
206 /* thunderbolt plugin */
207 if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") == 0 &&
208 fu_plugin_thunderbolt_power_supported (plugin)) {
209 data->needs_forcepower = FALSE;
210 if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) {
211 fu_device_set_metadata_boolean (device,
212 FU_DEVICE_METADATA_TBT_CAN_FORCE_POWER,
213 TRUE);
214 }
215 }
216 }
217
218 gboolean
219 fu_plugin_update_prepare (FuPlugin *plugin,
220 FuDevice *device,
221 GError **error)
222 {
223 FuPluginData *data = fu_plugin_get_data (plugin);
224 g_autoptr(GUdevDevice) udevice = NULL;
225 const gchar *devpath;
226
227 /* only run for thunderbolt plugin */
228 if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") != 0)
229 return TRUE;
230
231 devpath = fu_device_get_metadata (device, "sysfs-path");
232
233 udevice = g_udev_client_query_by_sysfs_path (data->udev, devpath);
234 if (udevice != NULL) {
235 data->needs_forcepower = FALSE;
236 return TRUE;
237 }
238 if (!fu_plugin_thunderbolt_power_set (plugin, TRUE, error))
239 return FALSE;
240
241 data->needs_forcepower = TRUE;
242 /* wait for the device to come back onto the bus */
243 g_usleep (TBT_NEW_DEVICE_TIMEOUT * G_USEC_PER_SEC);
244
245 return TRUE;
246 }
247
248 gboolean
249 fu_plugin_update_cleanup (FuPlugin *plugin,
250 FuDevice *device,
251 GError **error)
252 {
253 FuPluginData *data = fu_plugin_get_data (plugin);
254
255 /* only run for thunderbolt plugin */
256 if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") != 0)
257 return TRUE;
258
259 if (data->needs_forcepower &&
260 !fu_plugin_thunderbolt_power_set (plugin, FALSE, error))
261 return FALSE;
262 return TRUE;
263 }
264
265 gboolean
266 fu_plugin_coldplug (FuPlugin *plugin, GError **error)
267 {
268 FuPluginData *data = fu_plugin_get_data (plugin);
269
270 if (!fu_plugin_thunderbolt_power_supported (plugin)) {
271 g_set_error (error,
272 FWUPD_ERROR,
273 FWUPD_ERROR_NOT_SUPPORTED,
274 "missing kernel support for intel-wmi-thunderbolt");
275 return FALSE;
276 }
277
278 /* this means no devices were found at coldplug by thunderbolt plugin */
279 if (data->needs_forcepower) {
280 if (!fu_plugin_thunderbolt_power_set (plugin, TRUE, error))
281 return FALSE;
282 /* in case this was a re-coldplug */
283 if (data->timeout_id != 0)
284 g_source_remove (data->timeout_id);
285
286 /* reset force power to off after enough time to enumerate */
287 data->timeout_id =
288 g_timeout_add (TBT_NEW_DEVICE_TIMEOUT * 10000,
289 fu_plugin_thunderbolt_power_reset_cb,
290 plugin);
291 }
292
293 return TRUE;
294 }
0 cargs = ['-DG_LOG_DOMAIN="FuPluginThunderboltPower"']
1
2 fu_plugin_thunderbolt_power = shared_module('fu_plugin_thunderbolt_power',
3 sources : [
4 'fu-plugin-thunderbolt-power.c',
5 ],
6 include_directories : [
7 include_directories('../..'),
8 include_directories('../../src'),
9 include_directories('../../libfwupd'),
10 ],
11 install : true,
12 install_dir: plugin_dir,
13 c_args : cargs,
14 dependencies : [
15 plugin_deps,
16 gudev,
17 ],
18 )
145145 guid = g_udev_device_get_property (device, "FWUPD_GUID");
146146 if (guid == NULL)
147147 return;
148 if (g_strcmp0 (g_udev_device_get_subsystem (device), "usb") == 0)
149 return;
148150
149151 /* get data */
150152 ptask = as_profile_start (profile, "FuPluginUdev:client-add{%s}", guid);
175177 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
176178 fu_device_set_id (dev, id);
177179 fu_device_add_guid (dev, guid);
180 fu_device_add_icon (dev, "audio-card");
178181 display_name = g_udev_device_get_property (device, "FWUPD_MODEL");
179182 if (display_name == NULL)
180183 display_name = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE");
5858 static gboolean
5959 fu_fuzzer_write_files (GHashTable *hash, GError **error)
6060 {
61 GList *l;
6261 GString *str;
6362 g_autoptr(GList) keys = g_hash_table_get_keys (hash);
6463
65 for (l = keys; l != NULL; l = l->next) {
64 for (GList *l = keys; l != NULL; l = l->next) {
6665 g_autofree gchar *filename = NULL;
6766 const gchar *fn = l->data;
6867 filename = g_build_filename ("fuzzing", fn, NULL);
163162 int
164163 main (int argc, char *argv[])
165164 {
166 guint i;
167165 gboolean verbose = FALSE;
168166 g_autoptr(GError) error_parse = NULL;
169167 g_autoptr(GOptionContext) context = NULL;
189187 g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
190188 if (g_strcmp0 (argv[1], "rom") == 0) {
191189 gboolean all_successful = TRUE;
192 for (i = 2; i < (guint) argc; i++) {
190 for (guint i = 2; i < (guint) argc; i++) {
193191 g_autoptr(GError) error = NULL;
194192 if (!fu_fuzzer_rom_parse (argv[i], &error)) {
195193 g_print ("Failed to parse %s: %s\n",
132132 }
133133
134134 static gchar *
135 fu_rom_get_hex_dump (guint8 *buffer, gssize sz)
135 fu_rom_get_hex_dump (guint8 *buffer, guint32 sz)
136136 {
137137 GString *str = g_string_new ("");
138 if (sz <= 0)
139 return NULL;
140 for (guint i = 0; i < (guint) sz; i++)
138 for (guint32 i = 0; i < sz; i++)
141139 g_string_append_printf (str, "%02x ", buffer[i]);
142140 g_string_append (str, " ");
143 for (guint i = 0; i < (guint) sz; i++) {
141 for (guint32 i = 0; i < sz; i++) {
144142 gchar tmp = '?';
145143 if (g_ascii_isprint (buffer[i]))
146144 tmp = (gchar) buffer[i];
420418 }
421419
422420 static FuRomPciHeader *
423 fu_rom_pci_get_header (guint8 *buffer, gssize sz)
421 fu_rom_pci_get_header (guint8 *buffer, guint32 sz)
424422 {
425423 FuRomPciHeader *hdr;
426424
443441 /* fix up misreporting */
444442 if (hdr->rom_len == 0) {
445443 g_debug ("fixing up last image size");
446 hdr->rom_len = (guint32) sz;
444 hdr->rom_len = sz;
447445 }
448446
449447 /* copy this locally to the header */
567565 {
568566 FuRomPrivate *priv = GET_PRIVATE (rom);
569567 FuRomPciHeader *hdr = NULL;
570 gssize sz = buffer_sz;
568 guint32 sz = buffer_sz;
571569 guint32 jump = 0;
572570 guint32 hdr_sz = 0;
573571 g_autofree gchar *id = NULL;
607605 hdr->code_type = 0x00;
608606 hdr->last_image = 0x80;
609607 hdr->rom_offset = hdr_sz + jump;
610 hdr->rom_len = (guint32) (sz - hdr->rom_offset);
608 hdr->rom_len = sz - hdr->rom_offset;
611609 hdr->rom_data = g_memdup (&buffer[hdr->rom_offset], hdr->rom_len);
612610 hdr->image_len = hdr->rom_len;
613611 g_ptr_array_add (priv->hdrs, hdr);
00 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
11 *
2 * Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
2 * Copyright (C) 2016-2017 Richard Hughes <richard@hughsie.com>
33 *
44 * Licensed under the GNU General Public License Version 2
55 *
2929 #include "fu-plugin.h"
3030 #include "fu-plugin-vfuncs.h"
3131
32 #ifndef UX_CAPSULE_GUID
33 #define UX_CAPSULE_GUID EFI_GUID(0x3b8c8162,0x188c,0x46a4,0xaec9,0xbe,0x43,0xf1,0xd6,0x56,0x97)
34 #endif
35
36 void
37 fu_plugin_init (FuPlugin *plugin)
38 {
39 fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "upower");
40 }
41
42 static gchar *
43 fu_plugin_uefi_guid_to_string (efi_guid_t *guid_raw)
44 {
45 g_autofree gchar *guid = g_strdup ("00000000-0000-0000-0000-000000000000");
46 if (efi_guid_to_str (guid_raw, &guid) < 0)
47 return NULL;
48 return g_steal_pointer (&guid);
49 }
50
3251 static fwup_resource *
3352 fu_plugin_uefi_find (fwup_resource_iter *iter, const gchar *guid_str, GError **error)
3453 {
3554 efi_guid_t *guid_raw;
3655 fwup_resource *re_matched = NULL;
3756 fwup_resource *re = NULL;
38 g_autofree gchar *guid_str_tmp = NULL;
3957
4058 /* get the hardware we're referencing */
41 guid_str_tmp = g_strdup ("00000000-0000-0000-0000-000000000000");
4259 while (fwup_resource_iter_next (iter, &re) > 0) {
60 g_autofree gchar *guid_tmp = NULL;
4361
4462 /* convert to strings */
4563 fwup_get_guid (re, &guid_raw);
46 if (efi_guid_to_str (guid_raw, &guid_str_tmp) < 0) {
64 guid_tmp = fu_plugin_uefi_guid_to_string (guid_raw);
65 if (guid_tmp == NULL) {
4766 g_warning ("failed to convert guid to string");
4867 continue;
4968 }
5069
5170 /* FIXME: also match hardware_instance too */
52 if (g_strcmp0 (guid_str, guid_str_tmp) == 0) {
71 if (g_strcmp0 (guid_str, guid_tmp) == 0) {
5372 re_matched = re;
5473 break;
5574 }
6786 return re_matched;
6887 }
6988
89 static fwup_resource *
90 fu_plugin_uefi_find_raw (fwup_resource_iter *iter, efi_guid_t *guid)
91 {
92 fwup_resource *re_matched = NULL;
93 fwup_resource *re = NULL;
94 while (fwup_resource_iter_next (iter, &re) > 0) {
95 efi_guid_t *guid_tmp;
96 fwup_get_guid (re, &guid_tmp);
97 if (efi_guid_cmp (guid_tmp, guid) == 0) {
98 re_matched = re;
99 break;
100 }
101 }
102 return re_matched;
103 }
104
70105 static void
71106 _fwup_resource_iter_free (fwup_resource_iter *iter)
72107 {
97132 return TRUE;
98133 }
99134
100 /* only in git master */
101 #ifndef FWUP_LAST_ATTEMPT_STATUS_SUCCESS
102 #define FWUP_LAST_ATTEMPT_STATUS_SUCCESS 0x00000000
103 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL 0x00000001
104 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES 0x00000002
105 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION 0x00000003
106 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT 0x00000004
107 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR 0x00000005
108 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC 0x00000006
109 #define FWUP_LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT 0x00000007
110 #endif
111
112 static const gchar *
113 fu_plugin_uefi_last_attempt_status_to_str (guint32 status)
114 {
115 if (status == FWUP_LAST_ATTEMPT_STATUS_SUCCESS)
116 return "Success";
117 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL)
118 return "Unsuccessful";
119 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES)
120 return "Insufficient resources";
121 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION)
122 return "Incorrect version";
123 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT)
124 return "Invalid firmware format";
125 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR)
126 return "Authentication signing error";
127 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC)
128 return "AC power required";
129 if (status == FWUP_LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT)
130 return "Battery level is too low";
131 return NULL;
132 }
133
134135 gboolean
135136 fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error)
136137 {
139140 guint32 status = 0;
140141 guint32 version = 0;
141142 time_t when = 0;
142 g_autofree gchar *version_str = NULL;
143143 g_autoptr(fwup_resource_iter) iter = NULL;
144144
145145 /* get the hardware we're referencing */
155155 fu_device_get_guid_default (device));
156156 return FALSE;
157157 }
158 version_str = g_strdup_printf ("%u", version);
159 fu_device_set_update_version (device, version_str);
160158 if (status == FWUP_LAST_ATTEMPT_STATUS_SUCCESS) {
161159 fu_device_set_update_state (device, FWUPD_UPDATE_STATE_SUCCESS);
162160 } else {
161 g_autofree gchar *err_msg = NULL;
162 g_autofree gchar *version_str = g_strdup_printf ("%u", version);
163163 fu_device_set_update_state (device, FWUPD_UPDATE_STATE_FAILED);
164 tmp = fu_plugin_uefi_last_attempt_status_to_str (status);
165 if (tmp != NULL)
166 fu_device_set_update_error (device, tmp);
164 tmp = fwup_last_attempt_status_to_string (status);
165 if (tmp == NULL) {
166 err_msg = g_strdup_printf ("failed to update to %s",
167 version_str);
168 } else {
169 err_msg = g_strdup_printf ("failed to update to %s: %s",
170 version_str, tmp);
171 }
172 fu_device_set_update_error (device, err_msg);
167173 }
168174 return TRUE;
175 }
176
177 static gboolean
178 fu_plugin_uefi_update_resource (fwup_resource *re,
179 guint64 hardware_instance,
180 GBytes *blob,
181 GError **error)
182 {
183 int rc;
184 rc = fwup_set_up_update_with_buf (re, hardware_instance,
185 g_bytes_get_data (blob, NULL),
186 g_bytes_get_size (blob));
187 if (rc < 0) {
188 g_autoptr(GString) str = g_string_new (NULL);
189 rc = 1;
190 for (int i = 0; rc > 0; i++) {
191 char *filename = NULL;
192 char *function = NULL;
193 char *message = NULL;
194 int line = 0;
195 int err = 0;
196
197 rc = efi_error_get (i, &filename, &function, &line,
198 &message, &err);
199 if (rc <= 0)
200 break;
201 g_string_append_printf (str, "{error #%d} %s:%d %s(): %s: %s\t",
202 i, filename, line, function,
203 message, strerror (err));
204 }
205 if (str->len > 1)
206 g_string_truncate (str, str->len - 1);
207 g_set_error (error,
208 FWUPD_ERROR,
209 FWUPD_ERROR_NOT_SUPPORTED,
210 "UEFI firmware update failed: %s",
211 str->str);
212 return FALSE;
213 }
214 return TRUE;
215 }
216
217 static GBytes *
218 fu_plugin_uefi_get_splash_data (guint width, guint height, GError **error)
219 {
220 const gchar * const *langs = g_get_language_names ();
221 const gchar *localedir = LOCALEDIR;
222 const gsize chunk_size = 1024 * 1024;
223 gsize buf_idx = 0;
224 gsize buf_sz = chunk_size;
225 gssize len;
226 g_autofree gchar *basename = NULL;
227 g_autofree guint8 *buf = NULL;
228 g_autoptr(GBytes) compressed_data = NULL;
229 g_autoptr(GConverter) conv = NULL;
230 g_autoptr(GInputStream) stream_compressed = NULL;
231 g_autoptr(GInputStream) stream_raw = NULL;
232
233 /* ensure this is sane */
234 if (!g_str_has_prefix (localedir, "/"))
235 localedir = "/usr/share/locale";
236
237 /* find the closest locale match, falling back to `en` and `C` */
238 basename = g_strdup_printf ("fwupd-%u-%u.bmp.gz", width, height);
239 for (guint i = 0; langs[i] != NULL; i++) {
240 g_autofree gchar *fn = NULL;
241 if (g_str_has_suffix (langs[i], ".UTF-8"))
242 continue;
243 fn = g_build_filename (localedir, langs[i],
244 "LC_IMAGES", basename, NULL);
245 if (g_file_test (fn, G_FILE_TEST_EXISTS)) {
246 compressed_data = fu_common_get_contents_bytes (fn, error);
247 if (compressed_data == NULL)
248 return NULL;
249 break;
250 }
251 g_debug ("no %s found", fn);
252 }
253
254 /* we found nothing */
255 if (compressed_data == NULL) {
256 g_autofree gchar *tmp = g_strjoinv (",", (gchar **) langs);
257 g_set_error (error,
258 FWUPD_ERROR,
259 FWUPD_ERROR_NOT_SUPPORTED,
260 "failed to get splash file for %s in %s",
261 tmp, localedir);
262 return NULL;
263 }
264
265 /* decompress data */
266 stream_compressed = g_memory_input_stream_new_from_bytes (compressed_data);
267 conv = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
268 stream_raw = g_converter_input_stream_new (stream_compressed, conv);
269 buf = g_malloc0 (buf_sz);
270 while ((len = g_input_stream_read (stream_raw,
271 buf + buf_idx,
272 buf_sz - buf_idx,
273 NULL, error)) > 0) {
274 buf_idx += len;
275 if (buf_sz - buf_idx < chunk_size) {
276 buf_sz += chunk_size;
277 buf = g_realloc (buf, buf_sz);
278 }
279 }
280 if (len < 0) {
281 g_prefix_error (error, "failed to decompress file: ");
282 return NULL;
283 }
284 g_debug ("decompressed image to %" G_GSIZE_FORMAT "kb", buf_idx / 1024);
285 return g_bytes_new_take (g_steal_pointer (&buf), buf_idx);
286 }
287
288 static gboolean
289 fu_plugin_uefi_update_splash (GError **error)
290 {
291 fwup_resource *re = NULL;
292 guint best_idx = G_MAXUINT;
293 guint32 lowest_border_pixels = G_MAXUINT;
294 #ifdef HAVE_FWUP_GET_BGRT_INFO
295 int rc;
296 #endif
297 guint32 screen_height = 768;
298 guint32 screen_width = 1024;
299 g_autoptr(fwup_resource_iter) iter = NULL;
300 g_autoptr(GBytes) image_bmp = NULL;
301 struct {
302 guint32 width;
303 guint32 height;
304 } sizes[] = {
305 { 640, 480 }, /* matching the sizes in po/make-images */
306 { 800, 600 },
307 { 1024, 768 },
308 { 1920, 1080 },
309 { 3840, 2160 },
310 { 5120, 2880 },
311 { 5688, 3200 },
312 { 7680, 4320 },
313 { 0, 0 }
314 };
315
316 /* is this supported? */
317 fwup_resource_iter_create (&iter);
318 re = fu_plugin_uefi_find_raw (iter, &UX_CAPSULE_GUID);
319 if (re == NULL)
320 return TRUE;
321
322 /* get the boot graphics resource table data */
323 #ifdef HAVE_FWUP_GET_BGRT_INFO
324 rc = fwup_get_ux_capsule_info (&screen_width, &screen_height);
325 if (rc < 0) {
326 g_set_error_literal (error,
327 FWUPD_ERROR,
328 FWUPD_ERROR_NOT_SUPPORTED,
329 "failed to get BGRT screen size");
330 return FALSE;
331 }
332 g_debug ("BGRT screen size %" G_GUINT32_FORMAT " x%" G_GUINT32_FORMAT,
333 screen_width, screen_height);
334 #endif
335
336 /* find the 'best sized' pre-generated image */
337 for (guint i = 0; sizes[i].width != 0; i++) {
338 guint32 border_pixels;
339
340 /* disregard any images that are bigger than the screen */
341 if (sizes[i].width > screen_width)
342 continue;
343 if (sizes[i].height > screen_height)
344 continue;
345
346 /* is this the best fit for the display */
347 border_pixels = (screen_width * screen_height) -
348 (sizes[i].width * sizes[i].height);
349 if (border_pixels < lowest_border_pixels) {
350 lowest_border_pixels = border_pixels;
351 best_idx = i;
352 }
353 }
354 if (best_idx == G_MAXUINT) {
355 g_set_error_literal (error,
356 FWUPD_ERROR,
357 FWUPD_ERROR_NOT_SUPPORTED,
358 "failed to find a suitable image to use");
359 return FALSE;
360 }
361
362 /* get the raw data */
363 image_bmp = fu_plugin_uefi_get_splash_data (sizes[best_idx].width,
364 sizes[best_idx].height,
365 error);
366 if (image_bmp == NULL)
367 return FALSE;
368
369 /* perform the upload */
370 return fu_plugin_uefi_update_resource (re, 0, image_bmp, error);
169371 }
170372
171373 gboolean
177379 {
178380 fwup_resource *re = NULL;
179381 guint64 hardware_instance = 0; /* FIXME */
180 int rc;
181382 g_autoptr(fwup_resource_iter) iter = NULL;
182383 const gchar *str;
183384 g_autofree gchar *efibootmgr_path = NULL;
184385 g_autofree gchar *boot_variables = NULL;
386 g_autoptr(GError) error_splash = NULL;
185387
186388 /* get the hardware we're referencing */
187389 fwup_resource_iter_create (&iter);
196398 /* perform the update */
197399 g_debug ("Performing UEFI capsule update");
198400 fu_plugin_set_status (plugin, FWUPD_STATUS_SCHEDULING);
199 rc = fwup_set_up_update_with_buf (re, hardware_instance,
200 g_bytes_get_data (blob_fw, NULL),
201 g_bytes_get_size (blob_fw));
202 if (rc < 0) {
203 g_autoptr(GString) err_string = g_string_new ("UEFI firmware update failed:\n");
204
205 rc = 1;
206 for (int i =0; rc > 0; i++) {
207 char *filename = NULL;
208 char *function = NULL;
209 char *message = NULL;
210 int line = 0;
211 int err = 0;
212
213 rc = efi_error_get (i, &filename, &function, &line, &message, &err);
214 if (rc <= 0)
215 break;
216 g_string_append_printf (err_string,
217 "{error #%d} %s:%d %s(): %s: %s \n",
218 i, filename, line, function, message, strerror(err));
219 }
220 g_set_error_literal (error,
221 FWUPD_ERROR,
222 FWUPD_ERROR_NOT_SUPPORTED,
223 err_string->str);
224 return FALSE;
225 }
401 if (!fu_plugin_uefi_update_splash (&error_splash)) {
402 g_warning ("failed to upload BGRT splash text: %s",
403 error_splash->message);
404 }
405 if (!fu_plugin_uefi_update_resource (re, hardware_instance, blob_fw, error))
406 return FALSE;
226407
227408 /* record boot information to system log for future debugging */
228409 efibootmgr_path = g_find_program_in_path ("efibootmgr");
237418 }
238419
239420 static AsVersionParseFlag
240 fu_plugin_uefi_get_version_format (FuPlugin *plugin)
421 fu_plugin_uefi_get_version_format_for_type (FuPlugin *plugin, guint32 uefi_type)
241422 {
242423 const gchar *content;
424
425 /* we have no information for devices */
426 if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE)
427 return AS_VERSION_PARSE_FLAG_USE_TRIPLET;
243428
244429 content = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER);
245430 if (content == NULL)
260445 FuDevice *device,
261446 GError **error)
262447 {
263 #ifdef HAVE_UEFI_UNLOCK
264448 gint rc;
265449 g_debug ("unlocking UEFI device %s", fu_device_get_id (device));
266450 rc = fwup_enable_esrt();
277461 else if (rc == 3)
278462 g_debug ("UEFI device will be unlocked on next reboot");
279463 return TRUE;
280 #else
281 g_set_error_literal (error,
282 FWUPD_ERROR,
283 FWUPD_ERROR_INTERNAL,
284 "Not supported, update libfwupdate!");
285 return FALSE;
286 #endif
287464 }
288465
289466 static const gchar *
302479 return NULL;
303480 }
304481
482 static gchar *
483 fu_plugin_uefi_get_name_for_type (FuPlugin *plugin, guint32 uefi_type)
484 {
485 GString *display_name;
486
487 /* set Display Name prefix for capsules that are not PCI cards */
488 display_name = g_string_new (fu_plugin_uefi_uefi_type_to_string (uefi_type));
489 if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE) {
490 g_string_prepend (display_name, "UEFI ");
491 } else {
492 const gchar *tmp;
493 tmp = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME);
494 if (tmp != NULL && tmp[0] != '\0') {
495 g_string_prepend (display_name, " ");
496 g_string_prepend (display_name, tmp);
497 }
498 }
499 return g_string_free (display_name, FALSE);
500 }
501
502 static void
503 fu_plugin_uefi_coldplug_resource (FuPlugin *plugin, fwup_resource *re)
504 {
505 AsVersionParseFlag parse_flags;
506 efi_guid_t *guid_raw;
507 guint32 uefi_type;
508 guint32 version_raw;
509 guint64 hardware_instance = 0; /* FIXME */
510 g_autofree gchar *guid = NULL;
511 g_autofree gchar *id = NULL;
512 g_autofree gchar *name = NULL;
513 g_autofree gchar *version_lowest = NULL;
514 g_autofree gchar *version = NULL;
515 g_autoptr(FuDevice) dev = NULL;
516
517 /* detect the fake GUID used for uploading the image */
518 fwup_get_guid (re, &guid_raw);
519 if (efi_guid_cmp (guid_raw, &UX_CAPSULE_GUID) == 0) {
520 g_debug ("skipping entry, detected fake BGRT");
521 return;
522 }
523
524 /* convert to strings */
525 guid = fu_plugin_uefi_guid_to_string (guid_raw);
526 if (guid == NULL) {
527 g_warning ("failed to convert guid to string");
528 return;
529 }
530
531 fwup_get_fw_type (re, &uefi_type);
532 parse_flags = fu_plugin_uefi_get_version_format_for_type (plugin, uefi_type);
533 fwup_get_fw_version (re, &version_raw);
534 version = as_utils_version_from_uint32 (version_raw, parse_flags);
535 id = g_strdup_printf ("UEFI-%s-dev%" G_GUINT64_FORMAT,
536 guid, hardware_instance);
537
538 dev = fu_device_new ();
539 if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE) {
540 /* nothing better in the icon naming spec */
541 fu_device_add_icon (dev, "audio-card");
542 } else {
543 /* this is probably system firmware */
544 fu_device_add_icon (dev, "computer");
545 }
546 fu_device_set_id (dev, id);
547 fu_device_add_guid (dev, guid);
548 fu_device_set_version (dev, version);
549 name = fu_plugin_uefi_get_name_for_type (plugin, uefi_type);
550 if (name != NULL)
551 fu_device_set_name (dev, name);
552 fwup_get_lowest_supported_fw_version (re, &version_raw);
553 if (version_raw != 0) {
554 version_lowest = as_utils_version_from_uint32 (version_raw,
555 parse_flags);
556 fu_device_set_version_lowest (dev, version_lowest);
557 }
558 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
559 if (g_file_test ("/sys/firmware/efi/efivars", G_FILE_TEST_IS_DIR) ||
560 g_file_test ("/sys/firmware/efi/vars", G_FILE_TEST_IS_DIR)) {
561 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
562 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
563 } else {
564 g_warning ("Kernel support for EFI variables missing");
565 }
566 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
567 fu_plugin_device_add (plugin, dev);
568 }
569
305570 gboolean
306571 fu_plugin_coldplug (FuPlugin *plugin, GError **error)
307572 {
308 AsVersionParseFlag parse_flags;
309 const gchar *product_name;
310573 fwup_resource *re;
311574 gint supported;
312 g_autofree gchar *guid = NULL;
313 g_autoptr(FuDevice) dev = NULL;
314575 g_autoptr(fwup_resource_iter) iter = NULL;
315576
316577 /* supported = 0 : ESRT unspported
329590 }
330591
331592 if (supported == 2) {
332 dev = fu_device_new ();
593 g_autoptr(FuDevice) dev = fu_device_new ();
333594 fu_device_set_id (dev, "UEFI-dummy-dev0");
334595 fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e");
335596 fu_device_set_version (dev, "0");
597 fu_device_add_icon (dev, "computer");
336598 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
337599 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_LOCKED);
338600 fu_plugin_device_add (plugin, dev);
339601 return TRUE;
340602 }
341603
342 /* this can fail if we have no permissions */
604 /* add each device */
343605 if (fwup_resource_iter_create (&iter) < 0) {
344606 g_set_error_literal (error,
345607 FWUPD_ERROR,
347609 "Cannot create fwup iter");
348610 return FALSE;
349611 }
350
351 /* set Display Name to the system for all capsules */
352 product_name = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME);
353
354 /* add each device */
355 guid = g_strdup ("00000000-0000-0000-0000-000000000000");
356 parse_flags = fu_plugin_uefi_get_version_format (plugin);
357 while (fwup_resource_iter_next (iter, &re) > 0) {
358 const gchar *uefi_type_str = NULL;
359 efi_guid_t *guid_raw;
360 guint32 uefi_type;
361 guint32 version_raw;
362 guint64 hardware_instance = 0; /* FIXME */
363 g_autofree gchar *id = NULL;
364 g_autofree gchar *version = NULL;
365 g_autofree gchar *version_lowest = NULL;
366 g_autoptr(GString) display_name = g_string_new (NULL);
367
368 /* set up proper DisplayName */
369 fwup_get_fw_type (re, &uefi_type);
370 if (product_name != NULL)
371 g_string_append (display_name, product_name);
372 uefi_type_str = fu_plugin_uefi_uefi_type_to_string (uefi_type);
373 if (uefi_type_str != NULL) {
374 if (display_name->len > 0)
375 g_string_append (display_name, " ");
376 g_string_append (display_name, uefi_type_str);
377 }
378
379 /* convert to strings */
380 fwup_get_guid (re, &guid_raw);
381 if (efi_guid_to_str (guid_raw, &guid) < 0) {
382 g_warning ("failed to convert guid to string");
383 continue;
384 }
385 fwup_get_fw_version(re, &version_raw);
386 version = as_utils_version_from_uint32 (version_raw,
387 parse_flags);
388 id = g_strdup_printf ("UEFI-%s-dev%" G_GUINT64_FORMAT,
389 guid, hardware_instance);
390
391 dev = fu_device_new ();
392 fu_device_set_id (dev, id);
393 fu_device_add_guid (dev, guid);
394 fu_device_set_version (dev, version);
395 if (display_name->len > 0)
396 fu_device_set_name(dev, display_name->str);
397 fwup_get_lowest_supported_fw_version (re, &version_raw);
398 if (version_raw != 0) {
399 version_lowest = as_utils_version_from_uint32 (version_raw,
400 parse_flags);
401 fu_device_set_version_lowest (dev, version_lowest);
402 }
403 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
404 if (g_file_test ("/sys/firmware/efi/efivars", G_FILE_TEST_IS_DIR) ||
405 g_file_test ("/sys/firmware/efi/vars", G_FILE_TEST_IS_DIR)) {
406 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
407 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
408 } else {
409 g_warning ("Kernel support for EFI variables missing");
410 }
411 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
412 fu_plugin_device_add (plugin, dev);
413 }
612 while (fwup_resource_iter_next (iter, &re) > 0)
613 fu_plugin_uefi_coldplug_resource (plugin, re);
414614 return TRUE;
415615 }
2929
3030 #include "lu-context.h"
3131 #include "lu-device.h"
32 #include "lu-device-peripheral.h"
3233
3334 struct FuPluginData {
3435 LuContext *ctx;
6162 fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE);
6263 fu_device_set_id (dev, lu_device_get_platform_id (device));
6364 fu_device_set_name (dev, lu_device_get_product (device));
65 if (lu_device_get_kind (device) == LU_DEVICE_KIND_PERIPHERAL) {
66 const gchar *tmp;
67 tmp = lu_device_peripheral_get_summary (LU_DEVICE_PERIPHERAL (device));
68 if (tmp != NULL)
69 fu_device_set_summary (dev, tmp);
70 } else {
71 fu_device_set_summary (dev, "A miniaturised USB wireless receiver");
72 }
6473 fu_device_set_vendor (dev, lu_device_get_vendor (device));
6574 fu_device_set_vendor_id (dev, "USB:0x046D");
6675 fu_device_set_version (dev, lu_device_get_version_fw (device));
6978 for (guint i = 0; i < guids->len; i++) {
7079 const gchar *guid = g_ptr_array_index (guids, i);
7180 fu_device_add_guid (dev, guid);
81 }
82
83 /* add icon */
84 if (lu_device_get_kind (device) == LU_DEVICE_KIND_PERIPHERAL) {
85 const gchar *tmp = lu_device_peripheral_get_icon (LU_DEVICE_PERIPHERAL (device));
86 if (tmp != NULL)
87 fu_device_add_icon (dev, tmp);
88 } else {
89 /* FIXME: we need something better in the icon name spec for
90 * the USB Unifying receiver dongle */
91 fu_device_add_icon (dev, "preferences-desktop-keyboard");
7292 }
7393
7494 /* don't allow the USB plugin to claim this */
277297 fu_plugin_startup (FuPlugin *plugin, GError **error)
278298 {
279299 FuPluginData *data = fu_plugin_get_data (plugin);
300
301 /* check the kernel has CONFIG_HIDRAW */
302 if (!g_file_test ("/sys/class/hidraw", G_FILE_TEST_IS_DIR)) {
303 g_set_error_literal (error,
304 FWUPD_ERROR,
305 FWUPD_ERROR_NOT_SUPPORTED,
306 "no kernel support for CONFIG_HIDRAW");
307 return FALSE;
308 }
309
310 /* coldplug */
280311 g_signal_connect (data->ctx, "added",
281312 G_CALLBACK (fu_plugin_unifying_device_added_cb),
282313 plugin);
283314 g_signal_connect (data->ctx, "removed",
284315 G_CALLBACK (fu_plugin_unifying_device_removed_cb),
285316 plugin);
317 lu_context_set_supported (data->ctx, fu_plugin_get_supported (plugin));
286318 lu_context_coldplug (data->ctx);
287319 lu_context_set_poll_interval (data->ctx, 5000);
288320 return TRUE;
3434 struct _LuContext
3535 {
3636 GObject parent_instance;
37 GPtrArray *supported_guids;
3738 GPtrArray *devices;
3839 GHashTable *devices_active; /* LuDevice : 1 */
3940 GUsbContext *usb_ctx;
7374 if (!ctx->done_coldplug)
7475 lu_context_coldplug (ctx);
7576 return ctx->devices;
77 }
78
79 static gboolean
80 lu_context_check_supported (LuContext *ctx, const gchar *guid)
81 {
82 if (ctx->supported_guids == NULL) {
83 g_debug ("no list of supported GUIDs so assuming supported");
84 return TRUE;
85 }
86 for (guint i = 0; i < ctx->supported_guids->len; i++) {
87 const gchar *guid_tmp = g_ptr_array_index (ctx->supported_guids, i);
88 if (g_strcmp0 (guid, guid_tmp) == 0)
89 return TRUE;
90 }
91 return FALSE;
92 }
93
94 void
95 lu_context_set_supported (LuContext *ctx, GPtrArray *supported_guids)
96 {
97 if (ctx->supported_guids != NULL)
98 g_ptr_array_unref (ctx->supported_guids);
99 ctx->supported_guids = g_ptr_array_ref (supported_guids);
76100 }
77101
78102 static void
336360 /* generate GUID */
337361 devid = g_strdup_printf ("UFY\\VID_%04X&PID_%04X", vid, pid);
338362 lu_device_add_guid (device, devid);
363 if (!lu_context_check_supported (ctx, lu_device_get_guid_default (device))) {
364 g_debug ("%s not supported, so ignoring device", devid);
365 return;
366 }
339367 g_hash_table_insert (ctx->hash_devices,
340368 g_strdup (lu_device_get_platform_id (device)),
341369 g_object_ref (device));
3838 void lu_context_coldplug (LuContext *ctx);
3939 void lu_context_set_poll_interval (LuContext *ctx,
4040 guint poll_interval);
41 void lu_context_set_supported (LuContext *ctx,
42 GPtrArray *supported_guids);
4143 gboolean lu_context_wait_for_replug (LuContext *ctx,
4244 LuDevice *device,
4345 guint timeout_ms,
2828
2929 struct _LuDevicePeripheral
3030 {
31 LuDevice parent_instance;
32 guint8 cached_fw_entity;
31 LuDevice parent_instance;
32 guint8 cached_fw_entity;
33 LuDevicePeripheralKind kind;
3334 };
3435
3536 G_DEFINE_TYPE (LuDevicePeripheral, lu_device_peripheral, LU_TYPE_DEVICE)
37
38 LuDevicePeripheralKind
39 lu_device_peripheral_get_kind (LuDevicePeripheral *self)
40 {
41 return self->kind;
42 }
43
44 const gchar *
45 lu_device_peripheral_get_icon (LuDevicePeripheral *self)
46 {
47 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_KEYBOARD)
48 return "input-keyboard";
49 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_REMOTE_CONTROL)
50 return "pda"; // ish
51 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_NUMPAD)
52 return "input-dialpad";
53 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_MOUSE)
54 return "input-mouse";
55 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_TOUCHPAD)
56 return "input-touchpad";
57 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_TRACKBALL)
58 return "input-mouse"; // ish
59 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_PRESENTER)
60 return "pda"; // ish
61 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_RECEIVER)
62 return "preferences-desktop-keyboard";
63 return NULL;
64 }
65
66 const gchar *
67 lu_device_peripheral_get_summary (LuDevicePeripheral *self)
68 {
69 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_KEYBOARD)
70 return "Unifying Keyboard";
71 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_REMOTE_CONTROL)
72 return "Unifying Remote Control";
73 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_NUMPAD)
74 return "Unifying Number Pad";
75 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_MOUSE)
76 return "Unifying Mouse";
77 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_TOUCHPAD)
78 return "Unifying Touchpad";
79 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_TRACKBALL)
80 return "Unifying Trackball";
81 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_PRESENTER)
82 return "Unifying Presenter";
83 if (self->kind == LU_DEVICE_PERIPHERAL_KIND_RECEIVER)
84 return "Unifying Receiver";
85 return NULL;
86 }
3687
3788 static gboolean
3889 lu_device_peripheral_fetch_firmware_info (LuDevice *device, GError **error)
228279 static gboolean
229280 lu_device_peripheral_probe (LuDevice *device, GError **error)
230281 {
282 LuDevicePeripheral *self = LU_DEVICE_PERIPHERAL (device);
231283 guint8 idx;
232284 const guint16 map_features[] = {
285 HIDPP_FEATURE_GET_DEVICE_NAME_TYPE,
233286 HIDPP_FEATURE_I_FIRMWARE_INFO,
234287 HIDPP_FEATURE_BATTERY_LEVEL_STATUS,
235288 HIDPP_FEATURE_DFU_CONTROL,
266319 return FALSE;
267320
268321 /* try using HID++2.0 */
322 idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_GET_DEVICE_NAME_TYPE);
323 if (idx != 0x00) {
324 /* check the feature is available */
325 g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new ();
326 msg->report_id = HIDPP_REPORT_ID_SHORT;
327 msg->device_id = lu_device_get_hidpp_id (device);
328 msg->sub_id = idx;
329 msg->function_id = 0x02 << 4; /* getDeviceType */
330 if (!lu_device_hidpp_transfer (device, msg, error)) {
331 g_prefix_error (error, "failed to get device type: ");
332 return FALSE;
333 }
334 self->kind = msg->data[0];
335 }
269336 idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU_CONTROL);
270337 if (idx != 0x00) {
271338 lu_device_add_flag (device, LU_DEVICE_FLAG_CAN_FLASH);
2828 #define LU_TYPE_DEVICE_PERIPHERAL (lu_device_peripheral_get_type ())
2929 G_DECLARE_FINAL_TYPE (LuDevicePeripheral, lu_device_peripheral, LU, DEVICE_PERIPHERAL, LuDevice)
3030
31 typedef enum {
32 LU_DEVICE_PERIPHERAL_KIND_KEYBOARD,
33 LU_DEVICE_PERIPHERAL_KIND_REMOTE_CONTROL,
34 LU_DEVICE_PERIPHERAL_KIND_NUMPAD,
35 LU_DEVICE_PERIPHERAL_KIND_MOUSE,
36 LU_DEVICE_PERIPHERAL_KIND_TOUCHPAD,
37 LU_DEVICE_PERIPHERAL_KIND_TRACKBALL,
38 LU_DEVICE_PERIPHERAL_KIND_PRESENTER,
39 LU_DEVICE_PERIPHERAL_KIND_RECEIVER,
40 LU_DEVICE_PERIPHERAL_KIND_LAST
41 } LuDevicePeripheralKind;
42
43 LuDevicePeripheralKind lu_device_peripheral_get_kind (LuDevicePeripheral *self);
44 const gchar *lu_device_peripheral_get_icon (LuDevicePeripheral *self);
45 const gchar *lu_device_peripheral_get_summary (LuDevicePeripheral *self);
46
3147 G_END_DECLS
3248
3349 #endif /* __LU_DEVICE_PERIPHERAL_H */
2323 #include <fcntl.h>
2424 #include <glib/gstdio.h>
2525 #include <string.h>
26 #include <appstream-glib.h>
2627
2728 #include "lu-common.h"
2829 #include "lu-device-bootloader-nordic.h"
3738 GUdevDevice *udev_device;
3839 gint udev_device_fd;
3940 GUsbDevice *usb_device;
41 FuDeviceLocker *usb_device_locker;
4042 gchar *platform_id;
4143 gchar *product;
4244 gchar *vendor;
106108 return "Root";
107109 if (feature == HIDPP_FEATURE_I_FIRMWARE_INFO)
108110 return "IFirmwareInfo";
111 if (feature == HIDPP_FEATURE_GET_DEVICE_NAME_TYPE)
112 return "GetDevicenameType";
109113 if (feature == HIDPP_FEATURE_BATTERY_LEVEL_STATUS)
110114 return "BatteryLevelStatus";
111115 if (feature == HIDPP_FEATURE_DFU_CONTROL)
728732 priv->version_hw = g_strdup (version_hw);
729733 }
730734
735 const gchar *
736 lu_device_get_guid_default (LuDevice *device)
737 {
738 LuDevicePrivate *priv = GET_PRIVATE (device);
739 if (priv->guids->len == 0)
740 return NULL;
741 return g_ptr_array_index (priv->guids, 0);
742 }
743
731744 GPtrArray *
732745 lu_device_get_guids (LuDevice *device)
733746 {
739752 lu_device_add_guid (LuDevice *device, const gchar *guid)
740753 {
741754 LuDevicePrivate *priv = GET_PRIVATE (device);
755 if (!as_utils_guid_is_valid (guid)) {
756 g_ptr_array_add (priv->guids, as_utils_guid_from_string (guid));
757 return;
758 }
742759 g_ptr_array_add (priv->guids, g_strdup (guid));
743760 }
744761
818835 /* set default vendor */
819836 lu_device_set_vendor (device, "Logitech");
820837
821 /* open device */
822 if (priv->usb_device != NULL) {
823 g_debug ("opening unifying device using USB");
824 if (!g_usb_device_open (priv->usb_device, error))
825 return FALSE;
826 }
827
828838 /* USB */
829839 if (priv->usb_device != NULL) {
840 guint8 num_interfaces = 0x01;
830841 g_autofree gchar *devid = NULL;
831 guint8 num_interfaces = 0x01;
832 if (priv->kind == LU_DEVICE_KIND_RUNTIME)
833 num_interfaces = 0x03;
834 for (guint i = 0; i < num_interfaces; i++) {
835 g_debug ("claiming interface 0x%02x", i);
836 if (!g_usb_device_claim_interface (priv->usb_device, i,
837 G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
838 error)) {
839 g_prefix_error (error, "Failed to claim 0x%02x: ", i);
840 g_usb_device_close (priv->usb_device, NULL);
842
843 /* open device */
844 if (priv->usb_device_locker == NULL) {
845 g_autoptr(FuDeviceLocker) locker = NULL;
846 g_debug ("opening unifying device using USB");
847 locker = fu_device_locker_new (priv->usb_device, error);
848 if (locker == NULL)
841849 return FALSE;
850 if (priv->kind == LU_DEVICE_KIND_RUNTIME)
851 num_interfaces = 0x03;
852 for (guint i = 0; i < num_interfaces; i++) {
853 g_debug ("claiming interface 0x%02x", i);
854 if (!g_usb_device_claim_interface (priv->usb_device, i,
855 G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER,
856 error)) {
857 g_prefix_error (error, "Failed to claim 0x%02x: ", i);
858 return FALSE;
859 }
842860 }
861 priv->usb_device_locker = g_steal_pointer (&locker);
843862 }
844863
845864 /* generate GUID */
904923 * @device: A #LuDevice
905924 * @error: A #GError, or %NULL
906925 *
907 * Closes the device. If at all unsure about closing a device, don't. The device
908 * will be automatically closed when the last reference to it is dropped.
926 * Closes the device.
909927 *
910928 * Returns: %TRUE for success
911929 **/
930948 }
931949
932950 /* USB */
933 if (priv->usb_device != NULL) {
951 if (priv->usb_device_locker != NULL) {
934952 guint8 num_interfaces = 0x01;
935953 if (priv->kind == LU_DEVICE_KIND_RUNTIME)
936954 num_interfaces = 0x03;
952970 }
953971 }
954972 }
955 if (!g_usb_device_close (priv->usb_device, error))
956 return FALSE;
957 }
973 g_clear_object (&priv->usb_device_locker);
974 }
975 g_clear_object (&priv->usb_device);
958976
959977 /* HID */
960978 if (priv->udev_device != NULL && priv->udev_device_fd > 0) {
11601178 {
11611179 LuDevice *device = LU_DEVICE (object);
11621180 LuDevicePrivate *priv = GET_PRIVATE (device);
1163 g_autoptr(GError) error = NULL;
1164
1165 /* autoclose */
1166 if (!lu_device_close (device, &error))
1167 g_debug ("failed to close: %s", error->message);
11681181
11691182 if (priv->usb_device != NULL)
11701183 g_object_unref (priv->usb_device);
1184 if (priv->usb_device_locker != NULL)
1185 g_object_unref (priv->usb_device_locker);
11711186 if (priv->udev_device != NULL)
11721187 g_object_unref (priv->udev_device);
11731188 g_ptr_array_unref (priv->guids);
134134 const gchar *lu_device_get_version_hw (LuDevice *device);
135135 void lu_device_set_version_hw (LuDevice *device,
136136 const gchar *version_hw);
137 const gchar *lu_device_get_guid_default (LuDevice *device);
137138 GPtrArray *lu_device_get_guids (LuDevice *device);
138139 void lu_device_add_guid (LuDevice *device,
139140 const gchar *guid);
8181 const gchar *description,
8282 FuLuToolPrivateCb callback)
8383 {
84 guint i;
85 FuLuToolItem *item;
8684 g_auto(GStrv) names = NULL;
8785
8886 g_return_if_fail (name != NULL);
9189
9290 /* add each one */
9391 names = g_strsplit (name, ",", -1);
94 for (i = 0; names[i] != NULL; i++) {
95 item = g_new0 (FuLuToolItem, 1);
92 for (guint i = 0; names[i] != NULL; i++) {
93 FuLuToolItem *item = g_new0 (FuLuToolItem, 1);
9694 item->name = g_strdup (names[i]);
9795 if (i == 0) {
9896 item->description = g_strdup (description);
108106 static gchar *
109107 lu_tool_get_descriptions (GPtrArray *array)
110108 {
111 guint i;
112 gsize j;
113 gsize len;
114109 const gsize max_len = 31;
115 FuLuToolItem *item;
116 GString *string;
110 GString *str;
117111
118112 /* print each command */
119 string = g_string_new ("");
120 for (i = 0; i < array->len; i++) {
121 item = g_ptr_array_index (array, i);
122 g_string_append (string, " ");
123 g_string_append (string, item->name);
113 str = g_string_new ("");
114 for (guint i = 0; i < array->len; i++) {
115 FuLuToolItem *item = g_ptr_array_index (array, i);
116 gsize len;
117 g_string_append (str, " ");
118 g_string_append (str, item->name);
124119 len = strlen (item->name) + 2;
125120 if (item->arguments != NULL) {
126 g_string_append (string, " ");
127 g_string_append (string, item->arguments);
121 g_string_append (str, " ");
122 g_string_append (str, item->arguments);
128123 len += strlen (item->arguments) + 1;
129124 }
130125 if (len < max_len) {
131 for (j = len; j < max_len + 1; j++)
132 g_string_append_c (string, ' ');
133 g_string_append (string, item->description);
134 g_string_append_c (string, '\n');
126 for (guint j = len; j < max_len + 1; j++)
127 g_string_append_c (str, ' ');
128 g_string_append (str, item->description);
129 g_string_append_c (str, '\n');
135130 } else {
136 g_string_append_c (string, '\n');
137 for (j = 0; j < max_len + 1; j++)
138 g_string_append_c (string, ' ');
139 g_string_append (string, item->description);
140 g_string_append_c (string, '\n');
131 g_string_append_c (str, '\n');
132 for (guint j = 0; j < max_len + 1; j++)
133 g_string_append_c (str, ' ');
134 g_string_append (str, item->description);
135 g_string_append_c (str, '\n');
141136 }
142137 }
143138
144139 /* remove trailing newline */
145 if (string->len > 0)
146 g_string_set_size (string, string->len - 1);
147
148 return g_string_free (string, FALSE);
140 if (str->len > 0)
141 g_string_set_size (str, str->len - 1);
142
143 return g_string_free (str, FALSE);
149144 }
150145
151146 static gboolean
154149 gchar **values,
155150 GError **error)
156151 {
157 guint i;
158 FuLuToolItem *item;
159
160152 /* find command */
161 for (i = 0; i < priv->cmd_array->len; i++) {
162 item = g_ptr_array_index (priv->cmd_array, i);
153 for (guint i = 0; i < priv->cmd_array->len; i++) {
154 FuLuToolItem *item = g_ptr_array_index (priv->cmd_array, i);
163155 if (g_strcmp0 (item->name, command) == 0)
164156 return item->callback (priv, values, error);
165157 }
5151 ],
5252 link_with : [
5353 fwupd,
54 libfwupdprivate,
5455 ],
5556 c_args : cargs,
5657 )
4040 g_autoptr(AsProfile) profile = as_profile_new ();
4141 g_autoptr(AsProfileTask) ptask = NULL;
4242 g_autoptr(FuDevice) dev = NULL;
43 g_autoptr(FuDeviceLocker) locker = NULL;
4344 g_autoptr(GError) error = NULL;
4445
4546 /* ignore hubs */
5960 }
6061
6162 /* try to get the version without claiming interface */
62 if (!g_usb_device_open (device, &error)) {
63 locker = fu_device_locker_new (device, &error);
64 if (locker == NULL) {
6365 g_debug ("Failed to open: %s", error->message);
6466 return;
6567 }
7880 }
7981 if (product == NULL) {
8082 g_debug ("no product string descriptor");
81 g_usb_device_close (device, NULL);
8283 return;
8384 }
8485 fu_device_set_name (dev, product);
122123 g_usb_device_get_release (device));
123124 fu_device_add_guid (dev, devid2);
124125
125 /* we're done here */
126 if (!g_usb_device_close (device, &error))
127 g_debug ("Failed to close: %s", error->message);
128
129126 /* use a small delay for hotplugging so that other, better, plugins
130127 * can claim this interface and add the FuDevice */
131128 fu_plugin_device_add_delay (plugin, dev);
0 ast
01 ca
12 cs
23 de
34 en_GB
45 eu
6 fi
57 fr
68 he
79 hi
2123 tr
2224 uk
2325 zh_CN
26 zh_TW
00 data/org.freedesktop.fwupd.metainfo.xml
11 policy/org.freedesktop.fwupd.policy.in
2 libdfu/dfu-tool.c
2 plugins/dfu/dfu-tool.c
33 plugins/synapticsmst/synapticsmst-tool.c
44 plugins/uefi/fu-plugin-uefi.c
55 src/fu-debug.c
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Asturian (http://www.transifex.com/freedesktop/fwupd/language/ast/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr ""
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr ""
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Lleendo"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Escribiendo"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Verificando"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Desaniciando"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr ""
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr ""
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Amestóse"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Desanicióse"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Camudóse"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Encaboxóse"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Nome"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Cifráu"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Rexón"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Alcontróse"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protocolu"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Estáu"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Desconozse: permisu ñegáu"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Serial"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Mou"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Estáu"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Tamañu de tresferencia"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr ""
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr ""
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr ""
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr ""
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr ""
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr ""
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr ""
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr ""
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr ""
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr ""
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr ""
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr ""
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr ""
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr ""
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr ""
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr ""
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr ""
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr ""
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr ""
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr ""
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr ""
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr ""
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr ""
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr ""
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr ""
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr ""
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr ""
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr ""
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr ""
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr ""
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr ""
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr ""
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr ""
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr ""
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr ""
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr ""
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr ""
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr ""
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr ""
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr ""
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr ""
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr ""
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr ""
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr ""
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr ""
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr ""
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr ""
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr ""
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr ""
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr ""
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr ""
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr ""
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr ""
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr ""
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr ""
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr ""
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr ""
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr ""
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr ""
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr ""
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr ""
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr ""
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr ""
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr ""
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr ""
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr ""
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr ""
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr ""
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr ""
+188
-179
po/ca.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Catalan (http://www.transifex.com/freedesktop/fwupd/language/ca/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr "Es requereix autenticació per actualitzar les sumes de verificació emmagatzemades pels dispositius"
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Àlies per a %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "No s'ha trobat cap ordre"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "S'està llegint"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "S'està escrivint"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "S'està verificant"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "S'està esborrant"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "S'està desconectant"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "S'està conectant"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "S'ha afegit"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "S'ha eliminat"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "S'ha canviat"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "S'ha cancel·lat"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Nom"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Xifra"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Regió"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "S'ha trobat"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protocol"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Estat"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Desconegut: s'ha denegat el permís"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Sèrie"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Mode"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Estat"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Mida a transferir"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Peculiaritats"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Converteix el microprogramari al format DFU"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Fusiona múltiples fitxers de microprogramari en un de sol"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Estableix l'ID del proveïdor al fitxer del microprogramari"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Estableix l'ID del producte al fitxer del microprogramari"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr "Estableix l'adreça de l'element al fitxer del microprogramari"
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr "Estableix la mida del microprogramari per a l'objectiu"
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Estableix la versió de llançament al fitxer del microprogramari"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Estableix el número alternatiu al fitxer del microprogramari"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Estableix el nom alternatiu al fitxer del microprogramari"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Connecta un dispositiu amb capacitat DFU en temps real"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Llegeix el microprogramari des del dispositiu a un fitxer"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Llegeix el microprogramari des d'una partició a un fitxer"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Escriu el microprogramari des d'un fitxer a dins del dispositiu"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Escriu el microprogramari des d'un fitxer a dins d'una partició"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "Llista els dispositius amb capacitat DFU actualment connectats"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Desconecta el dispositiu amb capacitat DFU actualment connectat"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Bolca els detalls sobre un fitxer de microprogramari"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Vigila els dispositius DFU que han estat connectats en calent"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Encripta les dades del microprogramari"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Desencripta les dades del microprogramari"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Estableix les metadades en un fitxer de microprogramari"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr "Substitueix les dades en un fitxer de microprogramari existent"
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr "Crea un pedaç binari emprant dos fitxers"
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr "Aplica un pedaç binari"
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr "Bolca la informació sobre un pedaç binari a la pantalla"
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "Utilitat DFU"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Ha fallat en analitzar els arguments"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr "Enumera tots els dispositius de «Synaptics MST»"
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr "Instal·la un fitxer de microprogramari en un dispositiu MST"
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr "Utilitat «Synaptics Multistream Transport»"
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr "S'està instal·lant l'actualització de microprogramari..."
393376
407390 msgstr "Mostra les opcions per a la depuració"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Surt després d'un petit retard"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Sur una vegada s'hagi carregat el motor"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Dimoni per a l'actualització de microprogramari"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Servei de D-Bus per a l'actualització de microprogramari"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Està ociós..."
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "S'està descomprimint..."
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "S'està carregant..."
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "S'està reiniciant el dispositiu..."
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "S'està escrivint..."
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "S'està verificant..."
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Planificació..."
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr "S'està descarregant..."
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Desconegut"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "No s'ha detectat cap maquinari amb capacitat per a l'actualització del microprogramari"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Es torna a provar com una actualització fora de línia"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "S'està reinstal·lant %s amb %s... "
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "S'està desactualitzant %s des de %s a %s... "
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "S'està actualitzant %s des de %s a %s... "
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Fet!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "D'acord"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr "S'està obtenint la signatura"
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr "S'estan obtenint les metadades"
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr "S'està obtenint el microprogramari"
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr "S'està obtenint el fitxer"
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Versió:"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr "URI"
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Descripció"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "Suma de comprovació"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr "Trieu un alliberament:"
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "%s té actualitzacions de microprogramari:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Versió de l'actualització"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr "Actualitza l'ID remot:"
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Suma de verificació de l'actualització"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Ubicació de l'actualització"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Descripció de l'actualització"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr "ID remot"
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr "Tipus"
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619 msgstr ""
623 msgstr " Anell de claus"
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr "Habilitat"
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr "Antiguitat"
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr "Prioritat"
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr "Nom d'usuari"
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr "Contrasenya"
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr "Nom del fitxer"
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr "Signatura del nom del fitxer"
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Ubicació"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669 msgstr ""
663 msgstr "URI de les metadades"
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674 msgstr ""
668 msgstr "Signatura de l'URI de les metadades"
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679 msgstr ""
673 msgstr "URI base del microprogramari"
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "S'ha afegit el dispositiu:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "S'ha eliminat el dispositiu:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "S'ha canviat el dispositiu:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Mostra la informació de depuració addicional"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr "Mostra les versions del client i el dimoni"
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr "Planifica la instal·lació per al següent reinici quan sigui posible"
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Permet tornar a instal·lar les versions de microprogramari existents"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Permet tornar a la versió anterior del microprogramari"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr "Passa per alt els avisos del connector"
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Obté tots els dispositius que admeten actualitzacions de microprogramari"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr "Retorna tots els ID del maquinari de la màquina"
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Instal·la ara les actualitzacions preparades"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Instal·la un fitxer de microprogramari en aquest maquinari"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Obté la informació sobre un fitxer de microprogramari"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Obté la llista d'actualitzacions per al maquinari connectat"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Actualitza tot el microprogramari a les versions més recents"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Obté el resultat d'aplicar la funció criptogràfica de resum sobre el microprogramari bolcat"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "Desbloqueja el dispositiu per accedir al microprogramari"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Esborra els resultats de l'última actualització"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Obté els resultats de l'última actualització"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr "Obté els alliberaments per a un dispositiu"
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr "Obtén els remots configurats"
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr "Desactualitza el microprogramari en un dispositiu"
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Refresca les metadades des del servidor remot"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "Actualitza les metadades emmagatzemades amb el contingut de la ROM actual"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "Monitora el dimoni pels esdeveniments"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
813 msgstr "Construeix el microprogramari usant un entorn de proves"
814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
814823 msgstr ""
815824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Utilitat per al microprogramari"
+184
-175
po/cs.po less more
88 msgstr ""
99 "Project-Id-Version: fwupd\n"
1010 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
12 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
11 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
12 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1313 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1414 "Language-Team: Czech (http://www.transifex.com/freedesktop/fwupd/language/cs/)\n"
1515 "MIME-Version: 1.0\n"
105105 "Authentication is required to update the stored checksums for the device"
106106 msgstr "K aktualizaci uložených kontrolních součtů zařízení je vyžadováno ověření"
107107
108 #: policy/org.freedesktop.fwupd.policy.in:105
109 msgid "Modify a configured remote"
110 msgstr ""
111
112 #. TRANSLATORS: this is the PolicyKit modal dialog
113 #: policy/org.freedesktop.fwupd.policy.in:107
114 msgid ""
115 "Authentication is required to modify a configured remote used for firmware "
116 "updates"
117 msgstr ""
118
108119 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
109 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
120 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
110121 #: src/fu-util.c:112
111122 #, c-format
112123 msgid "Alias to %s"
113124 msgstr "Alias pro %s"
114125
115126 #. TRANSLATORS: error message
116 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
127 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
117128 #: src/fu-util.c:176
118129 msgid "Command not found"
119130 msgstr "Příkaz nebyl nalezen"
120131
121 #. TRANSLATORS: read from device to host
122 #: libdfu/dfu-tool.c:1236
123 msgid "Reading"
124 msgstr "Čte se"
125
126 #. TRANSLATORS: write from host to device
127 #: libdfu/dfu-tool.c:1242
128 msgid "Writing"
129 msgstr "Zapisuje se"
130
131 #. TRANSLATORS: read from device to host
132 #: libdfu/dfu-tool.c:1248
133 msgid "Verifying"
134 msgstr "Ověřuje se"
135
136 #. TRANSLATORS: read from device to host
137 #: libdfu/dfu-tool.c:1254
138 msgid "Erasing"
139 msgstr "Maže se"
140
141 #. TRANSLATORS: waiting for device
142 #: libdfu/dfu-tool.c:1260
143 msgid "Detaching"
144 msgstr "Odpojuje se"
145
146 #. TRANSLATORS: waiting for device
147 #: libdfu/dfu-tool.c:1266
148 msgid "Attaching"
149 msgstr "Napojuje se"
150
151132 #. TRANSLATORS: this is when a device is hotplugged
152 #: libdfu/dfu-tool.c:1487
133 #: plugins/dfu/dfu-tool.c:1440
153134 msgid "Added"
154135 msgstr "Přidáno"
155136
156137 #. TRANSLATORS: this is when a device is hotplugged
157 #: libdfu/dfu-tool.c:1498
138 #: plugins/dfu/dfu-tool.c:1451
158139 msgid "Removed"
159140 msgstr "Odebráno"
160141
161142 #. TRANSLATORS: this is when a device is hotplugged
162143 #. TRANSLATORS: this is when the daemon state changes
163 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
144 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
164145 msgid "Changed"
165146 msgstr "Změněno"
166147
167148 #. TRANSLATORS: this is when a device ctrl+c's a watch
168 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
149 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
169150 msgid "Cancelled"
170151 msgstr "Zrušeno"
171152
172153 #. TRANSLATORS: Appstream ID for the hardware type
173 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
154 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
174155 msgid "ID"
175156 msgstr "ID"
176157
177158 #. TRANSLATORS: interface name, e.g. "Flash"
178159 #. TRANSLATORS: device name, e.g. 'ColorHug2'
179 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
160 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
161 #: plugins/dfu/dfu-tool.c:2065
180162 msgid "Name"
181163 msgstr "Název"
182164
183165 #. TRANSLATORS: this is the encryption method used when writing
184 #: libdfu/dfu-tool.c:2043
166 #: plugins/dfu/dfu-tool.c:1985
185167 msgid "Cipher"
186168 msgstr "Šifra"
187169
188170 #. TRANSLATORS: these are areas of memory on the chip
189 #: libdfu/dfu-tool.c:2057
171 #: plugins/dfu/dfu-tool.c:1999
190172 msgid "Region"
191173 msgstr "Oblast"
192174
193175 #. TRANSLATORS: detected a DFU device
194 #: libdfu/dfu-tool.c:2092
176 #: plugins/dfu/dfu-tool.c:2033
195177 msgid "Found"
196178 msgstr "Nalezeno"
197179
198180 #. TRANSLATORS: DFU protocol version, e.g. 1.1
199 #: libdfu/dfu-tool.c:2100
181 #: plugins/dfu/dfu-tool.c:2041
200182 msgid "Protocol"
201183 msgstr "Protokol"
202184
203185 #. TRANSLATORS: probably not run as root...
204186 #. TRANSLATORS: device has failed to report status
205187 #. TRANSLATORS: device status, e.g. "OK"
206 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
188 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
189 #: plugins/dfu/dfu-tool.c:2080
207190 msgid "Status"
208191 msgstr "Stav"
209192
210 #: libdfu/dfu-tool.c:2112
193 #: plugins/dfu/dfu-tool.c:2054
211194 msgid "Unknown: permission denied"
212195 msgstr "Neznámý: přístup odepřen"
213196
214197 #. TRANSLATORS: serial number, e.g. '00012345'
215 #: libdfu/dfu-tool.c:2129
198 #: plugins/dfu/dfu-tool.c:2071
216199 msgid "Serial"
217200 msgstr "Sériové číslo"
218201
219202 #. TRANSLATORS: device mode, e.g. runtime or DFU
220 #: libdfu/dfu-tool.c:2134
203 #: plugins/dfu/dfu-tool.c:2076
221204 msgid "Mode"
222205 msgstr "Režim"
223206
224207 #. TRANSLATORS: device state, i.e. appIDLE
225 #: libdfu/dfu-tool.c:2142
208 #: plugins/dfu/dfu-tool.c:2084
226209 msgid "State"
227210 msgstr "Stav"
228211
229212 #. TRANSLATORS: transfer size in bytes
230 #: libdfu/dfu-tool.c:2150
213 #: plugins/dfu/dfu-tool.c:2092
231214 msgid "Transfer Size"
232215 msgstr "Přenášená velikost"
233216
234217 #. TRANSLATORS: device quirks, i.e. things that
235218 #. * it does that we have to work around
236 #: libdfu/dfu-tool.c:2158
219 #: plugins/dfu/dfu-tool.c:2100
237220 msgid "Quirks"
238221 msgstr "Zvláštní požadavky"
239222
240223 #. TRANSLATORS: command description
241 #: libdfu/dfu-tool.c:2237
224 #: plugins/dfu/dfu-tool.c:2181
242225 msgid "Convert firmware to DFU format"
243226 msgstr "Převést firmware do formátu DFU"
244227
245228 #. TRANSLATORS: command description
246 #: libdfu/dfu-tool.c:2243
229 #: plugins/dfu/dfu-tool.c:2187
247230 msgid "Merge multiple firmware files into one"
248231 msgstr "Sloučit více firmwarů do jednoho"
249232
250233 #. TRANSLATORS: command description
251 #: libdfu/dfu-tool.c:2249
234 #: plugins/dfu/dfu-tool.c:2193
252235 msgid "Set vendor ID on firmware file"
253236 msgstr "Nastavit ID výrobce v souboru s firmwarem"
254237
255238 #. TRANSLATORS: command description
256 #: libdfu/dfu-tool.c:2255
239 #: plugins/dfu/dfu-tool.c:2199
257240 msgid "Set product ID on firmware file"
258241 msgstr "Nastavit ID produktu v souboru s firmwarem"
259242
260243 #. TRANSLATORS: command description
261 #: libdfu/dfu-tool.c:2261
244 #: plugins/dfu/dfu-tool.c:2205
262245 msgid "Set element address on firmware file"
263246 msgstr ""
264247
265248 #. TRANSLATORS: command description
266 #: libdfu/dfu-tool.c:2267
249 #: plugins/dfu/dfu-tool.c:2211
267250 msgid "Set the firmware size for the target"
268251 msgstr ""
269252
270253 #. TRANSLATORS: command description
271 #: libdfu/dfu-tool.c:2273
254 #: plugins/dfu/dfu-tool.c:2217
272255 msgid "Set release version on firmware file"
273256 msgstr "Nastavit verzi vydání v souboru s firmwarem"
274257
275258 #. TRANSLATORS: command description
276 #: libdfu/dfu-tool.c:2279
259 #: plugins/dfu/dfu-tool.c:2223
277260 msgid "Set alternative number on firmware file"
278261 msgstr "Nastavit alternativní číslo v souboru s firmwarem"
279262
280263 #. TRANSLATORS: command description
281 #: libdfu/dfu-tool.c:2285
264 #: plugins/dfu/dfu-tool.c:2229
282265 msgid "Set alternative name on firmware file"
283266 msgstr "Nastavit alternativní název v souboru s firmwarem"
284267
285268 #. TRANSLATORS: command description
286 #: libdfu/dfu-tool.c:2291
269 #: plugins/dfu/dfu-tool.c:2235
287270 msgid "Attach DFU capable device back to runtime"
288271 msgstr "Napojit zařízení podporující DFU zpět do běhového režimu"
289272
290273 #. TRANSLATORS: command description
291 #: libdfu/dfu-tool.c:2297
274 #: plugins/dfu/dfu-tool.c:2241
292275 msgid "Read firmware from device into a file"
293276 msgstr "Přečíst firmware ze zařízení do souboru"
294277
295278 #. TRANSLATORS: command description
296 #: libdfu/dfu-tool.c:2303
279 #: plugins/dfu/dfu-tool.c:2247
297280 msgid "Read firmware from one partition into a file"
298281 msgstr "Přečíst firmware z jednoho oddílu do souboru"
299282
300283 #. TRANSLATORS: command description
301 #: libdfu/dfu-tool.c:2309
284 #: plugins/dfu/dfu-tool.c:2253
302285 msgid "Write firmware from file into device"
303286 msgstr "Zapsat firmware ze souboru do zařízení"
304287
305288 #. TRANSLATORS: command description
306 #: libdfu/dfu-tool.c:2315
289 #: plugins/dfu/dfu-tool.c:2259
307290 msgid "Write firmware from file into one partition"
308291 msgstr "Zapsat firmware ze souboru do jednoho oddílu"
309292
310293 #. TRANSLATORS: command description
311 #: libdfu/dfu-tool.c:2321
294 #: plugins/dfu/dfu-tool.c:2265
312295 msgid "List currently attached DFU capable devices"
313296 msgstr "Vypsat právě napojená zařízení podporující DFU"
314297
315298 #. TRANSLATORS: command description
316 #: libdfu/dfu-tool.c:2327
299 #: plugins/dfu/dfu-tool.c:2271
317300 msgid "Detach currently attached DFU capable device"
318301 msgstr "Odpojit aktuálně napojené zařízení podporující DFU"
319302
320303 #. TRANSLATORS: command description
321 #: libdfu/dfu-tool.c:2333
304 #: plugins/dfu/dfu-tool.c:2277
322305 msgid "Dump details about a firmware file"
323306 msgstr "Vypsat podrobnosti o souboru s firmwarem"
324307
325308 #. TRANSLATORS: command description
326 #: libdfu/dfu-tool.c:2339
309 #: plugins/dfu/dfu-tool.c:2283
327310 msgid "Watch DFU devices being hotplugged"
328311 msgstr "Sledovat připojení zařízení podporujících DFU"
329312
330313 #. TRANSLATORS: command description
331 #: libdfu/dfu-tool.c:2345
314 #: plugins/dfu/dfu-tool.c:2289
332315 msgid "Encrypt firmware data"
333316 msgstr "Zašifrovat data firmwaru"
334317
335318 #. TRANSLATORS: command description
336 #: libdfu/dfu-tool.c:2351
319 #: plugins/dfu/dfu-tool.c:2295
337320 msgid "Decrypt firmware data"
338321 msgstr "Dešifrovat data firmwaru"
339322
340323 #. TRANSLATORS: command description
341 #: libdfu/dfu-tool.c:2357
324 #: plugins/dfu/dfu-tool.c:2301
342325 msgid "Sets metadata on a firmware file"
343326 msgstr "Nastavit metadata v souboru s firmwarem"
344327
345328 #. TRANSLATORS: command description
346 #: libdfu/dfu-tool.c:2363
329 #: plugins/dfu/dfu-tool.c:2307
347330 msgid "Replace data in an existing firmware file"
348331 msgstr ""
349332
350333 #. TRANSLATORS: command description
351 #: libdfu/dfu-tool.c:2369
334 #: plugins/dfu/dfu-tool.c:2313
352335 msgid "Create a binary patch using two files"
353336 msgstr ""
354337
355338 #. TRANSLATORS: command description
356 #: libdfu/dfu-tool.c:2375
339 #: plugins/dfu/dfu-tool.c:2319
357340 msgid "Apply a binary patch"
358341 msgstr ""
359342
360343 #. TRANSLATORS: command description
361 #: libdfu/dfu-tool.c:2381
344 #: plugins/dfu/dfu-tool.c:2325
362345 msgid "Dump information about a binary patch to the screen"
363346 msgstr ""
364347
365348 #. TRANSLATORS: DFU stands for device firmware update
366 #: libdfu/dfu-tool.c:2407
349 #: plugins/dfu/dfu-tool.c:2351
367350 msgid "DFU Utility"
368351 msgstr "Nástroj pro práci s DFU"
369352
370353 #. TRANSLATORS: the user didn't read the man page
371 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
372 #: src/fu-util.c:1733
354 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
355 #: src/fu-util.c:1778
373356 msgid "Failed to parse arguments"
374357 msgstr "Selhalo zpracování argumentů"
375358
376359 #. TRANSLATORS: command description
377 #: plugins/synapticsmst/synapticsmst-tool.c:408
360 #: plugins/synapticsmst/synapticsmst-tool.c:400
378361 msgid "Enumerate all Synaptics MST devices"
379362 msgstr ""
380363
381364 #. TRANSLATORS: command description
382 #: plugins/synapticsmst/synapticsmst-tool.c:414
365 #: plugins/synapticsmst/synapticsmst-tool.c:406
383366 msgid "Flash firmware file to MST device"
384367 msgstr ""
385368
386 #: plugins/synapticsmst/synapticsmst-tool.c:434
369 #: plugins/synapticsmst/synapticsmst-tool.c:426
387370 msgid "Synaptics Multistream Transport Utility"
388371 msgstr ""
389372
390373 #. TRANSLATORS: this is shown when updating the firmware after the reboot
391 #: plugins/uefi/fu-plugin-uefi.c:194
374 #: plugins/uefi/fu-plugin-uefi.c:396
392375 msgid "Installing firmware update…"
393376 msgstr "Instaluje se aktualizace firmwaru…"
394377
408391 msgstr "Zobrazit volby ladění"
409392
410393 #. TRANSLATORS: exit after we've started up, used for user profiling
411 #: src/fu-main.c:863
394 #: src/fu-main.c:960
412395 msgid "Exit after a small delay"
413396 msgstr "Skončit po krátké prodlevě"
414397
415398 #. TRANSLATORS: exit straight away, used for automatic profiling
416 #: src/fu-main.c:866
399 #: src/fu-main.c:963
417400 msgid "Exit after the engine has loaded"
418401 msgstr "Skončit po načtení výkonné části"
419402
420403 #. TRANSLATORS: program name
421 #: src/fu-main.c:880
404 #: src/fu-main.c:977
422405 msgid "Firmware Update Daemon"
423406 msgstr "Démon pro aktualizaci firmwaru"
424407
425408 #. TRANSLATORS: program summary
426 #: src/fu-main.c:885
409 #: src/fu-main.c:982
427410 msgid "Firmware Update D-Bus Service"
428411 msgstr "Služba D-Bus pro aktualizaci firmwaru"
429412
430413 #. TRANSLATORS: daemon is inactive
431 #: src/fu-progressbar.c:51
414 #: src/fu-progressbar.c:52
432415 msgid "Idle…"
433416 msgstr "Nečinný…"
434417
435418 #. TRANSLATORS: decompressing the firmware file
436 #: src/fu-progressbar.c:55
419 #: src/fu-progressbar.c:56
437420 msgid "Decompressing…"
438421 msgstr "Rozbaluje se firmware…"
439422
440423 #. TRANSLATORS: parsing the firmware information
441 #: src/fu-progressbar.c:59
424 #: src/fu-progressbar.c:60
442425 msgid "Loading…"
443426 msgstr "Načítá se…"
444427
445428 #. TRANSLATORS: restarting the device to pick up new F/W
446 #: src/fu-progressbar.c:63
429 #: src/fu-progressbar.c:64
447430 msgid "Restarting device…"
448431 msgstr "Zařízení se restartuje…"
449432
433 #. TRANSLATORS: reading from the flash chips
434 #: src/fu-progressbar.c:68
435 msgid "Reading…"
436 msgstr ""
437
450438 #. TRANSLATORS: writing to the flash chips
451 #: src/fu-progressbar.c:67
439 #: src/fu-progressbar.c:72
452440 msgid "Writing…"
453441 msgstr "Zapisuje se…"
454442
443 #. TRANSLATORS: erasing contents of the flash chips
444 #: src/fu-progressbar.c:76
445 msgid "Erasing…"
446 msgstr ""
447
455448 #. TRANSLATORS: verifying we wrote the firmware correctly
456 #: src/fu-progressbar.c:71
449 #: src/fu-progressbar.c:80
457450 msgid "Verifying…"
458451 msgstr "Ověřuje se…"
459452
460453 #. TRANSLATORS: scheduing an update to be done on the next boot
461 #: src/fu-progressbar.c:75
454 #: src/fu-progressbar.c:84
462455 msgid "Scheduling…"
463456 msgstr "Plánuje se…"
464457
465458 #. TRANSLATORS: downloading from a remote server
466 #: src/fu-progressbar.c:79
459 #: src/fu-progressbar.c:88
467460 msgid "Downloading…"
468461 msgstr "Stahuje se…"
469462
463 #. TRANSLATORS: waiting for user to authenticate
464 #: src/fu-progressbar.c:92
465 msgid "Authenticating…"
466 msgstr ""
467
470468 #. TRANSLATORS: currect daemon status is unknown
471 #: src/fu-progressbar.c:86
469 #: src/fu-progressbar.c:99
472470 msgid "Unknown"
473471 msgstr "Neznámý"
474472
488486 msgid "No hardware detected with firmware update capability"
489487 msgstr "Nebylo nalezeno žádné zařízení schopné aktualizace firmwaru"
490488
491 #. TRANSLATOR: the plugin only supports offline
492 #: src/fu-util.c:337
493 msgid "Retrying as an offline update"
494 msgstr "Zkouší se znova jako aktualizace off-line"
495
496489 #. TRANSLATORS: the first replacement is a display name
497490 #. * e.g. "ColorHugALS" and the second is a version number
498491 #. * e.g. "1.2.3"
499 #: src/fu-util.c:501
492 #: src/fu-util.c:474
500493 #, c-format
501494 msgid "Reinstalling %s with %s... "
502495 msgstr "Přeinstalovává se %s na %s…"
504497 #. TRANSLATORS: the first replacement is a display name
505498 #. * e.g. "ColorHugALS" and the second and third are
506499 #. * version numbers e.g. "1.2.3"
507 #: src/fu-util.c:508
500 #: src/fu-util.c:481
508501 #, c-format
509502 msgid "Downgrading %s from %s to %s... "
510503 msgstr "Ponižuje se %s z verze %s na %s…"
512505 #. TRANSLATORS: the first replacement is a display name
513506 #. * e.g. "ColorHugALS" and the second and third are
514507 #. * version numbers e.g. "1.2.3"
515 #: src/fu-util.c:516
508 #: src/fu-util.c:489
516509 #, c-format
517510 msgid "Updating %s from %s to %s... "
518511 msgstr "Aktualizuje se %s z verze %s na %s…"
519512
520 #: src/fu-util.c:543
513 #: src/fu-util.c:516
521514 msgid "Done!"
522515 msgstr "Hotovo!"
523516
524 #: src/fu-util.c:585 src/fu-util.c:985
517 #: src/fu-util.c:565 src/fu-util.c:978
525518 msgid "OK"
526519 msgstr "V pořádku"
527520
528521 #. TRANSLATORS: downloading new signing file
529 #: src/fu-util.c:719
522 #: src/fu-util.c:699
530523 msgid "Fetching signature"
531524 msgstr ""
532525
533526 #. TRANSLATORS: downloading new metadata file
534 #: src/fu-util.c:722
527 #: src/fu-util.c:702
535528 msgid "Fetching metadata"
536529 msgstr ""
537530
538531 #. TRANSLATORS: downloading new firmware file
539 #: src/fu-util.c:725
532 #: src/fu-util.c:705
540533 msgid "Fetching firmware"
541534 msgstr ""
542535
543536 #. TRANSLATORS: downloading unknown file
544 #: src/fu-util.c:728
537 #: src/fu-util.c:708
545538 msgid "Fetching file"
546539 msgstr ""
547540
548541 #. TRANSLATORS: section header for release version number
549 #: src/fu-util.c:898
542 #: src/fu-util.c:888
550543 msgid "Version"
551544 msgstr "Verze"
552545
546 #. TRANSLATORS: section header for the remote the file is coming from
547 #: src/fu-util.c:891
548 msgid "Remote"
549 msgstr ""
550
553551 #. TRANSLATORS: section header for firmware URI
554 #: src/fu-util.c:901
552 #: src/fu-util.c:894
555553 msgid "URI"
556554 msgstr ""
557555
558556 #. TRANSLATORS: section header for firmware description
559 #: src/fu-util.c:907
557 #: src/fu-util.c:900
560558 msgid "Description"
561559 msgstr "Popis"
562560
563561 #. TRANSLATORS: section header for firmware checksum
564 #: src/fu-util.c:915
562 #. TRANSLATORS: remote checksum
563 #: src/fu-util.c:908 src/fu-util.c:1136
565564 msgid "Checksum"
566565 msgstr "Kontrolní součet"
567566
568567 #. TRANSLATORS: get interactive prompt
569 #: src/fu-util.c:947
568 #: src/fu-util.c:940
570569 msgid "Choose a release:"
571570 msgstr "Vyberte verzi:"
572571
573572 #. TRANSLATORS: first replacement is device name
574 #: src/fu-util.c:1036
573 #: src/fu-util.c:1041
575574 #, c-format
576575 msgid "%s has firmware updates:"
577576 msgstr "%s má aktualizace firmwaru:"
578577
579 #: src/fu-util.c:1046
578 #: src/fu-util.c:1048
580579 msgid "GUID"
581580 msgstr "GUID"
582581
583582 #. TRANSLATORS: section header for firmware version
584 #: src/fu-util.c:1050
583 #: src/fu-util.c:1060
585584 msgid "Update Version"
586585 msgstr "Verze aktualizace"
587586
588587 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
589 #: src/fu-util.c:1054
588 #: src/fu-util.c:1064
590589 msgid "Update Remote ID"
591590 msgstr "Vzdálené ID aktualizace"
592591
593592 #. TRANSLATORS: section header for firmware checksum
594 #: src/fu-util.c:1063
593 #: src/fu-util.c:1073
595594 msgid "Update Checksum"
596595 msgstr "Kontrolní součet aktualizace"
597596
598597 #. TRANSLATORS: section header for firmware remote http://
599 #: src/fu-util.c:1067
598 #: src/fu-util.c:1077
600599 msgid "Update Location"
601600 msgstr "Umístění aktualizace"
602601
603602 #. TRANSLATORS: section header for long firmware desc
604 #: src/fu-util.c:1078
603 #: src/fu-util.c:1088
605604 msgid "Update Description"
606605 msgstr "Popis aktualizace"
607606
608607 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
609 #: src/fu-util.c:1104
608 #: src/fu-util.c:1114
610609 msgid "Remote ID"
611610 msgstr ""
612611
612 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
613 #: src/fu-util.c:1118
614 msgid "Title"
615 msgstr ""
616
613617 #. TRANSLATORS: remote type, e.g. remote or local
614 #: src/fu-util.c:1108
618 #: src/fu-util.c:1122
615619 msgid "Type"
616620 msgstr ""
617621
618 #: src/fu-util.c:1113
622 #: src/fu-util.c:1127
619623 msgid "Keyring"
620624 msgstr ""
621625
622626 #. TRANSLATORS: if the remote is enabled
623 #: src/fu-util.c:1118
627 #: src/fu-util.c:1132
624628 msgid "Enabled"
625629 msgstr ""
626630
627631 #. TRANSLATORS: the age of the metadata
628 #: src/fu-util.c:1145
632 #: src/fu-util.c:1163
629633 msgid "Age"
630634 msgstr ""
631635
632636 #. TRANSLATORS: the numeric priority
633 #: src/fu-util.c:1152
637 #: src/fu-util.c:1170
634638 msgid "Priority"
635639 msgstr ""
636640
637641 #. TRANSLATORS: remote filename base
638 #: src/fu-util.c:1157
642 #: src/fu-util.c:1175
639643 msgid "Username"
640644 msgstr ""
641645
642646 #. TRANSLATORS: remote filename base
643 #: src/fu-util.c:1162
647 #: src/fu-util.c:1180
644648 msgid "Password"
645649 msgstr ""
646650
647 #. TRANSLATORS: remote filename base
648 #: src/fu-util.c:1167
651 #. TRANSLATORS: filename of the local file
652 #: src/fu-util.c:1185
649653 msgid "Filename"
650654 msgstr ""
651655
652 #. TRANSLATORS: remote filename base
653 #: src/fu-util.c:1172
656 #. TRANSLATORS: filename of the local file
657 #: src/fu-util.c:1190
654658 msgid "Filename Signature"
655659 msgstr ""
656660
657 #. TRANSLATORS: locatation of the local file
658 #: src/fu-util.c:1177
659 msgid "Location"
660 msgstr "Umístění"
661
662 #. TRANSLATORS: locatation of the local file
663 #: src/fu-util.c:1182
664 msgid "Location Signature"
665 msgstr ""
666
667661 #. TRANSLATORS: remote URI
668 #: src/fu-util.c:1187
662 #: src/fu-util.c:1195
669663 msgid "Metadata URI"
670664 msgstr ""
671665
672666 #. TRANSLATORS: remote URI
673 #: src/fu-util.c:1192
667 #: src/fu-util.c:1200
674668 msgid "Metadata URI Signature"
675669 msgstr ""
676670
677671 #. TRANSLATORS: remote URI
678 #: src/fu-util.c:1197
672 #: src/fu-util.c:1205
679673 msgid "Firmware Base URI"
680674 msgstr ""
681675
682676 #. TRANSLATORS: this is when a device is hotplugged
683 #: src/fu-util.c:1224
677 #: src/fu-util.c:1232
684678 msgid "Device added:"
685679 msgstr "Přidáno zařízení:"
686680
687681 #. TRANSLATORS: this is when a device is hotplugged
688 #: src/fu-util.c:1234
682 #: src/fu-util.c:1242
689683 msgid "Device removed:"
690684 msgstr "Odebráno zařízení:"
691685
692686 #. TRANSLATORS: this is when a device has been updated
693 #: src/fu-util.c:1244
687 #: src/fu-util.c:1252
694688 msgid "Device changed:"
695689 msgstr "Změněno zařízení:"
696690
697691 #. TRANSLATORS: command line option
698 #: src/fu-util.c:1568
692 #: src/fu-util.c:1595
699693 msgid "Show extra debugging information"
700694 msgstr "Zobrazovat doplňující informace pro ladění"
701695
702696 #. TRANSLATORS: command line option
703 #: src/fu-util.c:1571
697 #: src/fu-util.c:1598
704698 msgid "Show client and daemon versions"
705699 msgstr ""
706700
707701 #. TRANSLATORS: command line option
708 #: src/fu-util.c:1574
702 #: src/fu-util.c:1601
709703 msgid "Schedule installation for next reboot when possible"
710704 msgstr "Pokud je to možné, naplánovat instalaci na příští restart"
711705
712706 #. TRANSLATORS: command line option
713 #: src/fu-util.c:1577
707 #: src/fu-util.c:1604
714708 msgid "Allow re-installing existing firmware versions"
715709 msgstr "Povolit reinstalaci stávající verze firmwaru"
716710
717711 #. TRANSLATORS: command line option
718 #: src/fu-util.c:1580
712 #: src/fu-util.c:1607
719713 msgid "Allow downgrading firmware versions"
720714 msgstr "Povolit ponížení verze firmwaru"
721715
722716 #. TRANSLATORS: command line option
723 #: src/fu-util.c:1583
717 #: src/fu-util.c:1610
724718 msgid "Override plugin warning"
725719 msgstr "Potlačit varování zásuvného modulu"
726720
727721 #. TRANSLATORS: command description
728 #: src/fu-util.c:1607
722 #: src/fu-util.c:1634
729723 msgid "Get all devices that support firmware updates"
730724 msgstr "Zjistit všechna zařízení podporující aktualizaci firmwaru"
731725
732726 #. TRANSLATORS: command description
733 #: src/fu-util.c:1613
727 #: src/fu-util.c:1640
734728 msgid "Return all the hardware IDs for the machine"
735729 msgstr ""
736730
737731 #. TRANSLATORS: command description
738 #: src/fu-util.c:1619
732 #: src/fu-util.c:1646
739733 msgid "Install prepared updates now"
740734 msgstr "Nainstalovat připravené aktualizace nyní"
741735
742736 #. TRANSLATORS: command description
743 #: src/fu-util.c:1625
737 #: src/fu-util.c:1652
744738 msgid "Install a firmware file on this hardware"
745739 msgstr "Nainstalovat soubor s firmwarem na tento hardware"
746740
747741 #. TRANSLATORS: command description
748 #: src/fu-util.c:1631
742 #: src/fu-util.c:1658
749743 msgid "Gets details about a firmware file"
750744 msgstr "Vypsat podrobnosti o souboru s firmwarem"
751745
752746 #. TRANSLATORS: command description
753 #: src/fu-util.c:1637
747 #: src/fu-util.c:1664
754748 msgid "Gets the list of updates for connected hardware"
755749 msgstr "Vypsat seznam aktualizací pro připojený hardware"
756750
757751 #. TRANSLATORS: command description
758 #: src/fu-util.c:1643
752 #: src/fu-util.c:1670
759753 msgid "Updates all firmware to latest versions available"
760754 msgstr "Aktualizovat všechen firmware na nejnovější dostupné verze"
761755
762756 #. TRANSLATORS: command description
763 #: src/fu-util.c:1649
757 #: src/fu-util.c:1676
764758 msgid "Gets the cryptographic hash of the dumped firmware"
765759 msgstr "Získat kryptografický otisk vypsaného firmwaru"
766760
767761 #. TRANSLATORS: command description
768 #: src/fu-util.c:1655
762 #: src/fu-util.c:1682
769763 msgid "Unlocks the device for firmware access"
770764 msgstr "Odemknout zařízení pro přístup k firmwaru"
771765
772766 #. TRANSLATORS: command description
773 #: src/fu-util.c:1661
767 #: src/fu-util.c:1688
774768 msgid "Clears the results from the last update"
775769 msgstr "Smazat výsledky z poslední aktualizace"
776770
777771 #. TRANSLATORS: command description
778 #: src/fu-util.c:1667
772 #: src/fu-util.c:1694
773 msgid "Clears any updates scheduled to be updated offline"
774 msgstr ""
775
776 #. TRANSLATORS: command description
777 #: src/fu-util.c:1700
779778 msgid "Gets the results from the last update"
780779 msgstr "Vypsat výsledky z poslední aktualizace"
781780
782781 #. TRANSLATORS: command description
783 #: src/fu-util.c:1673
782 #: src/fu-util.c:1706
784783 msgid "Gets the releases for a device"
785784 msgstr ""
786785
787786 #. TRANSLATORS: command description
788 #: src/fu-util.c:1679
787 #: src/fu-util.c:1712
789788 msgid "Gets the configured remotes"
790789 msgstr ""
791790
792791 #. TRANSLATORS: command description
793 #: src/fu-util.c:1685
792 #: src/fu-util.c:1718
794793 msgid "Downgrades the firmware on a device"
795794 msgstr ""
796795
797796 #. TRANSLATORS: command description
798 #: src/fu-util.c:1691
797 #: src/fu-util.c:1724
799798 msgid "Refresh metadata from remote server"
800799 msgstr "Aktualizovat metadata ze vzdáleného serveru"
801800
802801 #. TRANSLATORS: command description
803 #: src/fu-util.c:1697
802 #: src/fu-util.c:1730
804803 msgid "Update the stored metadata with current ROM contents"
805804 msgstr "Aktualizovat uložená metadata pomocí aktuálního obsahu ROM"
806805
807806 #. TRANSLATORS: command description
808 #: src/fu-util.c:1703
807 #: src/fu-util.c:1736
809808 msgid "Monitor the daemon for events"
810809 msgstr "Sledovat události démonu"
811810
812811 #. TRANSLATORS: command description
813 #: src/fu-util.c:1709
812 #: src/fu-util.c:1742
814813 msgid "Build firmware using a sandbox"
815814 msgstr ""
816815
816 #. TRANSLATORS: command description
817 #: src/fu-util.c:1748
818 msgid "Dump SMBIOS data from a file"
819 msgstr ""
820
821 #. TRANSLATORS: command description
822 #: src/fu-util.c:1754
823 msgid "Modifies a given remote"
824 msgstr ""
825
817826 #. TRANSLATORS: program name
818 #: src/fu-util.c:1728
827 #: src/fu-util.c:1773
819828 msgid "Firmware Utility"
820829 msgstr "Nástroj pro práci s firmwarem"
+184
-175
po/de.po less more
88 msgstr ""
99 "Project-Id-Version: fwupd\n"
1010 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
12 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
11 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
12 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1313 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1414 "Language-Team: German (http://www.transifex.com/freedesktop/fwupd/language/de/)\n"
1515 "MIME-Version: 1.0\n"
105105 "Authentication is required to update the stored checksums for the device"
106106 msgstr ""
107107
108 #: policy/org.freedesktop.fwupd.policy.in:105
109 msgid "Modify a configured remote"
110 msgstr ""
111
112 #. TRANSLATORS: this is the PolicyKit modal dialog
113 #: policy/org.freedesktop.fwupd.policy.in:107
114 msgid ""
115 "Authentication is required to modify a configured remote used for firmware "
116 "updates"
117 msgstr ""
118
108119 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
109 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
120 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
110121 #: src/fu-util.c:112
111122 #, c-format
112123 msgid "Alias to %s"
113124 msgstr "Verweis auf %s"
114125
115126 #. TRANSLATORS: error message
116 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
127 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
117128 #: src/fu-util.c:176
118129 msgid "Command not found"
119130 msgstr "Befehl nicht gefunden"
120131
121 #. TRANSLATORS: read from device to host
122 #: libdfu/dfu-tool.c:1236
123 msgid "Reading"
124 msgstr ""
125
126 #. TRANSLATORS: write from host to device
127 #: libdfu/dfu-tool.c:1242
128 msgid "Writing"
129 msgstr ""
130
131 #. TRANSLATORS: read from device to host
132 #: libdfu/dfu-tool.c:1248
133 msgid "Verifying"
134 msgstr ""
135
136 #. TRANSLATORS: read from device to host
137 #: libdfu/dfu-tool.c:1254
138 msgid "Erasing"
139 msgstr ""
140
141 #. TRANSLATORS: waiting for device
142 #: libdfu/dfu-tool.c:1260
143 msgid "Detaching"
144 msgstr "Entfernen"
145
146 #. TRANSLATORS: waiting for device
147 #: libdfu/dfu-tool.c:1266
148 msgid "Attaching"
149 msgstr "Einhängen"
150
151132 #. TRANSLATORS: this is when a device is hotplugged
152 #: libdfu/dfu-tool.c:1487
133 #: plugins/dfu/dfu-tool.c:1440
153134 msgid "Added"
154135 msgstr "Hinzugefügt"
155136
156137 #. TRANSLATORS: this is when a device is hotplugged
157 #: libdfu/dfu-tool.c:1498
138 #: plugins/dfu/dfu-tool.c:1451
158139 msgid "Removed"
159140 msgstr "Entfernt"
160141
161142 #. TRANSLATORS: this is when a device is hotplugged
162143 #. TRANSLATORS: this is when the daemon state changes
163 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
144 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
164145 msgid "Changed"
165146 msgstr "Geändert"
166147
167148 #. TRANSLATORS: this is when a device ctrl+c's a watch
168 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
149 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
169150 msgid "Cancelled"
170151 msgstr "Abgebrochen"
171152
172153 #. TRANSLATORS: Appstream ID for the hardware type
173 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
154 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
174155 msgid "ID"
175156 msgstr "Kennung"
176157
177158 #. TRANSLATORS: interface name, e.g. "Flash"
178159 #. TRANSLATORS: device name, e.g. 'ColorHug2'
179 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
160 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
161 #: plugins/dfu/dfu-tool.c:2065
180162 msgid "Name"
181163 msgstr "Name"
182164
183165 #. TRANSLATORS: this is the encryption method used when writing
184 #: libdfu/dfu-tool.c:2043
166 #: plugins/dfu/dfu-tool.c:1985
185167 msgid "Cipher"
186168 msgstr "Verschlüsselungsverfahren"
187169
188170 #. TRANSLATORS: these are areas of memory on the chip
189 #: libdfu/dfu-tool.c:2057
171 #: plugins/dfu/dfu-tool.c:1999
190172 msgid "Region"
191173 msgstr "Bereich"
192174
193175 #. TRANSLATORS: detected a DFU device
194 #: libdfu/dfu-tool.c:2092
176 #: plugins/dfu/dfu-tool.c:2033
195177 msgid "Found"
196178 msgstr "Gefunden"
197179
198180 #. TRANSLATORS: DFU protocol version, e.g. 1.1
199 #: libdfu/dfu-tool.c:2100
181 #: plugins/dfu/dfu-tool.c:2041
200182 msgid "Protocol"
201183 msgstr "Protokoll"
202184
203185 #. TRANSLATORS: probably not run as root...
204186 #. TRANSLATORS: device has failed to report status
205187 #. TRANSLATORS: device status, e.g. "OK"
206 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
188 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
189 #: plugins/dfu/dfu-tool.c:2080
207190 msgid "Status"
208191 msgstr "Status"
209192
210 #: libdfu/dfu-tool.c:2112
193 #: plugins/dfu/dfu-tool.c:2054
211194 msgid "Unknown: permission denied"
212195 msgstr "Unbekannt: Zugriff verweigert"
213196
214197 #. TRANSLATORS: serial number, e.g. '00012345'
215 #: libdfu/dfu-tool.c:2129
198 #: plugins/dfu/dfu-tool.c:2071
216199 msgid "Serial"
217200 msgstr "Seriell"
218201
219202 #. TRANSLATORS: device mode, e.g. runtime or DFU
220 #: libdfu/dfu-tool.c:2134
203 #: plugins/dfu/dfu-tool.c:2076
221204 msgid "Mode"
222205 msgstr "Modus"
223206
224207 #. TRANSLATORS: device state, i.e. appIDLE
225 #: libdfu/dfu-tool.c:2142
208 #: plugins/dfu/dfu-tool.c:2084
226209 msgid "State"
227210 msgstr "Zustand"
228211
229212 #. TRANSLATORS: transfer size in bytes
230 #: libdfu/dfu-tool.c:2150
213 #: plugins/dfu/dfu-tool.c:2092
231214 msgid "Transfer Size"
232215 msgstr ""
233216
234217 #. TRANSLATORS: device quirks, i.e. things that
235218 #. * it does that we have to work around
236 #: libdfu/dfu-tool.c:2158
219 #: plugins/dfu/dfu-tool.c:2100
237220 msgid "Quirks"
238221 msgstr "Macken"
239222
240223 #. TRANSLATORS: command description
241 #: libdfu/dfu-tool.c:2237
224 #: plugins/dfu/dfu-tool.c:2181
242225 msgid "Convert firmware to DFU format"
243226 msgstr "Firmware in das DFU-Format konvertieren"
244227
245228 #. TRANSLATORS: command description
246 #: libdfu/dfu-tool.c:2243
229 #: plugins/dfu/dfu-tool.c:2187
247230 msgid "Merge multiple firmware files into one"
248231 msgstr "Mehrere Firmware-Dateien in eine zusammenführen"
249232
250233 #. TRANSLATORS: command description
251 #: libdfu/dfu-tool.c:2249
234 #: plugins/dfu/dfu-tool.c:2193
252235 msgid "Set vendor ID on firmware file"
253236 msgstr "Hersteller-Kennung einer Firmware-Datei festlegen"
254237
255238 #. TRANSLATORS: command description
256 #: libdfu/dfu-tool.c:2255
239 #: plugins/dfu/dfu-tool.c:2199
257240 msgid "Set product ID on firmware file"
258241 msgstr "Produkt-Kennung einer Firmware-Datei festlegen"
259242
260243 #. TRANSLATORS: command description
261 #: libdfu/dfu-tool.c:2261
244 #: plugins/dfu/dfu-tool.c:2205
262245 msgid "Set element address on firmware file"
263246 msgstr "Die Elementadresse in Firmware-Datei festlegen"
264247
265248 #. TRANSLATORS: command description
266 #: libdfu/dfu-tool.c:2267
249 #: plugins/dfu/dfu-tool.c:2211
267250 msgid "Set the firmware size for the target"
268251 msgstr "Die Firmware-Größe für das Ziel festlegen"
269252
270253 #. TRANSLATORS: command description
271 #: libdfu/dfu-tool.c:2273
254 #: plugins/dfu/dfu-tool.c:2217
272255 msgid "Set release version on firmware file"
273256 msgstr "Veröffentlichungsversion einer Firmware-Datei festlegen"
274257
275258 #. TRANSLATORS: command description
276 #: libdfu/dfu-tool.c:2279
259 #: plugins/dfu/dfu-tool.c:2223
277260 msgid "Set alternative number on firmware file"
278261 msgstr "Alternative Nummer einer Firmware-Datei festlegen"
279262
280263 #. TRANSLATORS: command description
281 #: libdfu/dfu-tool.c:2285
264 #: plugins/dfu/dfu-tool.c:2229
282265 msgid "Set alternative name on firmware file"
283266 msgstr "Alternativen Namen einer Firmware-Datei festlegen"
284267
285268 #. TRANSLATORS: command description
286 #: libdfu/dfu-tool.c:2291
269 #: plugins/dfu/dfu-tool.c:2235
287270 msgid "Attach DFU capable device back to runtime"
288271 msgstr "DFU-fähiges Gerät wieder zurück in Laufzeit einhängen"
289272
290273 #. TRANSLATORS: command description
291 #: libdfu/dfu-tool.c:2297
274 #: plugins/dfu/dfu-tool.c:2241
292275 msgid "Read firmware from device into a file"
293276 msgstr "Firmware von Gerät in Datei schreiben"
294277
295278 #. TRANSLATORS: command description
296 #: libdfu/dfu-tool.c:2303
279 #: plugins/dfu/dfu-tool.c:2247
297280 msgid "Read firmware from one partition into a file"
298281 msgstr "Firmware von einzelner Partition in Datei lesen"
299282
300283 #. TRANSLATORS: command description
301 #: libdfu/dfu-tool.c:2309
284 #: plugins/dfu/dfu-tool.c:2253
302285 msgid "Write firmware from file into device"
303286 msgstr "Firmware von Datei auf Gerät schreiben"
304287
305288 #. TRANSLATORS: command description
306 #: libdfu/dfu-tool.c:2315
289 #: plugins/dfu/dfu-tool.c:2259
307290 msgid "Write firmware from file into one partition"
308291 msgstr "Firmware aus Datei in einzelne Partition schreiben"
309292
310293 #. TRANSLATORS: command description
311 #: libdfu/dfu-tool.c:2321
294 #: plugins/dfu/dfu-tool.c:2265
312295 msgid "List currently attached DFU capable devices"
313296 msgstr "Derzeit angeschlossene DFU-fähige Geräte auflisten"
314297
315298 #. TRANSLATORS: command description
316 #: libdfu/dfu-tool.c:2327
299 #: plugins/dfu/dfu-tool.c:2271
317300 msgid "Detach currently attached DFU capable device"
318301 msgstr "Derzeit eingehängtes DFU-fähiges Gerät entfernen"
319302
320303 #. TRANSLATORS: command description
321 #: libdfu/dfu-tool.c:2333
304 #: plugins/dfu/dfu-tool.c:2277
322305 msgid "Dump details about a firmware file"
323306 msgstr "Details zu einer Firmware-Datei ausgeben"
324307
325308 #. TRANSLATORS: command description
326 #: libdfu/dfu-tool.c:2339
309 #: plugins/dfu/dfu-tool.c:2283
327310 msgid "Watch DFU devices being hotplugged"
328311 msgstr "Geräteanschluss von DFU-Geräten überwachen"
329312
330313 #. TRANSLATORS: command description
331 #: libdfu/dfu-tool.c:2345
314 #: plugins/dfu/dfu-tool.c:2289
332315 msgid "Encrypt firmware data"
333316 msgstr "Firmwaredaten verschlüsseln"
334317
335318 #. TRANSLATORS: command description
336 #: libdfu/dfu-tool.c:2351
319 #: plugins/dfu/dfu-tool.c:2295
337320 msgid "Decrypt firmware data"
338321 msgstr "Firmwaredaten entschlüsseln"
339322
340323 #. TRANSLATORS: command description
341 #: libdfu/dfu-tool.c:2357
324 #: plugins/dfu/dfu-tool.c:2301
342325 msgid "Sets metadata on a firmware file"
343326 msgstr "Metadaten einer Firmware-Datei festlegen"
344327
345328 #. TRANSLATORS: command description
346 #: libdfu/dfu-tool.c:2363
329 #: plugins/dfu/dfu-tool.c:2307
347330 msgid "Replace data in an existing firmware file"
348331 msgstr ""
349332
350333 #. TRANSLATORS: command description
351 #: libdfu/dfu-tool.c:2369
334 #: plugins/dfu/dfu-tool.c:2313
352335 msgid "Create a binary patch using two files"
353336 msgstr ""
354337
355338 #. TRANSLATORS: command description
356 #: libdfu/dfu-tool.c:2375
339 #: plugins/dfu/dfu-tool.c:2319
357340 msgid "Apply a binary patch"
358341 msgstr ""
359342
360343 #. TRANSLATORS: command description
361 #: libdfu/dfu-tool.c:2381
344 #: plugins/dfu/dfu-tool.c:2325
362345 msgid "Dump information about a binary patch to the screen"
363346 msgstr ""
364347
365348 #. TRANSLATORS: DFU stands for device firmware update
366 #: libdfu/dfu-tool.c:2407
349 #: plugins/dfu/dfu-tool.c:2351
367350 msgid "DFU Utility"
368351 msgstr "DFU-Werkzeug"
369352
370353 #. TRANSLATORS: the user didn't read the man page
371 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
372 #: src/fu-util.c:1733
354 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
355 #: src/fu-util.c:1778
373356 msgid "Failed to parse arguments"
374357 msgstr "Verarbeitung der Argumente schlug fehl"
375358
376359 #. TRANSLATORS: command description
377 #: plugins/synapticsmst/synapticsmst-tool.c:408
360 #: plugins/synapticsmst/synapticsmst-tool.c:400
378361 msgid "Enumerate all Synaptics MST devices"
379362 msgstr ""
380363
381364 #. TRANSLATORS: command description
382 #: plugins/synapticsmst/synapticsmst-tool.c:414
365 #: plugins/synapticsmst/synapticsmst-tool.c:406
383366 msgid "Flash firmware file to MST device"
384367 msgstr ""
385368
386 #: plugins/synapticsmst/synapticsmst-tool.c:434
369 #: plugins/synapticsmst/synapticsmst-tool.c:426
387370 msgid "Synaptics Multistream Transport Utility"
388371 msgstr ""
389372
390373 #. TRANSLATORS: this is shown when updating the firmware after the reboot
391 #: plugins/uefi/fu-plugin-uefi.c:194
374 #: plugins/uefi/fu-plugin-uefi.c:396
392375 msgid "Installing firmware update…"
393376 msgstr ""
394377
408391 msgstr "Debug Optionen anzeigen"
409392
410393 #. TRANSLATORS: exit after we've started up, used for user profiling
411 #: src/fu-main.c:863
394 #: src/fu-main.c:960
412395 msgid "Exit after a small delay"
413396 msgstr "Verlassen nach einer kurzen Verzögerung"
414397
415398 #. TRANSLATORS: exit straight away, used for automatic profiling
416 #: src/fu-main.c:866
399 #: src/fu-main.c:963
417400 msgid "Exit after the engine has loaded"
418401 msgstr "Nach dem Laden der Engine beenden"
419402
420403 #. TRANSLATORS: program name
421 #: src/fu-main.c:880
404 #: src/fu-main.c:977
422405 msgid "Firmware Update Daemon"
423406 msgstr "Dienst für Firmware-Aktualisierung"
424407
425408 #. TRANSLATORS: program summary
426 #: src/fu-main.c:885
409 #: src/fu-main.c:982
427410 msgid "Firmware Update D-Bus Service"
428411 msgstr "D-Bus-Dienst für Firmware-Aktualisierung"
429412
430413 #. TRANSLATORS: daemon is inactive
431 #: src/fu-progressbar.c:51
414 #: src/fu-progressbar.c:52
432415 msgid "Idle…"
433416 msgstr "Bereit …"
434417
435418 #. TRANSLATORS: decompressing the firmware file
436 #: src/fu-progressbar.c:55
419 #: src/fu-progressbar.c:56
437420 msgid "Decompressing…"
438421 msgstr "Entpacken …"
439422
440423 #. TRANSLATORS: parsing the firmware information
441 #: src/fu-progressbar.c:59
424 #: src/fu-progressbar.c:60
442425 msgid "Loading…"
443426 msgstr "Laden …"
444427
445428 #. TRANSLATORS: restarting the device to pick up new F/W
446 #: src/fu-progressbar.c:63
429 #: src/fu-progressbar.c:64
447430 msgid "Restarting device…"
448431 msgstr "Gerät wird neu gestartet …"
449432
433 #. TRANSLATORS: reading from the flash chips
434 #: src/fu-progressbar.c:68
435 msgid "Reading…"
436 msgstr ""
437
450438 #. TRANSLATORS: writing to the flash chips
451 #: src/fu-progressbar.c:67
439 #: src/fu-progressbar.c:72
452440 msgid "Writing…"
453441 msgstr "Schreiben …"
454442
443 #. TRANSLATORS: erasing contents of the flash chips
444 #: src/fu-progressbar.c:76
445 msgid "Erasing…"
446 msgstr ""
447
455448 #. TRANSLATORS: verifying we wrote the firmware correctly
456 #: src/fu-progressbar.c:71
449 #: src/fu-progressbar.c:80
457450 msgid "Verifying…"
458451 msgstr "Überprüfung läuft …"
459452
460453 #. TRANSLATORS: scheduing an update to be done on the next boot
461 #: src/fu-progressbar.c:75
454 #: src/fu-progressbar.c:84
462455 msgid "Scheduling…"
463456 msgstr "Einplanen …"
464457
465458 #. TRANSLATORS: downloading from a remote server
466 #: src/fu-progressbar.c:79
459 #: src/fu-progressbar.c:88
467460 msgid "Downloading…"
468461 msgstr ""
469462
463 #. TRANSLATORS: waiting for user to authenticate
464 #: src/fu-progressbar.c:92
465 msgid "Authenticating…"
466 msgstr ""
467
470468 #. TRANSLATORS: currect daemon status is unknown
471 #: src/fu-progressbar.c:86
469 #: src/fu-progressbar.c:99
472470 msgid "Unknown"
473471 msgstr "Unbekannt"
474472
488486 msgid "No hardware detected with firmware update capability"
489487 msgstr "Es wurde keine Hardware erkannt, deren Firmware aktualisiert werden kann"
490488
491 #. TRANSLATOR: the plugin only supports offline
492 #: src/fu-util.c:337
493 msgid "Retrying as an offline update"
494 msgstr "Erneuter Versuch als Offline-Aktualisierung"
495
496489 #. TRANSLATORS: the first replacement is a display name
497490 #. * e.g. "ColorHugALS" and the second is a version number
498491 #. * e.g. "1.2.3"
499 #: src/fu-util.c:501
492 #: src/fu-util.c:474
500493 #, c-format
501494 msgid "Reinstalling %s with %s... "
502495 msgstr "Erneute Installation von %s mit %s …"
504497 #. TRANSLATORS: the first replacement is a display name
505498 #. * e.g. "ColorHugALS" and the second and third are
506499 #. * version numbers e.g. "1.2.3"
507 #: src/fu-util.c:508
500 #: src/fu-util.c:481
508501 #, c-format
509502 msgid "Downgrading %s from %s to %s... "
510503 msgstr "Downgrade für %s von %s auf %s wird eingespielt …"
512505 #. TRANSLATORS: the first replacement is a display name
513506 #. * e.g. "ColorHugALS" and the second and third are
514507 #. * version numbers e.g. "1.2.3"
515 #: src/fu-util.c:516
508 #: src/fu-util.c:489
516509 #, c-format
517510 msgid "Updating %s from %s to %s... "
518511 msgstr "Aktualisieren von %s von %s nach %s …"
519512
520 #: src/fu-util.c:543
513 #: src/fu-util.c:516
521514 msgid "Done!"
522515 msgstr "Fertig."
523516
524 #: src/fu-util.c:585 src/fu-util.c:985
517 #: src/fu-util.c:565 src/fu-util.c:978
525518 msgid "OK"
526519 msgstr "Ok"
527520
528521 #. TRANSLATORS: downloading new signing file
529 #: src/fu-util.c:719
522 #: src/fu-util.c:699
530523 msgid "Fetching signature"
531524 msgstr ""
532525
533526 #. TRANSLATORS: downloading new metadata file
534 #: src/fu-util.c:722
527 #: src/fu-util.c:702
535528 msgid "Fetching metadata"
536529 msgstr ""
537530
538531 #. TRANSLATORS: downloading new firmware file
539 #: src/fu-util.c:725
532 #: src/fu-util.c:705
540533 msgid "Fetching firmware"
541534 msgstr ""
542535
543536 #. TRANSLATORS: downloading unknown file
544 #: src/fu-util.c:728
537 #: src/fu-util.c:708
545538 msgid "Fetching file"
546539 msgstr ""
547540
548541 #. TRANSLATORS: section header for release version number
549 #: src/fu-util.c:898
542 #: src/fu-util.c:888
550543 msgid "Version"
551544 msgstr "Version"
552545
546 #. TRANSLATORS: section header for the remote the file is coming from
547 #: src/fu-util.c:891
548 msgid "Remote"
549 msgstr ""
550
553551 #. TRANSLATORS: section header for firmware URI
554 #: src/fu-util.c:901
552 #: src/fu-util.c:894
555553 msgid "URI"
556554 msgstr ""
557555
558556 #. TRANSLATORS: section header for firmware description
559 #: src/fu-util.c:907
557 #: src/fu-util.c:900
560558 msgid "Description"
561559 msgstr "Beschreibung"
562560
563561 #. TRANSLATORS: section header for firmware checksum
564 #: src/fu-util.c:915
562 #. TRANSLATORS: remote checksum
563 #: src/fu-util.c:908 src/fu-util.c:1136
565564 msgid "Checksum"
566565 msgstr "Prüfsumme"
567566
568567 #. TRANSLATORS: get interactive prompt
569 #: src/fu-util.c:947
568 #: src/fu-util.c:940
570569 msgid "Choose a release:"
571570 msgstr ""
572571
573572 #. TRANSLATORS: first replacement is device name
574 #: src/fu-util.c:1036
573 #: src/fu-util.c:1041
575574 #, c-format
576575 msgid "%s has firmware updates:"
577576 msgstr "Firmwareaktualisierungen für %s verfügbar:"
578577
579 #: src/fu-util.c:1046
578 #: src/fu-util.c:1048
580579 msgid "GUID"
581580 msgstr "GUID"
582581
583582 #. TRANSLATORS: section header for firmware version
584 #: src/fu-util.c:1050
583 #: src/fu-util.c:1060
585584 msgid "Update Version"
586585 msgstr "Version aktualisieren"
587586
588587 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
589 #: src/fu-util.c:1054
588 #: src/fu-util.c:1064
590589 msgid "Update Remote ID"
591590 msgstr ""
592591
593592 #. TRANSLATORS: section header for firmware checksum
594 #: src/fu-util.c:1063
593 #: src/fu-util.c:1073
595594 msgid "Update Checksum"
596595 msgstr "Prüfsumme aktualisieren"
597596
598597 #. TRANSLATORS: section header for firmware remote http://
599 #: src/fu-util.c:1067
598 #: src/fu-util.c:1077
600599 msgid "Update Location"
601600 msgstr "Ort aktualisieren"
602601
603602 #. TRANSLATORS: section header for long firmware desc
604 #: src/fu-util.c:1078
603 #: src/fu-util.c:1088
605604 msgid "Update Description"
606605 msgstr "Beschreibung aktualisieren"
607606
608607 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
609 #: src/fu-util.c:1104
608 #: src/fu-util.c:1114
610609 msgid "Remote ID"
611610 msgstr ""
612611
612 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
613 #: src/fu-util.c:1118
614 msgid "Title"
615 msgstr ""
616
613617 #. TRANSLATORS: remote type, e.g. remote or local
614 #: src/fu-util.c:1108
618 #: src/fu-util.c:1122
615619 msgid "Type"
616620 msgstr ""
617621
618 #: src/fu-util.c:1113
622 #: src/fu-util.c:1127
619623 msgid "Keyring"
620624 msgstr ""
621625
622626 #. TRANSLATORS: if the remote is enabled
623 #: src/fu-util.c:1118
627 #: src/fu-util.c:1132
624628 msgid "Enabled"
625629 msgstr ""
626630
627631 #. TRANSLATORS: the age of the metadata
628 #: src/fu-util.c:1145
632 #: src/fu-util.c:1163
629633 msgid "Age"
630634 msgstr ""
631635
632636 #. TRANSLATORS: the numeric priority
633 #: src/fu-util.c:1152
637 #: src/fu-util.c:1170
634638 msgid "Priority"
635639 msgstr ""
636640
637641 #. TRANSLATORS: remote filename base
638 #: src/fu-util.c:1157
642 #: src/fu-util.c:1175
639643 msgid "Username"
640644 msgstr ""
641645
642646 #. TRANSLATORS: remote filename base
643 #: src/fu-util.c:1162
647 #: src/fu-util.c:1180
644648 msgid "Password"
645649 msgstr ""
646650
647 #. TRANSLATORS: remote filename base
648 #: src/fu-util.c:1167
651 #. TRANSLATORS: filename of the local file
652 #: src/fu-util.c:1185
649653 msgid "Filename"
650654 msgstr ""
651655
652 #. TRANSLATORS: remote filename base
653 #: src/fu-util.c:1172
656 #. TRANSLATORS: filename of the local file
657 #: src/fu-util.c:1190
654658 msgid "Filename Signature"
655659 msgstr ""
656660
657 #. TRANSLATORS: locatation of the local file
658 #: src/fu-util.c:1177
659 msgid "Location"
660 msgstr "Ort"
661
662 #. TRANSLATORS: locatation of the local file
663 #: src/fu-util.c:1182
664 msgid "Location Signature"
665 msgstr ""
666
667661 #. TRANSLATORS: remote URI
668 #: src/fu-util.c:1187
662 #: src/fu-util.c:1195
669663 msgid "Metadata URI"
670664 msgstr ""
671665
672666 #. TRANSLATORS: remote URI
673 #: src/fu-util.c:1192
667 #: src/fu-util.c:1200
674668 msgid "Metadata URI Signature"
675669 msgstr ""
676670
677671 #. TRANSLATORS: remote URI
678 #: src/fu-util.c:1197
672 #: src/fu-util.c:1205
679673 msgid "Firmware Base URI"
680674 msgstr ""
681675
682676 #. TRANSLATORS: this is when a device is hotplugged
683 #: src/fu-util.c:1224
677 #: src/fu-util.c:1232
684678 msgid "Device added:"
685679 msgstr "Gerät hinzugefügt:"
686680
687681 #. TRANSLATORS: this is when a device is hotplugged
688 #: src/fu-util.c:1234
682 #: src/fu-util.c:1242
689683 msgid "Device removed:"
690684 msgstr "Gerät entfernt:"
691685
692686 #. TRANSLATORS: this is when a device has been updated
693 #: src/fu-util.c:1244
687 #: src/fu-util.c:1252
694688 msgid "Device changed:"
695689 msgstr "Gerät geändert:"
696690
697691 #. TRANSLATORS: command line option
698 #: src/fu-util.c:1568
692 #: src/fu-util.c:1595
699693 msgid "Show extra debugging information"
700694 msgstr "Zusätzliche Informationen zur Fehlerdiagnose anzeigen"
701695
702696 #. TRANSLATORS: command line option
703 #: src/fu-util.c:1571
697 #: src/fu-util.c:1598
704698 msgid "Show client and daemon versions"
705699 msgstr ""
706700
707701 #. TRANSLATORS: command line option
708 #: src/fu-util.c:1574
702 #: src/fu-util.c:1601
709703 msgid "Schedule installation for next reboot when possible"
710704 msgstr ""
711705
712706 #. TRANSLATORS: command line option
713 #: src/fu-util.c:1577
707 #: src/fu-util.c:1604
714708 msgid "Allow re-installing existing firmware versions"
715709 msgstr "Erneute Installation vorhandener Firmware-Versionen erlauben"
716710
717711 #. TRANSLATORS: command line option
718 #: src/fu-util.c:1580
712 #: src/fu-util.c:1607
719713 msgid "Allow downgrading firmware versions"
720714 msgstr "Einspielen niedrigerer Firmwareversionen zulassen (Downgrade)"
721715
722716 #. TRANSLATORS: command line option
723 #: src/fu-util.c:1583
717 #: src/fu-util.c:1610
724718 msgid "Override plugin warning"
725719 msgstr ""
726720
727721 #. TRANSLATORS: command description
728 #: src/fu-util.c:1607
722 #: src/fu-util.c:1634
729723 msgid "Get all devices that support firmware updates"
730724 msgstr "Alle Geräte ermitteln, die Firmware-Aktualisierungen unterstützen"
731725
732726 #. TRANSLATORS: command description
733 #: src/fu-util.c:1613
727 #: src/fu-util.c:1640
734728 msgid "Return all the hardware IDs for the machine"
735729 msgstr ""
736730
737731 #. TRANSLATORS: command description
738 #: src/fu-util.c:1619
732 #: src/fu-util.c:1646
739733 msgid "Install prepared updates now"
740734 msgstr "Vorbereitete Aktualisierungen jetzt installieren"
741735
742736 #. TRANSLATORS: command description
743 #: src/fu-util.c:1625
737 #: src/fu-util.c:1652
744738 msgid "Install a firmware file on this hardware"
745739 msgstr "Eine Firmware-Datei auf dieser Hardware installieren"
746740
747741 #. TRANSLATORS: command description
748 #: src/fu-util.c:1631
742 #: src/fu-util.c:1658
749743 msgid "Gets details about a firmware file"
750744 msgstr "Ermittelt Details über eine Firmware-Datei"
751745
752746 #. TRANSLATORS: command description
753 #: src/fu-util.c:1637
747 #: src/fu-util.c:1664
754748 msgid "Gets the list of updates for connected hardware"
755749 msgstr "Ermittelt die Liste der Aktualisierungen für angeschlossene Hardware"
756750
757751 #. TRANSLATORS: command description
758 #: src/fu-util.c:1643
752 #: src/fu-util.c:1670
759753 msgid "Updates all firmware to latest versions available"
760754 msgstr "Alle Firmware auf die neueste verfügbare Version aktualisieren"
761755
762756 #. TRANSLATORS: command description
763 #: src/fu-util.c:1649
757 #: src/fu-util.c:1676
764758 msgid "Gets the cryptographic hash of the dumped firmware"
765759 msgstr "Ermittelt den kryptographischen Hash-Wert der abgelegten Firmware"
766760
767761 #. TRANSLATORS: command description
768 #: src/fu-util.c:1655
762 #: src/fu-util.c:1682
769763 msgid "Unlocks the device for firmware access"
770764 msgstr "Entsperrt das Gerät für Zugriff auf die Firmware"
771765
772766 #. TRANSLATORS: command description
773 #: src/fu-util.c:1661
767 #: src/fu-util.c:1688
774768 msgid "Clears the results from the last update"
775769 msgstr "Bereinigt die Ergebnisse der letzten Aktualisierung"
776770
777771 #. TRANSLATORS: command description
778 #: src/fu-util.c:1667
772 #: src/fu-util.c:1694
773 msgid "Clears any updates scheduled to be updated offline"
774 msgstr ""
775
776 #. TRANSLATORS: command description
777 #: src/fu-util.c:1700
779778 msgid "Gets the results from the last update"
780779 msgstr "Ermittelt die Ergebnisse der letzten Aktualisierung"
781780
782781 #. TRANSLATORS: command description
783 #: src/fu-util.c:1673
782 #: src/fu-util.c:1706
784783 msgid "Gets the releases for a device"
785784 msgstr ""
786785
787786 #. TRANSLATORS: command description
788 #: src/fu-util.c:1679
787 #: src/fu-util.c:1712
789788 msgid "Gets the configured remotes"
790789 msgstr ""
791790
792791 #. TRANSLATORS: command description
793 #: src/fu-util.c:1685
792 #: src/fu-util.c:1718
794793 msgid "Downgrades the firmware on a device"
795794 msgstr ""
796795
797796 #. TRANSLATORS: command description
798 #: src/fu-util.c:1691
797 #: src/fu-util.c:1724
799798 msgid "Refresh metadata from remote server"
800799 msgstr "Metadaten von entferntem Server aktualisieren"
801800
802801 #. TRANSLATORS: command description
803 #: src/fu-util.c:1697
802 #: src/fu-util.c:1730
804803 msgid "Update the stored metadata with current ROM contents"
805804 msgstr "Gespeicherte Metadaten mit dem aktuellen ROM-Inhalt aktualisieren"
806805
807806 #. TRANSLATORS: command description
808 #: src/fu-util.c:1703
807 #: src/fu-util.c:1736
809808 msgid "Monitor the daemon for events"
810809 msgstr "Den Daemon auf Ereignisse überwachen"
811810
812811 #. TRANSLATORS: command description
813 #: src/fu-util.c:1709
812 #: src/fu-util.c:1742
814813 msgid "Build firmware using a sandbox"
815814 msgstr ""
816815
816 #. TRANSLATORS: command description
817 #: src/fu-util.c:1748
818 msgid "Dump SMBIOS data from a file"
819 msgstr ""
820
821 #. TRANSLATORS: command description
822 #: src/fu-util.c:1754
823 msgid "Modifies a given remote"
824 msgstr ""
825
817826 #. TRANSLATORS: program name
818 #: src/fu-util.c:1728
827 #: src/fu-util.c:1773
819828 msgid "Firmware Utility"
820829 msgstr "Firmware-Werkzeug"
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: English (United Kingdom) (http://www.transifex.com/freedesktop/fwupd/language/en_GB/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Alias to %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Command not found"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr ""
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr ""
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr ""
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr ""
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Detaching"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "Attaching"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Added"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Removed"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Changed"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Cancelled"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Name"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Cipher"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Region"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Found"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr ""
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Status"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Unknown: permission denied"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr ""
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Mode"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "State"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr ""
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Quirks"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Convert firmware to DFU format"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Merge multiple firmware files into one"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Set vendor ID on firmware file"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Set product ID on firmware file"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Set release version on firmware file"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Set alternative number on firmware file"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Set alternative name on firmware file"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Attach DFU capable device back to runtime"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Read firmware from device into a file"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Read firmware from one partition into a file"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Write firmware from file into device"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Write firmware from file into one partition"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "List currently attached DFU capable devices"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Detach currently attached DFU capable device"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Dump details about a firmware file"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Watch DFU devices being hotplugged"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Encrypt firmware data"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Decrypt firmware data"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Sets metadata on a firmware file"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "DFU Utility"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Failed to parse arguments"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr "Show debugging options"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Exit after a small delay"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Exit after the engine has loaded"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Firmware Update Daemon"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Firmware Update D-Bus Service"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr ""
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr ""
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr ""
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr ""
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr ""
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr ""
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr ""
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr ""
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "No hardware detected with firmware update capability"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Retrying as an offline update"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Reinstalling %s with %s... "
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Downgrading %s from %s to %s... "
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Updating %s from %s to %s... "
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Done!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "OK"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Version"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Description"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "Checksum"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "%s has firmware updates:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr ""
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr ""
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr ""
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr ""
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Location"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr ""
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr ""
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr ""
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Show extra debugging information"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Allow re-installing existing firmware versions"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Allow downgrading firmware versions"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Get all devices that support firmware updates"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Install prepared updates now"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Install a firmware file on this hardware"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Gets details about a firmware file"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Gets the list of updates for connected hardware"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Updates all firmware to latest versions available"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Gets the cryptographic hash of the dumped firmware"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Clears the results from the last update"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Gets the results from the last update"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Refresh metadata from remote server"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "Update the stored metadata with current ROM contents"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Firmware Utility"
+184
-175
po/eu.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Basque (http://www.transifex.com/freedesktop/fwupd/language/eu/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr ""
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Ez da komandoa aurkitu"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Irakurtzen"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Idazten"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Egiaztatzen"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Ezabatzen"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr ""
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr ""
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Gehitua"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Kendua"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Aldatua"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr ""
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "IDa"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Izena"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr ""
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Eskualdea"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Aurkitua"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protokoloa"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Egoera"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Ezezaguna: baimena ukatu da"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr ""
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr ""
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr ""
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr ""
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr ""
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr ""
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr ""
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr ""
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr ""
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr ""
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr ""
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr ""
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr ""
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr ""
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr ""
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr ""
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr ""
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr ""
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr ""
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr ""
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr ""
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr ""
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr ""
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr ""
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr ""
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr ""
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr ""
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr ""
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr ""
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr ""
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr ""
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr ""
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr ""
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr ""
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr ""
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr ""
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr ""
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr ""
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr ""
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr ""
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr ""
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr ""
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr ""
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr ""
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr ""
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr ""
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr ""
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr ""
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr ""
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr ""
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr ""
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr ""
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr ""
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr ""
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr ""
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr ""
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr ""
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr ""
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr ""
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr ""
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr ""
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr ""
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr ""
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr ""
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr ""
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr ""
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr ""
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr ""
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr ""
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr ""
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr ""
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr ""
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr ""
+184
-175
po/fi.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Finnish (http://www.transifex.com/freedesktop/fwupd/language/fi/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr ""
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Komentoa ei löytynyt"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Luetaan"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Kirjoitetaan"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Vahvistetaan"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr ""
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr ""
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr ""
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Lisätty"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Poistettu"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Muutettu"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Peruttu"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr ""
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Nimi"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr ""
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr ""
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr ""
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr ""
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr ""
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr ""
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr ""
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr ""
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr ""
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr ""
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr ""
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr ""
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr ""
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr ""
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr ""
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr ""
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr ""
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr ""
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr ""
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr ""
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr ""
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr ""
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr ""
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr ""
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr ""
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr ""
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr ""
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr ""
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr ""
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr ""
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr ""
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr ""
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr ""
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr ""
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr ""
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr ""
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr ""
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Jouten…"
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "Puretaan…"
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "Ladataan…"
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "Käynnistetään laite uudelleen…"
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "Kirjoitetaan…"
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "Vahvistetaan…"
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Ajoitetaan…"
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr "Ladataan…"
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Tuntematon"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr ""
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr ""
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr ""
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr ""
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr ""
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Valmis!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "OK"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Versio"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Kuvaus"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr ""
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr ""
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr ""
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr ""
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr ""
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr ""
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr "Tyyppi"
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr "Käyttäjätunnus"
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr "Salasana"
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr "Tiedostonimi"
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Sijainti"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Laite lisätty:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Laite poistettu:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr ""
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr ""
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr ""
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr ""
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr ""
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr ""
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr ""
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr ""
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr ""
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr ""
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr ""
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr ""
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr ""
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr ""
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr ""
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr ""
+184
-175
po/fr.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: French (http://www.transifex.com/freedesktop/fwupd/language/fr/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Alias de %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr ""
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr ""
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr ""
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr ""
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr ""
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr ""
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr ""
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr ""
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr ""
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr ""
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr ""
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr ""
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr ""
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr ""
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr ""
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr ""
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr ""
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr ""
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr ""
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr ""
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr ""
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr ""
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr ""
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr ""
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr ""
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr ""
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr ""
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr ""
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr ""
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr ""
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr ""
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr ""
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr ""
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr ""
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr ""
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr ""
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr ""
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr ""
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr ""
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr ""
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr ""
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr ""
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr ""
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr ""
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Echec de l'analyse des paramètres"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr "Montrer les options de débogage"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Quitter après un bref délai"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Quitter après le chargement du moteur"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr ""
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Service D-Bus de mise à jour des micrologiciels"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr ""
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr ""
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr ""
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr ""
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr ""
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr ""
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr ""
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr ""
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Aucun matériel ayant des capacités de mise à jour du micrologiciel n'a été détecté"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr ""
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Réinstallation de %s en %s"
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Rétrogradation de %s de %s en %s"
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Mise à jour de %s de %s en %s"
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Terminé !"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr ""
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr ""
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr ""
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr ""
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr ""
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr ""
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr ""
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr ""
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr ""
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr ""
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr ""
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr ""
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr ""
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Montre des informations de débogage complémentaires"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr ""
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr ""
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Obtenir la liste des périphériques supportant les mises à jour de micrologiciel"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Installer immédiatement les mises à jour préparées"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Installer un fichier de micrologiciel sur ce matériel"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Obtenir les détails d'un fichier de micrologiciel"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr ""
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr ""
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr ""
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr ""
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr ""
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr ""
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr ""
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr ""
+184
-175
po/he.po less more
88 msgstr ""
99 "Project-Id-Version: fwupd\n"
1010 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
12 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
11 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
12 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1313 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1414 "Language-Team: Hebrew (http://www.transifex.com/freedesktop/fwupd/language/he/)\n"
1515 "MIME-Version: 1.0\n"
105105 "Authentication is required to update the stored checksums for the device"
106106 msgstr ""
107107
108 #: policy/org.freedesktop.fwupd.policy.in:105
109 msgid "Modify a configured remote"
110 msgstr ""
111
112 #. TRANSLATORS: this is the PolicyKit modal dialog
113 #: policy/org.freedesktop.fwupd.policy.in:107
114 msgid ""
115 "Authentication is required to modify a configured remote used for firmware "
116 "updates"
117 msgstr ""
118
108119 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
109 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
120 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
110121 #: src/fu-util.c:112
111122 #, c-format
112123 msgid "Alias to %s"
113124 msgstr "כינוי עבור %s"
114125
115126 #. TRANSLATORS: error message
116 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
127 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
117128 #: src/fu-util.c:176
118129 msgid "Command not found"
119130 msgstr "פקודה לא נמצאה"
120131
121 #. TRANSLATORS: read from device to host
122 #: libdfu/dfu-tool.c:1236
123 msgid "Reading"
124 msgstr ""
125
126 #. TRANSLATORS: write from host to device
127 #: libdfu/dfu-tool.c:1242
128 msgid "Writing"
129 msgstr ""
130
131 #. TRANSLATORS: read from device to host
132 #: libdfu/dfu-tool.c:1248
133 msgid "Verifying"
134 msgstr ""
135
136 #. TRANSLATORS: read from device to host
137 #: libdfu/dfu-tool.c:1254
138 msgid "Erasing"
139 msgstr ""
140
141 #. TRANSLATORS: waiting for device
142 #: libdfu/dfu-tool.c:1260
143 msgid "Detaching"
144 msgstr ""
145
146 #. TRANSLATORS: waiting for device
147 #: libdfu/dfu-tool.c:1266
148 msgid "Attaching"
149 msgstr ""
150
151132 #. TRANSLATORS: this is when a device is hotplugged
152 #: libdfu/dfu-tool.c:1487
133 #: plugins/dfu/dfu-tool.c:1440
153134 msgid "Added"
154135 msgstr ""
155136
156137 #. TRANSLATORS: this is when a device is hotplugged
157 #: libdfu/dfu-tool.c:1498
138 #: plugins/dfu/dfu-tool.c:1451
158139 msgid "Removed"
159140 msgstr ""
160141
161142 #. TRANSLATORS: this is when a device is hotplugged
162143 #. TRANSLATORS: this is when the daemon state changes
163 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
144 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
164145 msgid "Changed"
165146 msgstr ""
166147
167148 #. TRANSLATORS: this is when a device ctrl+c's a watch
168 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
149 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
169150 msgid "Cancelled"
170151 msgstr ""
171152
172153 #. TRANSLATORS: Appstream ID for the hardware type
173 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
154 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
174155 msgid "ID"
175156 msgstr ""
176157
177158 #. TRANSLATORS: interface name, e.g. "Flash"
178159 #. TRANSLATORS: device name, e.g. 'ColorHug2'
179 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
160 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
161 #: plugins/dfu/dfu-tool.c:2065
180162 msgid "Name"
181163 msgstr ""
182164
183165 #. TRANSLATORS: this is the encryption method used when writing
184 #: libdfu/dfu-tool.c:2043
166 #: plugins/dfu/dfu-tool.c:1985
185167 msgid "Cipher"
186168 msgstr ""
187169
188170 #. TRANSLATORS: these are areas of memory on the chip
189 #: libdfu/dfu-tool.c:2057
171 #: plugins/dfu/dfu-tool.c:1999
190172 msgid "Region"
191173 msgstr ""
192174
193175 #. TRANSLATORS: detected a DFU device
194 #: libdfu/dfu-tool.c:2092
176 #: plugins/dfu/dfu-tool.c:2033
195177 msgid "Found"
196178 msgstr ""
197179
198180 #. TRANSLATORS: DFU protocol version, e.g. 1.1
199 #: libdfu/dfu-tool.c:2100
181 #: plugins/dfu/dfu-tool.c:2041
200182 msgid "Protocol"
201183 msgstr ""
202184
203185 #. TRANSLATORS: probably not run as root...
204186 #. TRANSLATORS: device has failed to report status
205187 #. TRANSLATORS: device status, e.g. "OK"
206 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
188 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
189 #: plugins/dfu/dfu-tool.c:2080
207190 msgid "Status"
208191 msgstr ""
209192
210 #: libdfu/dfu-tool.c:2112
193 #: plugins/dfu/dfu-tool.c:2054
211194 msgid "Unknown: permission denied"
212195 msgstr ""
213196
214197 #. TRANSLATORS: serial number, e.g. '00012345'
215 #: libdfu/dfu-tool.c:2129
198 #: plugins/dfu/dfu-tool.c:2071
216199 msgid "Serial"
217200 msgstr ""
218201
219202 #. TRANSLATORS: device mode, e.g. runtime or DFU
220 #: libdfu/dfu-tool.c:2134
203 #: plugins/dfu/dfu-tool.c:2076
221204 msgid "Mode"
222205 msgstr ""
223206
224207 #. TRANSLATORS: device state, i.e. appIDLE
225 #: libdfu/dfu-tool.c:2142
208 #: plugins/dfu/dfu-tool.c:2084
226209 msgid "State"
227210 msgstr ""
228211
229212 #. TRANSLATORS: transfer size in bytes
230 #: libdfu/dfu-tool.c:2150
213 #: plugins/dfu/dfu-tool.c:2092
231214 msgid "Transfer Size"
232215 msgstr ""
233216
234217 #. TRANSLATORS: device quirks, i.e. things that
235218 #. * it does that we have to work around
236 #: libdfu/dfu-tool.c:2158
219 #: plugins/dfu/dfu-tool.c:2100
237220 msgid "Quirks"
238221 msgstr ""
239222
240223 #. TRANSLATORS: command description
241 #: libdfu/dfu-tool.c:2237
224 #: plugins/dfu/dfu-tool.c:2181
242225 msgid "Convert firmware to DFU format"
243226 msgstr ""
244227
245228 #. TRANSLATORS: command description
246 #: libdfu/dfu-tool.c:2243
229 #: plugins/dfu/dfu-tool.c:2187
247230 msgid "Merge multiple firmware files into one"
248231 msgstr ""
249232
250233 #. TRANSLATORS: command description
251 #: libdfu/dfu-tool.c:2249
234 #: plugins/dfu/dfu-tool.c:2193
252235 msgid "Set vendor ID on firmware file"
253236 msgstr ""
254237
255238 #. TRANSLATORS: command description
256 #: libdfu/dfu-tool.c:2255
239 #: plugins/dfu/dfu-tool.c:2199
257240 msgid "Set product ID on firmware file"
258241 msgstr ""
259242
260243 #. TRANSLATORS: command description
261 #: libdfu/dfu-tool.c:2261
244 #: plugins/dfu/dfu-tool.c:2205
262245 msgid "Set element address on firmware file"
263246 msgstr ""
264247
265248 #. TRANSLATORS: command description
266 #: libdfu/dfu-tool.c:2267
249 #: plugins/dfu/dfu-tool.c:2211
267250 msgid "Set the firmware size for the target"
268251 msgstr ""
269252
270253 #. TRANSLATORS: command description
271 #: libdfu/dfu-tool.c:2273
254 #: plugins/dfu/dfu-tool.c:2217
272255 msgid "Set release version on firmware file"
273256 msgstr ""
274257
275258 #. TRANSLATORS: command description
276 #: libdfu/dfu-tool.c:2279
259 #: plugins/dfu/dfu-tool.c:2223
277260 msgid "Set alternative number on firmware file"
278261 msgstr ""
279262
280263 #. TRANSLATORS: command description
281 #: libdfu/dfu-tool.c:2285
264 #: plugins/dfu/dfu-tool.c:2229
282265 msgid "Set alternative name on firmware file"
283266 msgstr ""
284267
285268 #. TRANSLATORS: command description
286 #: libdfu/dfu-tool.c:2291
269 #: plugins/dfu/dfu-tool.c:2235
287270 msgid "Attach DFU capable device back to runtime"
288271 msgstr ""
289272
290273 #. TRANSLATORS: command description
291 #: libdfu/dfu-tool.c:2297
274 #: plugins/dfu/dfu-tool.c:2241
292275 msgid "Read firmware from device into a file"
293276 msgstr ""
294277
295278 #. TRANSLATORS: command description
296 #: libdfu/dfu-tool.c:2303
279 #: plugins/dfu/dfu-tool.c:2247
297280 msgid "Read firmware from one partition into a file"
298281 msgstr ""
299282
300283 #. TRANSLATORS: command description
301 #: libdfu/dfu-tool.c:2309
284 #: plugins/dfu/dfu-tool.c:2253
302285 msgid "Write firmware from file into device"
303286 msgstr ""
304287
305288 #. TRANSLATORS: command description
306 #: libdfu/dfu-tool.c:2315
289 #: plugins/dfu/dfu-tool.c:2259
307290 msgid "Write firmware from file into one partition"
308291 msgstr ""
309292
310293 #. TRANSLATORS: command description
311 #: libdfu/dfu-tool.c:2321
294 #: plugins/dfu/dfu-tool.c:2265
312295 msgid "List currently attached DFU capable devices"
313296 msgstr ""
314297
315298 #. TRANSLATORS: command description
316 #: libdfu/dfu-tool.c:2327
299 #: plugins/dfu/dfu-tool.c:2271
317300 msgid "Detach currently attached DFU capable device"
318301 msgstr ""
319302
320303 #. TRANSLATORS: command description
321 #: libdfu/dfu-tool.c:2333
304 #: plugins/dfu/dfu-tool.c:2277
322305 msgid "Dump details about a firmware file"
323306 msgstr ""
324307
325308 #. TRANSLATORS: command description
326 #: libdfu/dfu-tool.c:2339
309 #: plugins/dfu/dfu-tool.c:2283
327310 msgid "Watch DFU devices being hotplugged"
328311 msgstr ""
329312
330313 #. TRANSLATORS: command description
331 #: libdfu/dfu-tool.c:2345
314 #: plugins/dfu/dfu-tool.c:2289
332315 msgid "Encrypt firmware data"
333316 msgstr ""
334317
335318 #. TRANSLATORS: command description
336 #: libdfu/dfu-tool.c:2351
319 #: plugins/dfu/dfu-tool.c:2295
337320 msgid "Decrypt firmware data"
338321 msgstr ""
339322
340323 #. TRANSLATORS: command description
341 #: libdfu/dfu-tool.c:2357
324 #: plugins/dfu/dfu-tool.c:2301
342325 msgid "Sets metadata on a firmware file"
343326 msgstr ""
344327
345328 #. TRANSLATORS: command description
346 #: libdfu/dfu-tool.c:2363
329 #: plugins/dfu/dfu-tool.c:2307
347330 msgid "Replace data in an existing firmware file"
348331 msgstr ""
349332
350333 #. TRANSLATORS: command description
351 #: libdfu/dfu-tool.c:2369
334 #: plugins/dfu/dfu-tool.c:2313
352335 msgid "Create a binary patch using two files"
353336 msgstr ""
354337
355338 #. TRANSLATORS: command description
356 #: libdfu/dfu-tool.c:2375
339 #: plugins/dfu/dfu-tool.c:2319
357340 msgid "Apply a binary patch"
358341 msgstr ""
359342
360343 #. TRANSLATORS: command description
361 #: libdfu/dfu-tool.c:2381
344 #: plugins/dfu/dfu-tool.c:2325
362345 msgid "Dump information about a binary patch to the screen"
363346 msgstr ""
364347
365348 #. TRANSLATORS: DFU stands for device firmware update
366 #: libdfu/dfu-tool.c:2407
349 #: plugins/dfu/dfu-tool.c:2351
367350 msgid "DFU Utility"
368351 msgstr ""
369352
370353 #. TRANSLATORS: the user didn't read the man page
371 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
372 #: src/fu-util.c:1733
354 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
355 #: src/fu-util.c:1778
373356 msgid "Failed to parse arguments"
374357 msgstr "נכשל בפענוח הארגומנטים"
375358
376359 #. TRANSLATORS: command description
377 #: plugins/synapticsmst/synapticsmst-tool.c:408
360 #: plugins/synapticsmst/synapticsmst-tool.c:400
378361 msgid "Enumerate all Synaptics MST devices"
379362 msgstr ""
380363
381364 #. TRANSLATORS: command description
382 #: plugins/synapticsmst/synapticsmst-tool.c:414
365 #: plugins/synapticsmst/synapticsmst-tool.c:406
383366 msgid "Flash firmware file to MST device"
384367 msgstr ""
385368
386 #: plugins/synapticsmst/synapticsmst-tool.c:434
369 #: plugins/synapticsmst/synapticsmst-tool.c:426
387370 msgid "Synaptics Multistream Transport Utility"
388371 msgstr ""
389372
390373 #. TRANSLATORS: this is shown when updating the firmware after the reboot
391 #: plugins/uefi/fu-plugin-uefi.c:194
374 #: plugins/uefi/fu-plugin-uefi.c:396
392375 msgid "Installing firmware update…"
393376 msgstr ""
394377
408391 msgstr "הצג אפשרויות ניפוי שגיאות"
409392
410393 #. TRANSLATORS: exit after we've started up, used for user profiling
411 #: src/fu-main.c:863
394 #: src/fu-main.c:960
412395 msgid "Exit after a small delay"
413396 msgstr "יציאה לאחר השהייה קצרה"
414397
415398 #. TRANSLATORS: exit straight away, used for automatic profiling
416 #: src/fu-main.c:866
399 #: src/fu-main.c:963
417400 msgid "Exit after the engine has loaded"
418401 msgstr "יציאה לאחר טעינת מנוע התכנה"
419402
420403 #. TRANSLATORS: program name
421 #: src/fu-main.c:880
404 #: src/fu-main.c:977
422405 msgid "Firmware Update Daemon"
423406 msgstr "שדון עדכון קושחה"
424407
425408 #. TRANSLATORS: program summary
426 #: src/fu-main.c:885
409 #: src/fu-main.c:982
427410 msgid "Firmware Update D-Bus Service"
428411 msgstr "שירות D-Bus עדכון קושחה"
429412
430413 #. TRANSLATORS: daemon is inactive
431 #: src/fu-progressbar.c:51
414 #: src/fu-progressbar.c:52
432415 msgid "Idle…"
433416 msgstr ""
434417
435418 #. TRANSLATORS: decompressing the firmware file
436 #: src/fu-progressbar.c:55
419 #: src/fu-progressbar.c:56
437420 msgid "Decompressing…"
438421 msgstr ""
439422
440423 #. TRANSLATORS: parsing the firmware information
441 #: src/fu-progressbar.c:59
424 #: src/fu-progressbar.c:60
442425 msgid "Loading…"
443426 msgstr ""
444427
445428 #. TRANSLATORS: restarting the device to pick up new F/W
446 #: src/fu-progressbar.c:63
429 #: src/fu-progressbar.c:64
447430 msgid "Restarting device…"
448431 msgstr ""
449432
433 #. TRANSLATORS: reading from the flash chips
434 #: src/fu-progressbar.c:68
435 msgid "Reading…"
436 msgstr ""
437
450438 #. TRANSLATORS: writing to the flash chips
451 #: src/fu-progressbar.c:67
439 #: src/fu-progressbar.c:72
452440 msgid "Writing…"
453441 msgstr ""
454442
443 #. TRANSLATORS: erasing contents of the flash chips
444 #: src/fu-progressbar.c:76
445 msgid "Erasing…"
446 msgstr ""
447
455448 #. TRANSLATORS: verifying we wrote the firmware correctly
456 #: src/fu-progressbar.c:71
449 #: src/fu-progressbar.c:80
457450 msgid "Verifying…"
458451 msgstr ""
459452
460453 #. TRANSLATORS: scheduing an update to be done on the next boot
461 #: src/fu-progressbar.c:75
454 #: src/fu-progressbar.c:84
462455 msgid "Scheduling…"
463456 msgstr ""
464457
465458 #. TRANSLATORS: downloading from a remote server
466 #: src/fu-progressbar.c:79
459 #: src/fu-progressbar.c:88
467460 msgid "Downloading…"
468461 msgstr ""
469462
463 #. TRANSLATORS: waiting for user to authenticate
464 #: src/fu-progressbar.c:92
465 msgid "Authenticating…"
466 msgstr ""
467
470468 #. TRANSLATORS: currect daemon status is unknown
471 #: src/fu-progressbar.c:86
469 #: src/fu-progressbar.c:99
472470 msgid "Unknown"
473471 msgstr ""
474472
488486 msgid "No hardware detected with firmware update capability"
489487 msgstr "לא אותרה חומרה בעלת יכולת עדכון קושחה"
490488
491 #. TRANSLATOR: the plugin only supports offline
492 #: src/fu-util.c:337
493 msgid "Retrying as an offline update"
494 msgstr ""
495
496489 #. TRANSLATORS: the first replacement is a display name
497490 #. * e.g. "ColorHugALS" and the second is a version number
498491 #. * e.g. "1.2.3"
499 #: src/fu-util.c:501
492 #: src/fu-util.c:474
500493 #, c-format
501494 msgid "Reinstalling %s with %s... "
502495 msgstr "מתקין מחדש %s עם %s..."
504497 #. TRANSLATORS: the first replacement is a display name
505498 #. * e.g. "ColorHugALS" and the second and third are
506499 #. * version numbers e.g. "1.2.3"
507 #: src/fu-util.c:508
500 #: src/fu-util.c:481
508501 #, c-format
509502 msgid "Downgrading %s from %s to %s... "
510503 msgstr "משנמך גרסת %s מ־%s ל־%s..."
512505 #. TRANSLATORS: the first replacement is a display name
513506 #. * e.g. "ColorHugALS" and the second and third are
514507 #. * version numbers e.g. "1.2.3"
515 #: src/fu-util.c:516
508 #: src/fu-util.c:489
516509 #, c-format
517510 msgid "Updating %s from %s to %s... "
518511 msgstr "מעדכן %s מ־%s ל־%s..."
519512
520 #: src/fu-util.c:543
513 #: src/fu-util.c:516
521514 msgid "Done!"
522515 msgstr "הסתיים!"
523516
524 #: src/fu-util.c:585 src/fu-util.c:985
517 #: src/fu-util.c:565 src/fu-util.c:978
525518 msgid "OK"
526519 msgstr "אישור"
527520
528521 #. TRANSLATORS: downloading new signing file
529 #: src/fu-util.c:719
522 #: src/fu-util.c:699
530523 msgid "Fetching signature"
531524 msgstr ""
532525
533526 #. TRANSLATORS: downloading new metadata file
534 #: src/fu-util.c:722
527 #: src/fu-util.c:702
535528 msgid "Fetching metadata"
536529 msgstr ""
537530
538531 #. TRANSLATORS: downloading new firmware file
539 #: src/fu-util.c:725
532 #: src/fu-util.c:705
540533 msgid "Fetching firmware"
541534 msgstr ""
542535
543536 #. TRANSLATORS: downloading unknown file
544 #: src/fu-util.c:728
537 #: src/fu-util.c:708
545538 msgid "Fetching file"
546539 msgstr ""
547540
548541 #. TRANSLATORS: section header for release version number
549 #: src/fu-util.c:898
542 #: src/fu-util.c:888
550543 msgid "Version"
551544 msgstr "גרסא"
552545
546 #. TRANSLATORS: section header for the remote the file is coming from
547 #: src/fu-util.c:891
548 msgid "Remote"
549 msgstr ""
550
553551 #. TRANSLATORS: section header for firmware URI
554 #: src/fu-util.c:901
552 #: src/fu-util.c:894
555553 msgid "URI"
556554 msgstr ""
557555
558556 #. TRANSLATORS: section header for firmware description
559 #: src/fu-util.c:907
557 #: src/fu-util.c:900
560558 msgid "Description"
561559 msgstr "תיאור"
562560
563561 #. TRANSLATORS: section header for firmware checksum
564 #: src/fu-util.c:915
562 #. TRANSLATORS: remote checksum
563 #: src/fu-util.c:908 src/fu-util.c:1136
565564 msgid "Checksum"
566565 msgstr "סכום ביקורת"
567566
568567 #. TRANSLATORS: get interactive prompt
569 #: src/fu-util.c:947
568 #: src/fu-util.c:940
570569 msgid "Choose a release:"
571570 msgstr ""
572571
573572 #. TRANSLATORS: first replacement is device name
574 #: src/fu-util.c:1036
573 #: src/fu-util.c:1041
575574 #, c-format
576575 msgid "%s has firmware updates:"
577576 msgstr "ישנם עדכוני קושחה עבור %s:"
578577
579 #: src/fu-util.c:1046
578 #: src/fu-util.c:1048
580579 msgid "GUID"
581580 msgstr ""
582581
583582 #. TRANSLATORS: section header for firmware version
584 #: src/fu-util.c:1050
583 #: src/fu-util.c:1060
585584 msgid "Update Version"
586585 msgstr ""
587586
588587 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
589 #: src/fu-util.c:1054
588 #: src/fu-util.c:1064
590589 msgid "Update Remote ID"
591590 msgstr ""
592591
593592 #. TRANSLATORS: section header for firmware checksum
594 #: src/fu-util.c:1063
593 #: src/fu-util.c:1073
595594 msgid "Update Checksum"
596595 msgstr ""
597596
598597 #. TRANSLATORS: section header for firmware remote http://
599 #: src/fu-util.c:1067
598 #: src/fu-util.c:1077
600599 msgid "Update Location"
601600 msgstr ""
602601
603602 #. TRANSLATORS: section header for long firmware desc
604 #: src/fu-util.c:1078
603 #: src/fu-util.c:1088
605604 msgid "Update Description"
606605 msgstr ""
607606
608607 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
609 #: src/fu-util.c:1104
608 #: src/fu-util.c:1114
610609 msgid "Remote ID"
611610 msgstr ""
612611
612 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
613 #: src/fu-util.c:1118
614 msgid "Title"
615 msgstr ""
616
613617 #. TRANSLATORS: remote type, e.g. remote or local
614 #: src/fu-util.c:1108
618 #: src/fu-util.c:1122
615619 msgid "Type"
616620 msgstr ""
617621
618 #: src/fu-util.c:1113
622 #: src/fu-util.c:1127
619623 msgid "Keyring"
620624 msgstr ""
621625
622626 #. TRANSLATORS: if the remote is enabled
623 #: src/fu-util.c:1118
627 #: src/fu-util.c:1132
624628 msgid "Enabled"
625629 msgstr ""
626630
627631 #. TRANSLATORS: the age of the metadata
628 #: src/fu-util.c:1145
632 #: src/fu-util.c:1163
629633 msgid "Age"
630634 msgstr ""
631635
632636 #. TRANSLATORS: the numeric priority
633 #: src/fu-util.c:1152
637 #: src/fu-util.c:1170
634638 msgid "Priority"
635639 msgstr ""
636640
637641 #. TRANSLATORS: remote filename base
638 #: src/fu-util.c:1157
642 #: src/fu-util.c:1175
639643 msgid "Username"
640644 msgstr ""
641645
642646 #. TRANSLATORS: remote filename base
643 #: src/fu-util.c:1162
647 #: src/fu-util.c:1180
644648 msgid "Password"
645649 msgstr ""
646650
647 #. TRANSLATORS: remote filename base
648 #: src/fu-util.c:1167
651 #. TRANSLATORS: filename of the local file
652 #: src/fu-util.c:1185
649653 msgid "Filename"
650654 msgstr ""
651655
652 #. TRANSLATORS: remote filename base
653 #: src/fu-util.c:1172
656 #. TRANSLATORS: filename of the local file
657 #: src/fu-util.c:1190
654658 msgid "Filename Signature"
655659 msgstr ""
656660
657 #. TRANSLATORS: locatation of the local file
658 #: src/fu-util.c:1177
659 msgid "Location"
660 msgstr "מיקום"
661
662 #. TRANSLATORS: locatation of the local file
663 #: src/fu-util.c:1182
664 msgid "Location Signature"
665 msgstr ""
666
667661 #. TRANSLATORS: remote URI
668 #: src/fu-util.c:1187
662 #: src/fu-util.c:1195
669663 msgid "Metadata URI"
670664 msgstr ""
671665
672666 #. TRANSLATORS: remote URI
673 #: src/fu-util.c:1192
667 #: src/fu-util.c:1200
674668 msgid "Metadata URI Signature"
675669 msgstr ""
676670
677671 #. TRANSLATORS: remote URI
678 #: src/fu-util.c:1197
672 #: src/fu-util.c:1205
679673 msgid "Firmware Base URI"
680674 msgstr ""
681675
682676 #. TRANSLATORS: this is when a device is hotplugged
683 #: src/fu-util.c:1224
677 #: src/fu-util.c:1232
684678 msgid "Device added:"
685679 msgstr ""
686680
687681 #. TRANSLATORS: this is when a device is hotplugged
688 #: src/fu-util.c:1234
682 #: src/fu-util.c:1242
689683 msgid "Device removed:"
690684 msgstr ""
691685
692686 #. TRANSLATORS: this is when a device has been updated
693 #: src/fu-util.c:1244
687 #: src/fu-util.c:1252
694688 msgid "Device changed:"
695689 msgstr ""
696690
697691 #. TRANSLATORS: command line option
698 #: src/fu-util.c:1568
692 #: src/fu-util.c:1595
699693 msgid "Show extra debugging information"
700694 msgstr "הצג מידע ניפוי שגיאות מורחב"
701695
702696 #. TRANSLATORS: command line option
703 #: src/fu-util.c:1571
697 #: src/fu-util.c:1598
704698 msgid "Show client and daemon versions"
705699 msgstr ""
706700
707701 #. TRANSLATORS: command line option
708 #: src/fu-util.c:1574
702 #: src/fu-util.c:1601
709703 msgid "Schedule installation for next reboot when possible"
710704 msgstr ""
711705
712706 #. TRANSLATORS: command line option
713 #: src/fu-util.c:1577
707 #: src/fu-util.c:1604
714708 msgid "Allow re-installing existing firmware versions"
715709 msgstr ""
716710
717711 #. TRANSLATORS: command line option
718 #: src/fu-util.c:1580
712 #: src/fu-util.c:1607
719713 msgid "Allow downgrading firmware versions"
720714 msgstr ""
721715
722716 #. TRANSLATORS: command line option
723 #: src/fu-util.c:1583
717 #: src/fu-util.c:1610
724718 msgid "Override plugin warning"
725719 msgstr ""
726720
727721 #. TRANSLATORS: command description
728 #: src/fu-util.c:1607
722 #: src/fu-util.c:1634
729723 msgid "Get all devices that support firmware updates"
730724 msgstr "מציג כל המכשירים התומכים בעדכוני קושחה"
731725
732726 #. TRANSLATORS: command description
733 #: src/fu-util.c:1613
727 #: src/fu-util.c:1640
734728 msgid "Return all the hardware IDs for the machine"
735729 msgstr ""
736730
737731 #. TRANSLATORS: command description
738 #: src/fu-util.c:1619
732 #: src/fu-util.c:1646
739733 msgid "Install prepared updates now"
740734 msgstr "מתקין כעת עדכונים מוכנים"
741735
742736 #. TRANSLATORS: command description
743 #: src/fu-util.c:1625
737 #: src/fu-util.c:1652
744738 msgid "Install a firmware file on this hardware"
745739 msgstr "מתקין קובץ קושחה בחומרה זו"
746740
747741 #. TRANSLATORS: command description
748 #: src/fu-util.c:1631
742 #: src/fu-util.c:1658
749743 msgid "Gets details about a firmware file"
750744 msgstr "מציג פרטים אודות קובץ קושחה"
751745
752746 #. TRANSLATORS: command description
753 #: src/fu-util.c:1637
747 #: src/fu-util.c:1664
754748 msgid "Gets the list of updates for connected hardware"
755749 msgstr ""
756750
757751 #. TRANSLATORS: command description
758 #: src/fu-util.c:1643
752 #: src/fu-util.c:1670
759753 msgid "Updates all firmware to latest versions available"
760754 msgstr ""
761755
762756 #. TRANSLATORS: command description
763 #: src/fu-util.c:1649
757 #: src/fu-util.c:1676
764758 msgid "Gets the cryptographic hash of the dumped firmware"
765759 msgstr ""
766760
767761 #. TRANSLATORS: command description
768 #: src/fu-util.c:1655
762 #: src/fu-util.c:1682
769763 msgid "Unlocks the device for firmware access"
770764 msgstr ""
771765
772766 #. TRANSLATORS: command description
773 #: src/fu-util.c:1661
767 #: src/fu-util.c:1688
774768 msgid "Clears the results from the last update"
775769 msgstr ""
776770
777771 #. TRANSLATORS: command description
778 #: src/fu-util.c:1667
772 #: src/fu-util.c:1694
773 msgid "Clears any updates scheduled to be updated offline"
774 msgstr ""
775
776 #. TRANSLATORS: command description
777 #: src/fu-util.c:1700
779778 msgid "Gets the results from the last update"
780779 msgstr ""
781780
782781 #. TRANSLATORS: command description
783 #: src/fu-util.c:1673
782 #: src/fu-util.c:1706
784783 msgid "Gets the releases for a device"
785784 msgstr ""
786785
787786 #. TRANSLATORS: command description
788 #: src/fu-util.c:1679
787 #: src/fu-util.c:1712
789788 msgid "Gets the configured remotes"
790789 msgstr ""
791790
792791 #. TRANSLATORS: command description
793 #: src/fu-util.c:1685
792 #: src/fu-util.c:1718
794793 msgid "Downgrades the firmware on a device"
795794 msgstr ""
796795
797796 #. TRANSLATORS: command description
798 #: src/fu-util.c:1691
797 #: src/fu-util.c:1724
799798 msgid "Refresh metadata from remote server"
800799 msgstr ""
801800
802801 #. TRANSLATORS: command description
803 #: src/fu-util.c:1697
802 #: src/fu-util.c:1730
804803 msgid "Update the stored metadata with current ROM contents"
805804 msgstr ""
806805
807806 #. TRANSLATORS: command description
808 #: src/fu-util.c:1703
807 #: src/fu-util.c:1736
809808 msgid "Monitor the daemon for events"
810809 msgstr ""
811810
812811 #. TRANSLATORS: command description
813 #: src/fu-util.c:1709
812 #: src/fu-util.c:1742
814813 msgid "Build firmware using a sandbox"
815814 msgstr ""
816815
816 #. TRANSLATORS: command description
817 #: src/fu-util.c:1748
818 msgid "Dump SMBIOS data from a file"
819 msgstr ""
820
821 #. TRANSLATORS: command description
822 #: src/fu-util.c:1754
823 msgid "Modifies a given remote"
824 msgstr ""
825
817826 #. TRANSLATORS: program name
818 #: src/fu-util.c:1728
827 #: src/fu-util.c:1773
819828 msgid "Firmware Utility"
820829 msgstr ""
+184
-175
po/hi.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Hindi (http://www.transifex.com/freedesktop/fwupd/language/hi/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "%s का उपनाम "
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr ""
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr ""
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr ""
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr ""
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr ""
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr ""
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr ""
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr ""
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr ""
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr ""
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr ""
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr ""
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr ""
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr ""
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr ""
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr ""
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr ""
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr ""
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr ""
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr ""
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr ""
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr ""
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr ""
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr ""
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr ""
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr ""
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr ""
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr ""
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr ""
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr ""
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr ""
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr ""
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr ""
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr ""
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr ""
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr ""
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr ""
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr ""
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr ""
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr ""
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr ""
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr ""
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr ""
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr ""
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "आर्गुमेंट पार्स करने में असफल "
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr "डिबगिंग के विकल्प दिखाए "
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "थोड़ी देरी के बाद बहार जाएँ "
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "इंजन के लोड हो जाने पर बहार जाएँ "
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr ""
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "फर्मवेयर अपडेट डी-बस सेवा "
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr ""
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr ""
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr ""
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr ""
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr ""
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr ""
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr ""
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr ""
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "अपडेट की क्षमता वाला हार्डवेयर उपलब्ध नहीं "
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr ""
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "%s को %s से दोबारा स्थापित करा जा रहा है "
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "%s की %s से %s तक अधोगति हो रही है "
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "%s को %s से %s तक अपडेट करा जा रहा है "
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "हो गया !"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr ""
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr ""
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr ""
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr ""
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr ""
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr ""
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr ""
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr ""
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr ""
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr ""
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr ""
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr ""
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr ""
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "डिबगिंग की अतिरिक्त जानकारी दिखाएँ "
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr ""
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr ""
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "फर्मवेयर अपडेट का समर्थन करने वाली सभी युक्तियाँ प्राप्त करें "
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "तैयार अपडेट अभी स्थापित करें "
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "फर्मवेयर फाइल को इस हार्डवेयर पर स्थापित करें "
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "फर्मवेयर फाइल की अधिक जानकारी प्राप्त करें "
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr ""
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr ""
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr ""
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr ""
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr ""
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr ""
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr ""
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr ""
+184
-175
po/hr.po less more
99 msgstr ""
1010 "Project-Id-Version: fwupd\n"
1111 "Report-Msgid-Bugs-To: \n"
12 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
13 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
12 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
13 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1414 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1515 "Language-Team: Croatian (http://www.transifex.com/freedesktop/fwupd/language/hr/)\n"
1616 "MIME-Version: 1.0\n"
106106 "Authentication is required to update the stored checksums for the device"
107107 msgstr "Potrebna je ovjera za nadopunu spremljenog kontrolnog zbroja uređaja"
108108
109 #: policy/org.freedesktop.fwupd.policy.in:105
110 msgid "Modify a configured remote"
111 msgstr ""
112
113 #. TRANSLATORS: this is the PolicyKit modal dialog
114 #: policy/org.freedesktop.fwupd.policy.in:107
115 msgid ""
116 "Authentication is required to modify a configured remote used for firmware "
117 "updates"
118 msgstr ""
119
109120 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
110 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
121 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
111122 #: src/fu-util.c:112
112123 #, c-format
113124 msgid "Alias to %s"
114125 msgstr "Zamjena za %s"
115126
116127 #. TRANSLATORS: error message
117 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
128 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
118129 #: src/fu-util.c:176
119130 msgid "Command not found"
120131 msgstr "Naredba nije pronađena"
121132
122 #. TRANSLATORS: read from device to host
123 #: libdfu/dfu-tool.c:1236
124 msgid "Reading"
125 msgstr "Čitanje"
126
127 #. TRANSLATORS: write from host to device
128 #: libdfu/dfu-tool.c:1242
129 msgid "Writing"
130 msgstr "Zapisivanje"
131
132 #. TRANSLATORS: read from device to host
133 #: libdfu/dfu-tool.c:1248
134 msgid "Verifying"
135 msgstr "Provjera"
136
137 #. TRANSLATORS: read from device to host
138 #: libdfu/dfu-tool.c:1254
139 msgid "Erasing"
140 msgstr "Brisanje"
141
142 #. TRANSLATORS: waiting for device
143 #: libdfu/dfu-tool.c:1260
144 msgid "Detaching"
145 msgstr "Odvajanje"
146
147 #. TRANSLATORS: waiting for device
148 #: libdfu/dfu-tool.c:1266
149 msgid "Attaching"
150 msgstr "Povezivanje"
151
152133 #. TRANSLATORS: this is when a device is hotplugged
153 #: libdfu/dfu-tool.c:1487
134 #: plugins/dfu/dfu-tool.c:1440
154135 msgid "Added"
155136 msgstr "Dodano"
156137
157138 #. TRANSLATORS: this is when a device is hotplugged
158 #: libdfu/dfu-tool.c:1498
139 #: plugins/dfu/dfu-tool.c:1451
159140 msgid "Removed"
160141 msgstr "Uklonjeno"
161142
162143 #. TRANSLATORS: this is when a device is hotplugged
163144 #. TRANSLATORS: this is when the daemon state changes
164 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
145 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
165146 msgid "Changed"
166147 msgstr "Promijenjeno"
167148
168149 #. TRANSLATORS: this is when a device ctrl+c's a watch
169 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
150 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
170151 msgid "Cancelled"
171152 msgstr "Prekinuto"
172153
173154 #. TRANSLATORS: Appstream ID for the hardware type
174 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
155 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
175156 msgid "ID"
176157 msgstr "ID"
177158
178159 #. TRANSLATORS: interface name, e.g. "Flash"
179160 #. TRANSLATORS: device name, e.g. 'ColorHug2'
180 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
161 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
162 #: plugins/dfu/dfu-tool.c:2065
181163 msgid "Name"
182164 msgstr "Naziv"
183165
184166 #. TRANSLATORS: this is the encryption method used when writing
185 #: libdfu/dfu-tool.c:2043
167 #: plugins/dfu/dfu-tool.c:1985
186168 msgid "Cipher"
187169 msgstr "Cipher"
188170
189171 #. TRANSLATORS: these are areas of memory on the chip
190 #: libdfu/dfu-tool.c:2057
172 #: plugins/dfu/dfu-tool.c:1999
191173 msgid "Region"
192174 msgstr "Regija"
193175
194176 #. TRANSLATORS: detected a DFU device
195 #: libdfu/dfu-tool.c:2092
177 #: plugins/dfu/dfu-tool.c:2033
196178 msgid "Found"
197179 msgstr "Pronađen"
198180
199181 #. TRANSLATORS: DFU protocol version, e.g. 1.1
200 #: libdfu/dfu-tool.c:2100
182 #: plugins/dfu/dfu-tool.c:2041
201183 msgid "Protocol"
202184 msgstr "Protokol"
203185
204186 #. TRANSLATORS: probably not run as root...
205187 #. TRANSLATORS: device has failed to report status
206188 #. TRANSLATORS: device status, e.g. "OK"
207 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
189 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
190 #: plugins/dfu/dfu-tool.c:2080
208191 msgid "Status"
209192 msgstr "Stanje"
210193
211 #: libdfu/dfu-tool.c:2112
194 #: plugins/dfu/dfu-tool.c:2054
212195 msgid "Unknown: permission denied"
213196 msgstr "Nepoznato: dozvola odbijena"
214197
215198 #. TRANSLATORS: serial number, e.g. '00012345'
216 #: libdfu/dfu-tool.c:2129
199 #: plugins/dfu/dfu-tool.c:2071
217200 msgid "Serial"
218201 msgstr "Serijski broj"
219202
220203 #. TRANSLATORS: device mode, e.g. runtime or DFU
221 #: libdfu/dfu-tool.c:2134
204 #: plugins/dfu/dfu-tool.c:2076
222205 msgid "Mode"
223206 msgstr "Način"
224207
225208 #. TRANSLATORS: device state, i.e. appIDLE
226 #: libdfu/dfu-tool.c:2142
209 #: plugins/dfu/dfu-tool.c:2084
227210 msgid "State"
228211 msgstr "Stanje"
229212
230213 #. TRANSLATORS: transfer size in bytes
231 #: libdfu/dfu-tool.c:2150
214 #: plugins/dfu/dfu-tool.c:2092
232215 msgid "Transfer Size"
233216 msgstr "Veličina prijenosa"
234217
235218 #. TRANSLATORS: device quirks, i.e. things that
236219 #. * it does that we have to work around
237 #: libdfu/dfu-tool.c:2158
220 #: plugins/dfu/dfu-tool.c:2100
238221 msgid "Quirks"
239222 msgstr "Okolnosti uređaja"
240223
241224 #. TRANSLATORS: command description
242 #: libdfu/dfu-tool.c:2237
225 #: plugins/dfu/dfu-tool.c:2181
243226 msgid "Convert firmware to DFU format"
244227 msgstr "Pretvori firmver u DFU format"
245228
246229 #. TRANSLATORS: command description
247 #: libdfu/dfu-tool.c:2243
230 #: plugins/dfu/dfu-tool.c:2187
248231 msgid "Merge multiple firmware files into one"
249232 msgstr "Spoji više frimver datoteka u jednu"
250233
251234 #. TRANSLATORS: command description
252 #: libdfu/dfu-tool.c:2249
235 #: plugins/dfu/dfu-tool.c:2193
253236 msgid "Set vendor ID on firmware file"
254237 msgstr "Postavi ID proizvođača u datoteku firmvera"
255238
256239 #. TRANSLATORS: command description
257 #: libdfu/dfu-tool.c:2255
240 #: plugins/dfu/dfu-tool.c:2199
258241 msgid "Set product ID on firmware file"
259242 msgstr "Postavi ID proizvoda u datoteku firmvera"
260243
261244 #. TRANSLATORS: command description
262 #: libdfu/dfu-tool.c:2261
245 #: plugins/dfu/dfu-tool.c:2205
263246 msgid "Set element address on firmware file"
264247 msgstr "Postavi adresu elementa na datoteku frimvera"
265248
266249 #. TRANSLATORS: command description
267 #: libdfu/dfu-tool.c:2267
250 #: plugins/dfu/dfu-tool.c:2211
268251 msgid "Set the firmware size for the target"
269252 msgstr "Postavi veličinu frimvera za metu"
270253
271254 #. TRANSLATORS: command description
272 #: libdfu/dfu-tool.c:2273
255 #: plugins/dfu/dfu-tool.c:2217
273256 msgid "Set release version on firmware file"
274257 msgstr "Postavi inačicu izdanja u datoteku firmvera"
275258
276259 #. TRANSLATORS: command description
277 #: libdfu/dfu-tool.c:2279
260 #: plugins/dfu/dfu-tool.c:2223
278261 msgid "Set alternative number on firmware file"
279262 msgstr "Postavi zamjenski broj u datoteku firmvera"
280263
281264 #. TRANSLATORS: command description
282 #: libdfu/dfu-tool.c:2285
265 #: plugins/dfu/dfu-tool.c:2229
283266 msgid "Set alternative name on firmware file"
284267 msgstr "Postavi zamjenski naziv u datoteku firmvera"
285268
286269 #. TRANSLATORS: command description
287 #: libdfu/dfu-tool.c:2291
270 #: plugins/dfu/dfu-tool.c:2235
288271 msgid "Attach DFU capable device back to runtime"
289272 msgstr "Poveži DFU sposoban uređaj natrag u vremenu izvršavanja"
290273
291274 #. TRANSLATORS: command description
292 #: libdfu/dfu-tool.c:2297
275 #: plugins/dfu/dfu-tool.c:2241
293276 msgid "Read firmware from device into a file"
294277 msgstr "Očitaj frimver iz uređaja u datoteku"
295278
296279 #. TRANSLATORS: command description
297 #: libdfu/dfu-tool.c:2303
280 #: plugins/dfu/dfu-tool.c:2247
298281 msgid "Read firmware from one partition into a file"
299282 msgstr "Očitaj frimver iz jedne particije u datoteku"
300283
301284 #. TRANSLATORS: command description
302 #: libdfu/dfu-tool.c:2309
285 #: plugins/dfu/dfu-tool.c:2253
303286 msgid "Write firmware from file into device"
304287 msgstr "Zapiši frimver iz datoteke u uređaj"
305288
306289 #. TRANSLATORS: command description
307 #: libdfu/dfu-tool.c:2315
290 #: plugins/dfu/dfu-tool.c:2259
308291 msgid "Write firmware from file into one partition"
309292 msgstr "Zapiši frimver iz datoteke u jednu particiju uređaja"
310293
311294 #. TRANSLATORS: command description
312 #: libdfu/dfu-tool.c:2321
295 #: plugins/dfu/dfu-tool.c:2265
313296 msgid "List currently attached DFU capable devices"
314297 msgstr "Prikaži trenutno povezane DFU sposobne uređaje"
315298
316299 #. TRANSLATORS: command description
317 #: libdfu/dfu-tool.c:2327
300 #: plugins/dfu/dfu-tool.c:2271
318301 msgid "Detach currently attached DFU capable device"
319302 msgstr "Odspoji trenutno povezane DFU sposobne uređaje"
320303
321304 #. TRANSLATORS: command description
322 #: libdfu/dfu-tool.c:2333
305 #: plugins/dfu/dfu-tool.c:2277
323306 msgid "Dump details about a firmware file"
324307 msgstr "Ispiši opširnije pojedinosti o frimveru u datoteku"
325308
326309 #. TRANSLATORS: command description
327 #: libdfu/dfu-tool.c:2339
310 #: plugins/dfu/dfu-tool.c:2283
328311 msgid "Watch DFU devices being hotplugged"
329312 msgstr "Nadgledaj odspajanje DFU uređaja"
330313
331314 #. TRANSLATORS: command description
332 #: libdfu/dfu-tool.c:2345
315 #: plugins/dfu/dfu-tool.c:2289
333316 msgid "Encrypt firmware data"
334317 msgstr "Šifriraj podatke frimvera"
335318
336319 #. TRANSLATORS: command description
337 #: libdfu/dfu-tool.c:2351
320 #: plugins/dfu/dfu-tool.c:2295
338321 msgid "Decrypt firmware data"
339322 msgstr "Dešifriraj podatke frimvera"
340323
341324 #. TRANSLATORS: command description
342 #: libdfu/dfu-tool.c:2357
325 #: plugins/dfu/dfu-tool.c:2301
343326 msgid "Sets metadata on a firmware file"
344327 msgstr "Postavlja metapodatke u datoteku frimvera"
345328
346329 #. TRANSLATORS: command description
347 #: libdfu/dfu-tool.c:2363
330 #: plugins/dfu/dfu-tool.c:2307
348331 msgid "Replace data in an existing firmware file"
349332 msgstr "Zamijeni podatke u postojećoj datoteci frimvera"
350333
351334 #. TRANSLATORS: command description
352 #: libdfu/dfu-tool.c:2369
335 #: plugins/dfu/dfu-tool.c:2313
353336 msgid "Create a binary patch using two files"
354337 msgstr "Stvori binarnu zakrpu koristeći dvije datoteke"
355338
356339 #. TRANSLATORS: command description
357 #: libdfu/dfu-tool.c:2375
340 #: plugins/dfu/dfu-tool.c:2319
358341 msgid "Apply a binary patch"
359342 msgstr "Primijeni binarnu zakrpu"
360343
361344 #. TRANSLATORS: command description
362 #: libdfu/dfu-tool.c:2381
345 #: plugins/dfu/dfu-tool.c:2325
363346 msgid "Dump information about a binary patch to the screen"
364347 msgstr "Ispiši informacije o binarnoj zakrpi na zaslonu"
365348
366349 #. TRANSLATORS: DFU stands for device firmware update
367 #: libdfu/dfu-tool.c:2407
350 #: plugins/dfu/dfu-tool.c:2351
368351 msgid "DFU Utility"
369352 msgstr "DFU pomagalo"
370353
371354 #. TRANSLATORS: the user didn't read the man page
372 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
373 #: src/fu-util.c:1733
355 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
356 #: src/fu-util.c:1778
374357 msgid "Failed to parse arguments"
375358 msgstr "Neuspjela obrada argumenata"
376359
377360 #. TRANSLATORS: command description
378 #: plugins/synapticsmst/synapticsmst-tool.c:408
361 #: plugins/synapticsmst/synapticsmst-tool.c:400
379362 msgid "Enumerate all Synaptics MST devices"
380363 msgstr "Pobroji sve Synaptics MST uređaje"
381364
382365 #. TRANSLATORS: command description
383 #: plugins/synapticsmst/synapticsmst-tool.c:414
366 #: plugins/synapticsmst/synapticsmst-tool.c:406
384367 msgid "Flash firmware file to MST device"
385368 msgstr "Zapiši datoteku frimvera u MST uređaj"
386369
387 #: plugins/synapticsmst/synapticsmst-tool.c:434
370 #: plugins/synapticsmst/synapticsmst-tool.c:426
388371 msgid "Synaptics Multistream Transport Utility"
389372 msgstr "Synaptics Multistream Transport pomagalo"
390373
391374 #. TRANSLATORS: this is shown when updating the firmware after the reboot
392 #: plugins/uefi/fu-plugin-uefi.c:194
375 #: plugins/uefi/fu-plugin-uefi.c:396
393376 msgid "Installing firmware update…"
394377 msgstr "Instalacija nadopune frimvera..."
395378
409392 msgstr "Prikaži mogućnosti otklanjanja greške"
410393
411394 #. TRANSLATORS: exit after we've started up, used for user profiling
412 #: src/fu-main.c:863
395 #: src/fu-main.c:960
413396 msgid "Exit after a small delay"
414397 msgstr "Izađi nakon kratke odgode"
415398
416399 #. TRANSLATORS: exit straight away, used for automatic profiling
417 #: src/fu-main.c:866
400 #: src/fu-main.c:963
418401 msgid "Exit after the engine has loaded"
419402 msgstr "Izađi nakon učitavanja pogona"
420403
421404 #. TRANSLATORS: program name
422 #: src/fu-main.c:880
405 #: src/fu-main.c:977
423406 msgid "Firmware Update Daemon"
424407 msgstr "Pozadinski program nadopune frimvera"
425408
426409 #. TRANSLATORS: program summary
427 #: src/fu-main.c:885
410 #: src/fu-main.c:982
428411 msgid "Firmware Update D-Bus Service"
429412 msgstr "Firmver nadopuna D-Bus usluge"
430413
431414 #. TRANSLATORS: daemon is inactive
432 #: src/fu-progressbar.c:51
415 #: src/fu-progressbar.c:52
433416 msgid "Idle…"
434417 msgstr "Mirovanje..."
435418
436419 #. TRANSLATORS: decompressing the firmware file
437 #: src/fu-progressbar.c:55
420 #: src/fu-progressbar.c:56
438421 msgid "Decompressing…"
439422 msgstr "Raspakiravanje..."
440423
441424 #. TRANSLATORS: parsing the firmware information
442 #: src/fu-progressbar.c:59
425 #: src/fu-progressbar.c:60
443426 msgid "Loading…"
444427 msgstr "Učitavanje..."
445428
446429 #. TRANSLATORS: restarting the device to pick up new F/W
447 #: src/fu-progressbar.c:63
430 #: src/fu-progressbar.c:64
448431 msgid "Restarting device…"
449432 msgstr "Ponovno pokretanje uređaja..."
450433
434 #. TRANSLATORS: reading from the flash chips
435 #: src/fu-progressbar.c:68
436 msgid "Reading…"
437 msgstr ""
438
451439 #. TRANSLATORS: writing to the flash chips
452 #: src/fu-progressbar.c:67
440 #: src/fu-progressbar.c:72
453441 msgid "Writing…"
454442 msgstr "Zapisivanje..."
455443
444 #. TRANSLATORS: erasing contents of the flash chips
445 #: src/fu-progressbar.c:76
446 msgid "Erasing…"
447 msgstr ""
448
456449 #. TRANSLATORS: verifying we wrote the firmware correctly
457 #: src/fu-progressbar.c:71
450 #: src/fu-progressbar.c:80
458451 msgid "Verifying…"
459452 msgstr "Provjeravanje..."
460453
461454 #. TRANSLATORS: scheduing an update to be done on the next boot
462 #: src/fu-progressbar.c:75
455 #: src/fu-progressbar.c:84
463456 msgid "Scheduling…"
464457 msgstr "Zakazivanje..."
465458
466459 #. TRANSLATORS: downloading from a remote server
467 #: src/fu-progressbar.c:79
460 #: src/fu-progressbar.c:88
468461 msgid "Downloading…"
469462 msgstr "Preuzimanje..."
470463
464 #. TRANSLATORS: waiting for user to authenticate
465 #: src/fu-progressbar.c:92
466 msgid "Authenticating…"
467 msgstr ""
468
471469 #. TRANSLATORS: currect daemon status is unknown
472 #: src/fu-progressbar.c:86
470 #: src/fu-progressbar.c:99
473471 msgid "Unknown"
474472 msgstr "Nepoznat"
475473
489487 msgid "No hardware detected with firmware update capability"
490488 msgstr "Nema otkrivenog hardvera s mogućnosti nadopune frimvera"
491489
492 #. TRANSLATOR: the plugin only supports offline
493 #: src/fu-util.c:337
494 msgid "Retrying as an offline update"
495 msgstr "Ponovni pokušaj nadopune bez pristupa internetu"
496
497490 #. TRANSLATORS: the first replacement is a display name
498491 #. * e.g. "ColorHugALS" and the second is a version number
499492 #. * e.g. "1.2.3"
500 #: src/fu-util.c:501
493 #: src/fu-util.c:474
501494 #, c-format
502495 msgid "Reinstalling %s with %s... "
503496 msgstr "Ponovna instalacija %s inačice %s... "
505498 #. TRANSLATORS: the first replacement is a display name
506499 #. * e.g. "ColorHugALS" and the second and third are
507500 #. * version numbers e.g. "1.2.3"
508 #: src/fu-util.c:508
501 #: src/fu-util.c:481
509502 #, c-format
510503 msgid "Downgrading %s from %s to %s... "
511504 msgstr "Vraćanje %s s inačice %s na inačicu %s... "
513506 #. TRANSLATORS: the first replacement is a display name
514507 #. * e.g. "ColorHugALS" and the second and third are
515508 #. * version numbers e.g. "1.2.3"
516 #: src/fu-util.c:516
509 #: src/fu-util.c:489
517510 #, c-format
518511 msgid "Updating %s from %s to %s... "
519512 msgstr "Nadopuna %s s inačice %s na inačicu %s... "
520513
521 #: src/fu-util.c:543
514 #: src/fu-util.c:516
522515 msgid "Done!"
523516 msgstr "Završeno!"
524517
525 #: src/fu-util.c:585 src/fu-util.c:985
518 #: src/fu-util.c:565 src/fu-util.c:978
526519 msgid "OK"
527520 msgstr "U redu"
528521
529522 #. TRANSLATORS: downloading new signing file
530 #: src/fu-util.c:719
523 #: src/fu-util.c:699
531524 msgid "Fetching signature"
532525 msgstr "Dohvaćanje potpisa"
533526
534527 #. TRANSLATORS: downloading new metadata file
535 #: src/fu-util.c:722
528 #: src/fu-util.c:702
536529 msgid "Fetching metadata"
537530 msgstr "Dohvaćanje metapodataka"
538531
539532 #. TRANSLATORS: downloading new firmware file
540 #: src/fu-util.c:725
533 #: src/fu-util.c:705
541534 msgid "Fetching firmware"
542535 msgstr "Dohvaćanje frimvera"
543536
544537 #. TRANSLATORS: downloading unknown file
545 #: src/fu-util.c:728
538 #: src/fu-util.c:708
546539 msgid "Fetching file"
547540 msgstr "Dohvaćanje datoteke"
548541
549542 #. TRANSLATORS: section header for release version number
550 #: src/fu-util.c:898
543 #: src/fu-util.c:888
551544 msgid "Version"
552545 msgstr "Inačica"
553546
547 #. TRANSLATORS: section header for the remote the file is coming from
548 #: src/fu-util.c:891
549 msgid "Remote"
550 msgstr ""
551
554552 #. TRANSLATORS: section header for firmware URI
555 #: src/fu-util.c:901
553 #: src/fu-util.c:894
556554 msgid "URI"
557555 msgstr "URI"
558556
559557 #. TRANSLATORS: section header for firmware description
560 #: src/fu-util.c:907
558 #: src/fu-util.c:900
561559 msgid "Description"
562560 msgstr "Opis"
563561
564562 #. TRANSLATORS: section header for firmware checksum
565 #: src/fu-util.c:915
563 #. TRANSLATORS: remote checksum
564 #: src/fu-util.c:908 src/fu-util.c:1136
566565 msgid "Checksum"
567566 msgstr "Kontrolni zbroj"
568567
569568 #. TRANSLATORS: get interactive prompt
570 #: src/fu-util.c:947
569 #: src/fu-util.c:940
571570 msgid "Choose a release:"
572571 msgstr "Odaberi izdanje:"
573572
574573 #. TRANSLATORS: first replacement is device name
575 #: src/fu-util.c:1036
574 #: src/fu-util.c:1041
576575 #, c-format
577576 msgid "%s has firmware updates:"
578577 msgstr "%s ima nadopune frimvera:"
579578
580 #: src/fu-util.c:1046
579 #: src/fu-util.c:1048
581580 msgid "GUID"
582581 msgstr "GUID"
583582
584583 #. TRANSLATORS: section header for firmware version
585 #: src/fu-util.c:1050
584 #: src/fu-util.c:1060
586585 msgid "Update Version"
587586 msgstr "Inačica nadopune"
588587
589588 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
590 #: src/fu-util.c:1054
589 #: src/fu-util.c:1064
591590 msgid "Update Remote ID"
592591 msgstr "Udaljeni ID nadopune"
593592
594593 #. TRANSLATORS: section header for firmware checksum
595 #: src/fu-util.c:1063
594 #: src/fu-util.c:1073
596595 msgid "Update Checksum"
597596 msgstr "Kontrolni zbroj nadopune"
598597
599598 #. TRANSLATORS: section header for firmware remote http://
600 #: src/fu-util.c:1067
599 #: src/fu-util.c:1077
601600 msgid "Update Location"
602601 msgstr "Lokacija nadopune"
603602
604603 #. TRANSLATORS: section header for long firmware desc
605 #: src/fu-util.c:1078
604 #: src/fu-util.c:1088
606605 msgid "Update Description"
607606 msgstr "Opis nadopune"
608607
609608 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
610 #: src/fu-util.c:1104
609 #: src/fu-util.c:1114
611610 msgid "Remote ID"
612611 msgstr "Udaljeni ID"
613612
613 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
614 #: src/fu-util.c:1118
615 msgid "Title"
616 msgstr ""
617
614618 #. TRANSLATORS: remote type, e.g. remote or local
615 #: src/fu-util.c:1108
619 #: src/fu-util.c:1122
616620 msgid "Type"
617621 msgstr "Vrsta"
618622
619 #: src/fu-util.c:1113
623 #: src/fu-util.c:1127
620624 msgid "Keyring"
621625 msgstr ""
622626
623627 #. TRANSLATORS: if the remote is enabled
624 #: src/fu-util.c:1118
628 #: src/fu-util.c:1132
625629 msgid "Enabled"
626630 msgstr "Omogućeno"
627631
628632 #. TRANSLATORS: the age of the metadata
629 #: src/fu-util.c:1145
633 #: src/fu-util.c:1163
630634 msgid "Age"
631635 msgstr "Dob"
632636
633637 #. TRANSLATORS: the numeric priority
634 #: src/fu-util.c:1152
638 #: src/fu-util.c:1170
635639 msgid "Priority"
636640 msgstr "Prioritet"
637641
638642 #. TRANSLATORS: remote filename base
639 #: src/fu-util.c:1157
643 #: src/fu-util.c:1175
640644 msgid "Username"
641645 msgstr "Korisničko ime"
642646
643647 #. TRANSLATORS: remote filename base
644 #: src/fu-util.c:1162
648 #: src/fu-util.c:1180
645649 msgid "Password"
646650 msgstr "Lozinka"
647651
648 #. TRANSLATORS: remote filename base
649 #: src/fu-util.c:1167
652 #. TRANSLATORS: filename of the local file
653 #: src/fu-util.c:1185
650654 msgid "Filename"
651655 msgstr "Naziv datoteke"
652656
653 #. TRANSLATORS: remote filename base
654 #: src/fu-util.c:1172
657 #. TRANSLATORS: filename of the local file
658 #: src/fu-util.c:1190
655659 msgid "Filename Signature"
656660 msgstr "Potpis naziva datoteke"
657661
658 #. TRANSLATORS: locatation of the local file
659 #: src/fu-util.c:1177
660 msgid "Location"
661 msgstr "Lokacija"
662
663 #. TRANSLATORS: locatation of the local file
664 #: src/fu-util.c:1182
665 msgid "Location Signature"
666 msgstr ""
667
668662 #. TRANSLATORS: remote URI
669 #: src/fu-util.c:1187
663 #: src/fu-util.c:1195
670664 msgid "Metadata URI"
671665 msgstr ""
672666
673667 #. TRANSLATORS: remote URI
674 #: src/fu-util.c:1192
668 #: src/fu-util.c:1200
675669 msgid "Metadata URI Signature"
676670 msgstr ""
677671
678672 #. TRANSLATORS: remote URI
679 #: src/fu-util.c:1197
673 #: src/fu-util.c:1205
680674 msgid "Firmware Base URI"
681675 msgstr ""
682676
683677 #. TRANSLATORS: this is when a device is hotplugged
684 #: src/fu-util.c:1224
678 #: src/fu-util.c:1232
685679 msgid "Device added:"
686680 msgstr "Uređaj dodan:"
687681
688682 #. TRANSLATORS: this is when a device is hotplugged
689 #: src/fu-util.c:1234
683 #: src/fu-util.c:1242
690684 msgid "Device removed:"
691685 msgstr "Uređaj uklonjen:"
692686
693687 #. TRANSLATORS: this is when a device has been updated
694 #: src/fu-util.c:1244
688 #: src/fu-util.c:1252
695689 msgid "Device changed:"
696690 msgstr "Uređaj promijenjen:"
697691
698692 #. TRANSLATORS: command line option
699 #: src/fu-util.c:1568
693 #: src/fu-util.c:1595
700694 msgid "Show extra debugging information"
701695 msgstr "Prikaži dodatne informacije otklanjanja grešaka"
702696
703697 #. TRANSLATORS: command line option
704 #: src/fu-util.c:1571
698 #: src/fu-util.c:1598
705699 msgid "Show client and daemon versions"
706700 msgstr "Prikaži inačicu klijenta i pozadinskog programa"
707701
708702 #. TRANSLATORS: command line option
709 #: src/fu-util.c:1574
703 #: src/fu-util.c:1601
710704 msgid "Schedule installation for next reboot when possible"
711705 msgstr "Zakaži instalaciju pri sljedećem pokretanju kada je moguće"
712706
713707 #. TRANSLATORS: command line option
714 #: src/fu-util.c:1577
708 #: src/fu-util.c:1604
715709 msgid "Allow re-installing existing firmware versions"
716710 msgstr "Dopusti ponovnu instalaciju frimvera postojeće inačice"
717711
718712 #. TRANSLATORS: command line option
719 #: src/fu-util.c:1580
713 #: src/fu-util.c:1607
720714 msgid "Allow downgrading firmware versions"
721715 msgstr "Dopusti vraćanje starije inačice frimvera"
722716
723717 #. TRANSLATORS: command line option
724 #: src/fu-util.c:1583
718 #: src/fu-util.c:1610
725719 msgid "Override plugin warning"
726720 msgstr "Zaobiđi upozorenja priključka"
727721
728722 #. TRANSLATORS: command description
729 #: src/fu-util.c:1607
723 #: src/fu-util.c:1634
730724 msgid "Get all devices that support firmware updates"
731725 msgstr "Prikaži sve uređaje koji podržavaju nadopunu frimvera"
732726
733727 #. TRANSLATORS: command description
734 #: src/fu-util.c:1613
728 #: src/fu-util.c:1640
735729 msgid "Return all the hardware IDs for the machine"
736730 msgstr "Vrati sve ID-ove hardvera za uređaj"
737731
738732 #. TRANSLATORS: command description
739 #: src/fu-util.c:1619
733 #: src/fu-util.c:1646
740734 msgid "Install prepared updates now"
741735 msgstr "Instaliraj pripremljene uređaje odmah"
742736
743737 #. TRANSLATORS: command description
744 #: src/fu-util.c:1625
738 #: src/fu-util.c:1652
745739 msgid "Install a firmware file on this hardware"
746740 msgstr "Instaliraj datoteku frimvera na ovaj uređaj"
747741
748742 #. TRANSLATORS: command description
749 #: src/fu-util.c:1631
743 #: src/fu-util.c:1658
750744 msgid "Gets details about a firmware file"
751745 msgstr "Prikaži pojedinosti datoteke frimvera"
752746
753747 #. TRANSLATORS: command description
754 #: src/fu-util.c:1637
748 #: src/fu-util.c:1664
755749 msgid "Gets the list of updates for connected hardware"
756750 msgstr "Prikaži popis nadopuna za povezani hardver"
757751
758752 #. TRANSLATORS: command description
759 #: src/fu-util.c:1643
753 #: src/fu-util.c:1670
760754 msgid "Updates all firmware to latest versions available"
761755 msgstr "Nadopuni sav frimver na najnovije dostupne inačice"
762756
763757 #. TRANSLATORS: command description
764 #: src/fu-util.c:1649
758 #: src/fu-util.c:1676
765759 msgid "Gets the cryptographic hash of the dumped firmware"
766760 msgstr "Prikaži kriptografsku jedinstvenu vrijednost opširnijih informacija frimvera"
767761
768762 #. TRANSLATORS: command description
769 #: src/fu-util.c:1655
763 #: src/fu-util.c:1682
770764 msgid "Unlocks the device for firmware access"
771765 msgstr "Otključava uređaj za pristup frimvera"
772766
773767 #. TRANSLATORS: command description
774 #: src/fu-util.c:1661
768 #: src/fu-util.c:1688
775769 msgid "Clears the results from the last update"
776770 msgstr "Uklanja rezultate posljednje nadopune"
777771
778772 #. TRANSLATORS: command description
779 #: src/fu-util.c:1667
773 #: src/fu-util.c:1694
774 msgid "Clears any updates scheduled to be updated offline"
775 msgstr ""
776
777 #. TRANSLATORS: command description
778 #: src/fu-util.c:1700
780779 msgid "Gets the results from the last update"
781780 msgstr "Prikaži rezultate posljednje nadopune"
782781
783782 #. TRANSLATORS: command description
784 #: src/fu-util.c:1673
783 #: src/fu-util.c:1706
785784 msgid "Gets the releases for a device"
786785 msgstr "Prikazuje izdanja za uređaj"
787786
788787 #. TRANSLATORS: command description
789 #: src/fu-util.c:1679
788 #: src/fu-util.c:1712
790789 msgid "Gets the configured remotes"
791790 msgstr "Prikazuje udaljena podešavanja"
792791
793792 #. TRANSLATORS: command description
794 #: src/fu-util.c:1685
793 #: src/fu-util.c:1718
795794 msgid "Downgrades the firmware on a device"
796795 msgstr "Vraća stariju inačicu frimvera na uređaju"
797796
798797 #. TRANSLATORS: command description
799 #: src/fu-util.c:1691
798 #: src/fu-util.c:1724
800799 msgid "Refresh metadata from remote server"
801800 msgstr "Osvježi metapodatke s udaljenog poslužitelja"
802801
803802 #. TRANSLATORS: command description
804 #: src/fu-util.c:1697
803 #: src/fu-util.c:1730
805804 msgid "Update the stored metadata with current ROM contents"
806805 msgstr "Nadopuni pohranjene metapodatke s trenutnim sadržajem ROM-a"
807806
808807 #. TRANSLATORS: command description
809 #: src/fu-util.c:1703
808 #: src/fu-util.c:1736
810809 msgid "Monitor the daemon for events"
811810 msgstr "Nadgledaj događaje pozadinskim programom"
812811
813812 #. TRANSLATORS: command description
814 #: src/fu-util.c:1709
813 #: src/fu-util.c:1742
815814 msgid "Build firmware using a sandbox"
816815 msgstr ""
817816
817 #. TRANSLATORS: command description
818 #: src/fu-util.c:1748
819 msgid "Dump SMBIOS data from a file"
820 msgstr ""
821
822 #. TRANSLATORS: command description
823 #: src/fu-util.c:1754
824 msgid "Modifies a given remote"
825 msgstr ""
826
818827 #. TRANSLATORS: program name
819 #: src/fu-util.c:1728
828 #: src/fu-util.c:1773
820829 msgid "Firmware Utility"
821830 msgstr "Firmver pomagalo"
+184
-175
po/hu.po less more
1010 msgstr ""
1111 "Project-Id-Version: fwupd\n"
1212 "Report-Msgid-Bugs-To: \n"
13 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
14 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
13 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
14 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1515 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1616 "Language-Team: Hungarian (http://www.transifex.com/freedesktop/fwupd/language/hu/)\n"
1717 "MIME-Version: 1.0\n"
107107 "Authentication is required to update the stored checksums for the device"
108108 msgstr "Hitelesítés szükséges az eszköz tárolt ellenőrzőösszegeinek frissítéséhez"
109109
110 #: policy/org.freedesktop.fwupd.policy.in:105
111 msgid "Modify a configured remote"
112 msgstr ""
113
114 #. TRANSLATORS: this is the PolicyKit modal dialog
115 #: policy/org.freedesktop.fwupd.policy.in:107
116 msgid ""
117 "Authentication is required to modify a configured remote used for firmware "
118 "updates"
119 msgstr ""
120
110121 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
111 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
122 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
112123 #: src/fu-util.c:112
113124 #, c-format
114125 msgid "Alias to %s"
115126 msgstr "Álnév ehhez: %s"
116127
117128 #. TRANSLATORS: error message
118 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
129 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
119130 #: src/fu-util.c:176
120131 msgid "Command not found"
121132 msgstr "A parancs nem található"
122133
123 #. TRANSLATORS: read from device to host
124 #: libdfu/dfu-tool.c:1236
125 msgid "Reading"
126 msgstr "Olvasás"
127
128 #. TRANSLATORS: write from host to device
129 #: libdfu/dfu-tool.c:1242
130 msgid "Writing"
131 msgstr "Írás"
132
133 #. TRANSLATORS: read from device to host
134 #: libdfu/dfu-tool.c:1248
135 msgid "Verifying"
136 msgstr "Ellenőrzés"
137
138 #. TRANSLATORS: read from device to host
139 #: libdfu/dfu-tool.c:1254
140 msgid "Erasing"
141 msgstr "Törlés"
142
143 #. TRANSLATORS: waiting for device
144 #: libdfu/dfu-tool.c:1260
145 msgid "Detaching"
146 msgstr "Leválasztás"
147
148 #. TRANSLATORS: waiting for device
149 #: libdfu/dfu-tool.c:1266
150 msgid "Attaching"
151 msgstr "Csatlakozás"
152
153134 #. TRANSLATORS: this is when a device is hotplugged
154 #: libdfu/dfu-tool.c:1487
135 #: plugins/dfu/dfu-tool.c:1440
155136 msgid "Added"
156137 msgstr "Hozzáadva"
157138
158139 #. TRANSLATORS: this is when a device is hotplugged
159 #: libdfu/dfu-tool.c:1498
140 #: plugins/dfu/dfu-tool.c:1451
160141 msgid "Removed"
161142 msgstr "Eltávolítva"
162143
163144 #. TRANSLATORS: this is when a device is hotplugged
164145 #. TRANSLATORS: this is when the daemon state changes
165 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
146 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
166147 msgid "Changed"
167148 msgstr "Módosítva"
168149
169150 #. TRANSLATORS: this is when a device ctrl+c's a watch
170 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
151 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
171152 msgid "Cancelled"
172153 msgstr "Megszakítva"
173154
174155 #. TRANSLATORS: Appstream ID for the hardware type
175 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
156 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
176157 msgid "ID"
177158 msgstr "Azonosító"
178159
179160 #. TRANSLATORS: interface name, e.g. "Flash"
180161 #. TRANSLATORS: device name, e.g. 'ColorHug2'
181 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
162 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
163 #: plugins/dfu/dfu-tool.c:2065
182164 msgid "Name"
183165 msgstr "Név"
184166
185167 #. TRANSLATORS: this is the encryption method used when writing
186 #: libdfu/dfu-tool.c:2043
168 #: plugins/dfu/dfu-tool.c:1985
187169 msgid "Cipher"
188170 msgstr "Titkosító"
189171
190172 #. TRANSLATORS: these are areas of memory on the chip
191 #: libdfu/dfu-tool.c:2057
173 #: plugins/dfu/dfu-tool.c:1999
192174 msgid "Region"
193175 msgstr "Régió"
194176
195177 #. TRANSLATORS: detected a DFU device
196 #: libdfu/dfu-tool.c:2092
178 #: plugins/dfu/dfu-tool.c:2033
197179 msgid "Found"
198180 msgstr "Megtalálva"
199181
200182 #. TRANSLATORS: DFU protocol version, e.g. 1.1
201 #: libdfu/dfu-tool.c:2100
183 #: plugins/dfu/dfu-tool.c:2041
202184 msgid "Protocol"
203185 msgstr "Protokoll"
204186
205187 #. TRANSLATORS: probably not run as root...
206188 #. TRANSLATORS: device has failed to report status
207189 #. TRANSLATORS: device status, e.g. "OK"
208 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
190 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
191 #: plugins/dfu/dfu-tool.c:2080
209192 msgid "Status"
210193 msgstr "Állapot"
211194
212 #: libdfu/dfu-tool.c:2112
195 #: plugins/dfu/dfu-tool.c:2054
213196 msgid "Unknown: permission denied"
214197 msgstr "Ismeretlen: hozzáférés megtagadva"
215198
216199 #. TRANSLATORS: serial number, e.g. '00012345'
217 #: libdfu/dfu-tool.c:2129
200 #: plugins/dfu/dfu-tool.c:2071
218201 msgid "Serial"
219202 msgstr "Sorozat"
220203
221204 #. TRANSLATORS: device mode, e.g. runtime or DFU
222 #: libdfu/dfu-tool.c:2134
205 #: plugins/dfu/dfu-tool.c:2076
223206 msgid "Mode"
224207 msgstr "Mód"
225208
226209 #. TRANSLATORS: device state, i.e. appIDLE
227 #: libdfu/dfu-tool.c:2142
210 #: plugins/dfu/dfu-tool.c:2084
228211 msgid "State"
229212 msgstr "Állapot"
230213
231214 #. TRANSLATORS: transfer size in bytes
232 #: libdfu/dfu-tool.c:2150
215 #: plugins/dfu/dfu-tool.c:2092
233216 msgid "Transfer Size"
234217 msgstr "Átviteli méret"
235218
236219 #. TRANSLATORS: device quirks, i.e. things that
237220 #. * it does that we have to work around
238 #: libdfu/dfu-tool.c:2158
221 #: plugins/dfu/dfu-tool.c:2100
239222 msgid "Quirks"
240223 msgstr "Kompatibilitási trükkök"
241224
242225 #. TRANSLATORS: command description
243 #: libdfu/dfu-tool.c:2237
226 #: plugins/dfu/dfu-tool.c:2181
244227 msgid "Convert firmware to DFU format"
245228 msgstr "Firmware átalakítása DFU formátumra"
246229
247230 #. TRANSLATORS: command description
248 #: libdfu/dfu-tool.c:2243
231 #: plugins/dfu/dfu-tool.c:2187
249232 msgid "Merge multiple firmware files into one"
250233 msgstr "Több firmware fájl egyesítése"
251234
252235 #. TRANSLATORS: command description
253 #: libdfu/dfu-tool.c:2249
236 #: plugins/dfu/dfu-tool.c:2193
254237 msgid "Set vendor ID on firmware file"
255238 msgstr "Gyártóazonosító beállítása a firmware fájlon"
256239
257240 #. TRANSLATORS: command description
258 #: libdfu/dfu-tool.c:2255
241 #: plugins/dfu/dfu-tool.c:2199
259242 msgid "Set product ID on firmware file"
260243 msgstr "Termékazonosító beállítása a firmware fájlon"
261244
262245 #. TRANSLATORS: command description
263 #: libdfu/dfu-tool.c:2261
246 #: plugins/dfu/dfu-tool.c:2205
264247 msgid "Set element address on firmware file"
265248 msgstr "Elem címének beállítása a firmware fájlban"
266249
267250 #. TRANSLATORS: command description
268 #: libdfu/dfu-tool.c:2267
251 #: plugins/dfu/dfu-tool.c:2211
269252 msgid "Set the firmware size for the target"
270253 msgstr "A firmware méretének beállítása a célhoz"
271254
272255 #. TRANSLATORS: command description
273 #: libdfu/dfu-tool.c:2273
256 #: plugins/dfu/dfu-tool.c:2217
274257 msgid "Set release version on firmware file"
275258 msgstr "Kiadási verzió beállítása a firmware fájlon"
276259
277260 #. TRANSLATORS: command description
278 #: libdfu/dfu-tool.c:2279
261 #: plugins/dfu/dfu-tool.c:2223
279262 msgid "Set alternative number on firmware file"
280263 msgstr "Alternatív szám beállítása a firmware fájlon"
281264
282265 #. TRANSLATORS: command description
283 #: libdfu/dfu-tool.c:2285
266 #: plugins/dfu/dfu-tool.c:2229
284267 msgid "Set alternative name on firmware file"
285268 msgstr "Alternatív név beállítása a firmware fájlon"
286269
287270 #. TRANSLATORS: command description
288 #: libdfu/dfu-tool.c:2291
271 #: plugins/dfu/dfu-tool.c:2235
289272 msgid "Attach DFU capable device back to runtime"
290273 msgstr "DFU-képes eszköz visszacsatolása a futtatókörnyezethez"
291274
292275 #. TRANSLATORS: command description
293 #: libdfu/dfu-tool.c:2297
276 #: plugins/dfu/dfu-tool.c:2241
294277 msgid "Read firmware from device into a file"
295278 msgstr "Firmware beolvasása eszközről egy fájlba"
296279
297280 #. TRANSLATORS: command description
298 #: libdfu/dfu-tool.c:2303
281 #: plugins/dfu/dfu-tool.c:2247
299282 msgid "Read firmware from one partition into a file"
300283 msgstr "Firmware beolvasása egy partícióról fájlba"
301284
302285 #. TRANSLATORS: command description
303 #: libdfu/dfu-tool.c:2309
286 #: plugins/dfu/dfu-tool.c:2253
304287 msgid "Write firmware from file into device"
305288 msgstr "Firmware írása fájlból egy eszközre"
306289
307290 #. TRANSLATORS: command description
308 #: libdfu/dfu-tool.c:2315
291 #: plugins/dfu/dfu-tool.c:2259
309292 msgid "Write firmware from file into one partition"
310293 msgstr "Firmware írása fájlból egy partícióra"
311294
312295 #. TRANSLATORS: command description
313 #: libdfu/dfu-tool.c:2321
296 #: plugins/dfu/dfu-tool.c:2265
314297 msgid "List currently attached DFU capable devices"
315298 msgstr "Jelenleg csatlakoztatott DFU-képes eszközök felsorolása"
316299
317300 #. TRANSLATORS: command description
318 #: libdfu/dfu-tool.c:2327
301 #: plugins/dfu/dfu-tool.c:2271
319302 msgid "Detach currently attached DFU capable device"
320303 msgstr "Jelenleg csatlakoztatott DFU-képes eszközök leválasztása"
321304
322305 #. TRANSLATORS: command description
323 #: libdfu/dfu-tool.c:2333
306 #: plugins/dfu/dfu-tool.c:2277
324307 msgid "Dump details about a firmware file"
325308 msgstr "Részletek kiírása egy firmware fájlról"
326309
327310 #. TRANSLATORS: command description
328 #: libdfu/dfu-tool.c:2339
311 #: plugins/dfu/dfu-tool.c:2283
329312 msgid "Watch DFU devices being hotplugged"
330313 msgstr "DFU-eszközök menet közbeni csatlakoztatásának figyelése"
331314
332315 #. TRANSLATORS: command description
333 #: libdfu/dfu-tool.c:2345
316 #: plugins/dfu/dfu-tool.c:2289
334317 msgid "Encrypt firmware data"
335318 msgstr "Firmware adatok titkosítása"
336319
337320 #. TRANSLATORS: command description
338 #: libdfu/dfu-tool.c:2351
321 #: plugins/dfu/dfu-tool.c:2295
339322 msgid "Decrypt firmware data"
340323 msgstr "Firmware adatok visszafejtése"
341324
342325 #. TRANSLATORS: command description
343 #: libdfu/dfu-tool.c:2357
326 #: plugins/dfu/dfu-tool.c:2301
344327 msgid "Sets metadata on a firmware file"
345328 msgstr "Metaadatok beállítása egy firmware fájlon"
346329
347330 #. TRANSLATORS: command description
348 #: libdfu/dfu-tool.c:2363
331 #: plugins/dfu/dfu-tool.c:2307
349332 msgid "Replace data in an existing firmware file"
350333 msgstr "Adatok cseréje egy meglévő firmware fájlban"
351334
352335 #. TRANSLATORS: command description
353 #: libdfu/dfu-tool.c:2369
336 #: plugins/dfu/dfu-tool.c:2313
354337 msgid "Create a binary patch using two files"
355338 msgstr ""
356339
357340 #. TRANSLATORS: command description
358 #: libdfu/dfu-tool.c:2375
341 #: plugins/dfu/dfu-tool.c:2319
359342 msgid "Apply a binary patch"
360343 msgstr ""
361344
362345 #. TRANSLATORS: command description
363 #: libdfu/dfu-tool.c:2381
346 #: plugins/dfu/dfu-tool.c:2325
364347 msgid "Dump information about a binary patch to the screen"
365348 msgstr ""
366349
367350 #. TRANSLATORS: DFU stands for device firmware update
368 #: libdfu/dfu-tool.c:2407
351 #: plugins/dfu/dfu-tool.c:2351
369352 msgid "DFU Utility"
370353 msgstr "DFU segédprogram"
371354
372355 #. TRANSLATORS: the user didn't read the man page
373 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
374 #: src/fu-util.c:1733
356 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
357 #: src/fu-util.c:1778
375358 msgid "Failed to parse arguments"
376359 msgstr "Nem sikerült feldolgozni az argumentumokat"
377360
378361 #. TRANSLATORS: command description
379 #: plugins/synapticsmst/synapticsmst-tool.c:408
362 #: plugins/synapticsmst/synapticsmst-tool.c:400
380363 msgid "Enumerate all Synaptics MST devices"
381364 msgstr "Az összes Synaptics MST eszköz felsorolása"
382365
383366 #. TRANSLATORS: command description
384 #: plugins/synapticsmst/synapticsmst-tool.c:414
367 #: plugins/synapticsmst/synapticsmst-tool.c:406
385368 msgid "Flash firmware file to MST device"
386369 msgstr "Firmware fájl beírása az MST eszközbe"
387370
388 #: plugins/synapticsmst/synapticsmst-tool.c:434
371 #: plugins/synapticsmst/synapticsmst-tool.c:426
389372 msgid "Synaptics Multistream Transport Utility"
390373 msgstr "Synaptics több adatfolyamos átviteli segédprogram"
391374
392375 #. TRANSLATORS: this is shown when updating the firmware after the reboot
393 #: plugins/uefi/fu-plugin-uefi.c:194
376 #: plugins/uefi/fu-plugin-uefi.c:396
394377 msgid "Installing firmware update…"
395378 msgstr "Firmware frissítés telepítése…"
396379
410393 msgstr "Hibakeresési beállítások megjelenítése"
411394
412395 #. TRANSLATORS: exit after we've started up, used for user profiling
413 #: src/fu-main.c:863
396 #: src/fu-main.c:960
414397 msgid "Exit after a small delay"
415398 msgstr "Kilépés egy kis késleltetés után"
416399
417400 #. TRANSLATORS: exit straight away, used for automatic profiling
418 #: src/fu-main.c:866
401 #: src/fu-main.c:963
419402 msgid "Exit after the engine has loaded"
420403 msgstr "Kilépés a motor betöltődése után"
421404
422405 #. TRANSLATORS: program name
423 #: src/fu-main.c:880
406 #: src/fu-main.c:977
424407 msgid "Firmware Update Daemon"
425408 msgstr "Firmware frissítő démon"
426409
427410 #. TRANSLATORS: program summary
428 #: src/fu-main.c:885
411 #: src/fu-main.c:982
429412 msgid "Firmware Update D-Bus Service"
430413 msgstr "Firmware frissítés D-Bus szolgáltatás"
431414
432415 #. TRANSLATORS: daemon is inactive
433 #: src/fu-progressbar.c:51
416 #: src/fu-progressbar.c:52
434417 msgid "Idle…"
435418 msgstr "Üresjárat…"
436419
437420 #. TRANSLATORS: decompressing the firmware file
438 #: src/fu-progressbar.c:55
421 #: src/fu-progressbar.c:56
439422 msgid "Decompressing…"
440423 msgstr "Kibontás…"
441424
442425 #. TRANSLATORS: parsing the firmware information
443 #: src/fu-progressbar.c:59
426 #: src/fu-progressbar.c:60
444427 msgid "Loading…"
445428 msgstr "Betöltés…"
446429
447430 #. TRANSLATORS: restarting the device to pick up new F/W
448 #: src/fu-progressbar.c:63
431 #: src/fu-progressbar.c:64
449432 msgid "Restarting device…"
450433 msgstr "Eszköz újraindítása…"
451434
435 #. TRANSLATORS: reading from the flash chips
436 #: src/fu-progressbar.c:68
437 msgid "Reading…"
438 msgstr ""
439
452440 #. TRANSLATORS: writing to the flash chips
453 #: src/fu-progressbar.c:67
441 #: src/fu-progressbar.c:72
454442 msgid "Writing…"
455443 msgstr "Írás…"
456444
445 #. TRANSLATORS: erasing contents of the flash chips
446 #: src/fu-progressbar.c:76
447 msgid "Erasing…"
448 msgstr ""
449
457450 #. TRANSLATORS: verifying we wrote the firmware correctly
458 #: src/fu-progressbar.c:71
451 #: src/fu-progressbar.c:80
459452 msgid "Verifying…"
460453 msgstr "Ellenőrzés…"
461454
462455 #. TRANSLATORS: scheduing an update to be done on the next boot
463 #: src/fu-progressbar.c:75
456 #: src/fu-progressbar.c:84
464457 msgid "Scheduling…"
465458 msgstr "Ütemezés…"
466459
467460 #. TRANSLATORS: downloading from a remote server
468 #: src/fu-progressbar.c:79
461 #: src/fu-progressbar.c:88
469462 msgid "Downloading…"
470463 msgstr ""
471464
465 #. TRANSLATORS: waiting for user to authenticate
466 #: src/fu-progressbar.c:92
467 msgid "Authenticating…"
468 msgstr ""
469
472470 #. TRANSLATORS: currect daemon status is unknown
473 #: src/fu-progressbar.c:86
471 #: src/fu-progressbar.c:99
474472 msgid "Unknown"
475473 msgstr "Ismeretlen"
476474
490488 msgid "No hardware detected with firmware update capability"
491489 msgstr "Nem észlelhető firmware frissítési képességgel rendelkező hardver"
492490
493 #. TRANSLATOR: the plugin only supports offline
494 #: src/fu-util.c:337
495 msgid "Retrying as an offline update"
496 msgstr "Újrapróbálás kapcsolat nélküli frissítésként"
497
498491 #. TRANSLATORS: the first replacement is a display name
499492 #. * e.g. "ColorHugALS" and the second is a version number
500493 #. * e.g. "1.2.3"
501 #: src/fu-util.c:501
494 #: src/fu-util.c:474
502495 #, c-format
503496 msgid "Reinstalling %s with %s... "
504497 msgstr "%s újratelepítése ezzel: %s…"
506499 #. TRANSLATORS: the first replacement is a display name
507500 #. * e.g. "ColorHugALS" and the second and third are
508501 #. * version numbers e.g. "1.2.3"
509 #: src/fu-util.c:508
502 #: src/fu-util.c:481
510503 #, c-format
511504 msgid "Downgrading %s from %s to %s... "
512505 msgstr "%s visszafejlesztése: %s -> %s…"
514507 #. TRANSLATORS: the first replacement is a display name
515508 #. * e.g. "ColorHugALS" and the second and third are
516509 #. * version numbers e.g. "1.2.3"
517 #: src/fu-util.c:516
510 #: src/fu-util.c:489
518511 #, c-format
519512 msgid "Updating %s from %s to %s... "
520513 msgstr "%s frissítése: %s -> %s…"
521514
522 #: src/fu-util.c:543
515 #: src/fu-util.c:516
523516 msgid "Done!"
524517 msgstr "Kész!"
525518
526 #: src/fu-util.c:585 src/fu-util.c:985
519 #: src/fu-util.c:565 src/fu-util.c:978
527520 msgid "OK"
528521 msgstr "OK"
529522
530523 #. TRANSLATORS: downloading new signing file
531 #: src/fu-util.c:719
524 #: src/fu-util.c:699
532525 msgid "Fetching signature"
533526 msgstr ""
534527
535528 #. TRANSLATORS: downloading new metadata file
536 #: src/fu-util.c:722
529 #: src/fu-util.c:702
537530 msgid "Fetching metadata"
538531 msgstr ""
539532
540533 #. TRANSLATORS: downloading new firmware file
541 #: src/fu-util.c:725
534 #: src/fu-util.c:705
542535 msgid "Fetching firmware"
543536 msgstr ""
544537
545538 #. TRANSLATORS: downloading unknown file
546 #: src/fu-util.c:728
539 #: src/fu-util.c:708
547540 msgid "Fetching file"
548541 msgstr ""
549542
550543 #. TRANSLATORS: section header for release version number
551 #: src/fu-util.c:898
544 #: src/fu-util.c:888
552545 msgid "Version"
553546 msgstr "Verzió"
554547
548 #. TRANSLATORS: section header for the remote the file is coming from
549 #: src/fu-util.c:891
550 msgid "Remote"
551 msgstr ""
552
555553 #. TRANSLATORS: section header for firmware URI
556 #: src/fu-util.c:901
554 #: src/fu-util.c:894
557555 msgid "URI"
558556 msgstr "URI"
559557
560558 #. TRANSLATORS: section header for firmware description
561 #: src/fu-util.c:907
559 #: src/fu-util.c:900
562560 msgid "Description"
563561 msgstr "Leírás"
564562
565563 #. TRANSLATORS: section header for firmware checksum
566 #: src/fu-util.c:915
564 #. TRANSLATORS: remote checksum
565 #: src/fu-util.c:908 src/fu-util.c:1136
567566 msgid "Checksum"
568567 msgstr "Ellenőrzőösszeg"
569568
570569 #. TRANSLATORS: get interactive prompt
571 #: src/fu-util.c:947
570 #: src/fu-util.c:940
572571 msgid "Choose a release:"
573572 msgstr "Válasszon kiadást:"
574573
575574 #. TRANSLATORS: first replacement is device name
576 #: src/fu-util.c:1036
575 #: src/fu-util.c:1041
577576 #, c-format
578577 msgid "%s has firmware updates:"
579578 msgstr "%s firmware frissítésekkel rendelkezik:"
580579
581 #: src/fu-util.c:1046
580 #: src/fu-util.c:1048
582581 msgid "GUID"
583582 msgstr "GUID"
584583
585584 #. TRANSLATORS: section header for firmware version
586 #: src/fu-util.c:1050
585 #: src/fu-util.c:1060
587586 msgid "Update Version"
588587 msgstr "Frissítés verziója"
589588
590589 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
591 #: src/fu-util.c:1054
590 #: src/fu-util.c:1064
592591 msgid "Update Remote ID"
593592 msgstr "Távoli azonosító frissítése"
594593
595594 #. TRANSLATORS: section header for firmware checksum
596 #: src/fu-util.c:1063
595 #: src/fu-util.c:1073
597596 msgid "Update Checksum"
598597 msgstr "Frissítés ellenőrzőösszege"
599598
600599 #. TRANSLATORS: section header for firmware remote http://
601 #: src/fu-util.c:1067
600 #: src/fu-util.c:1077
602601 msgid "Update Location"
603602 msgstr "Frissítés helye"
604603
605604 #. TRANSLATORS: section header for long firmware desc
606 #: src/fu-util.c:1078
605 #: src/fu-util.c:1088
607606 msgid "Update Description"
608607 msgstr "Frissítés leírása"
609608
610609 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
611 #: src/fu-util.c:1104
610 #: src/fu-util.c:1114
612611 msgid "Remote ID"
613612 msgstr ""
614613
614 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
615 #: src/fu-util.c:1118
616 msgid "Title"
617 msgstr ""
618
615619 #. TRANSLATORS: remote type, e.g. remote or local
616 #: src/fu-util.c:1108
620 #: src/fu-util.c:1122
617621 msgid "Type"
618622 msgstr ""
619623
620 #: src/fu-util.c:1113
624 #: src/fu-util.c:1127
621625 msgid "Keyring"
622626 msgstr ""
623627
624628 #. TRANSLATORS: if the remote is enabled
625 #: src/fu-util.c:1118
629 #: src/fu-util.c:1132
626630 msgid "Enabled"
627631 msgstr ""
628632
629633 #. TRANSLATORS: the age of the metadata
630 #: src/fu-util.c:1145
634 #: src/fu-util.c:1163
631635 msgid "Age"
632636 msgstr ""
633637
634638 #. TRANSLATORS: the numeric priority
635 #: src/fu-util.c:1152
639 #: src/fu-util.c:1170
636640 msgid "Priority"
637641 msgstr ""
638642
639643 #. TRANSLATORS: remote filename base
640 #: src/fu-util.c:1157
644 #: src/fu-util.c:1175
641645 msgid "Username"
642646 msgstr ""
643647
644648 #. TRANSLATORS: remote filename base
645 #: src/fu-util.c:1162
649 #: src/fu-util.c:1180
646650 msgid "Password"
647651 msgstr ""
648652
649 #. TRANSLATORS: remote filename base
650 #: src/fu-util.c:1167
653 #. TRANSLATORS: filename of the local file
654 #: src/fu-util.c:1185
651655 msgid "Filename"
652656 msgstr ""
653657
654 #. TRANSLATORS: remote filename base
655 #: src/fu-util.c:1172
658 #. TRANSLATORS: filename of the local file
659 #: src/fu-util.c:1190
656660 msgid "Filename Signature"
657661 msgstr ""
658662
659 #. TRANSLATORS: locatation of the local file
660 #: src/fu-util.c:1177
661 msgid "Location"
662 msgstr "Hely"
663
664 #. TRANSLATORS: locatation of the local file
665 #: src/fu-util.c:1182
666 msgid "Location Signature"
667 msgstr ""
668
669663 #. TRANSLATORS: remote URI
670 #: src/fu-util.c:1187
664 #: src/fu-util.c:1195
671665 msgid "Metadata URI"
672666 msgstr ""
673667
674668 #. TRANSLATORS: remote URI
675 #: src/fu-util.c:1192
669 #: src/fu-util.c:1200
676670 msgid "Metadata URI Signature"
677671 msgstr ""
678672
679673 #. TRANSLATORS: remote URI
680 #: src/fu-util.c:1197
674 #: src/fu-util.c:1205
681675 msgid "Firmware Base URI"
682676 msgstr ""
683677
684678 #. TRANSLATORS: this is when a device is hotplugged
685 #: src/fu-util.c:1224
679 #: src/fu-util.c:1232
686680 msgid "Device added:"
687681 msgstr "Eszköz hozzáadva:"
688682
689683 #. TRANSLATORS: this is when a device is hotplugged
690 #: src/fu-util.c:1234
684 #: src/fu-util.c:1242
691685 msgid "Device removed:"
692686 msgstr "Eszköz eltávolítva:"
693687
694688 #. TRANSLATORS: this is when a device has been updated
695 #: src/fu-util.c:1244
689 #: src/fu-util.c:1252
696690 msgid "Device changed:"
697691 msgstr "Eszköz módosítva:"
698692
699693 #. TRANSLATORS: command line option
700 #: src/fu-util.c:1568
694 #: src/fu-util.c:1595
701695 msgid "Show extra debugging information"
702696 msgstr "További hibakeresési információk megjelenítése"
703697
704698 #. TRANSLATORS: command line option
705 #: src/fu-util.c:1571
699 #: src/fu-util.c:1598
706700 msgid "Show client and daemon versions"
707701 msgstr ""
708702
709703 #. TRANSLATORS: command line option
710 #: src/fu-util.c:1574
704 #: src/fu-util.c:1601
711705 msgid "Schedule installation for next reboot when possible"
712706 msgstr "Telepítés ütemezése a következő újraindításkor, ha lehetséges"
713707
714708 #. TRANSLATORS: command line option
715 #: src/fu-util.c:1577
709 #: src/fu-util.c:1604
716710 msgid "Allow re-installing existing firmware versions"
717711 msgstr "Meglévő firmware verziók újratelepítésének engedélyezése"
718712
719713 #. TRANSLATORS: command line option
720 #: src/fu-util.c:1580
714 #: src/fu-util.c:1607
721715 msgid "Allow downgrading firmware versions"
722716 msgstr "Firmware verziók visszafejlesztésének engedélyezése"
723717
724718 #. TRANSLATORS: command line option
725 #: src/fu-util.c:1583
719 #: src/fu-util.c:1610
726720 msgid "Override plugin warning"
727721 msgstr "Bővítmény figyelmeztetés felülbírálása"
728722
729723 #. TRANSLATORS: command description
730 #: src/fu-util.c:1607
724 #: src/fu-util.c:1634
731725 msgid "Get all devices that support firmware updates"
732726 msgstr "Minden eszköz lekérése, amelyek támogatják a firmware frissítéseket"
733727
734728 #. TRANSLATORS: command description
735 #: src/fu-util.c:1613
729 #: src/fu-util.c:1640
736730 msgid "Return all the hardware IDs for the machine"
737731 msgstr "A géphez tartoó összes hardverazonosító visszaadása"
738732
739733 #. TRANSLATORS: command description
740 #: src/fu-util.c:1619
734 #: src/fu-util.c:1646
741735 msgid "Install prepared updates now"
742736 msgstr "Az előkészített frissítések telepítés most"
743737
744738 #. TRANSLATORS: command description
745 #: src/fu-util.c:1625
739 #: src/fu-util.c:1652
746740 msgid "Install a firmware file on this hardware"
747741 msgstr "Egy firmware fájl telepítése ezen a hardveren"
748742
749743 #. TRANSLATORS: command description
750 #: src/fu-util.c:1631
744 #: src/fu-util.c:1658
751745 msgid "Gets details about a firmware file"
752746 msgstr "Részleteket kér le egy firmware fájlról"
753747
754748 #. TRANSLATORS: command description
755 #: src/fu-util.c:1637
749 #: src/fu-util.c:1664
756750 msgid "Gets the list of updates for connected hardware"
757751 msgstr "A frissítések listáját kéri le a csatlakoztatott hardverhez"
758752
759753 #. TRANSLATORS: command description
760 #: src/fu-util.c:1643
754 #: src/fu-util.c:1670
761755 msgid "Updates all firmware to latest versions available"
762756 msgstr "Minden firmware-t az elérhető legfrissebb verziókra frissít"
763757
764758 #. TRANSLATORS: command description
765 #: src/fu-util.c:1649
759 #: src/fu-util.c:1676
766760 msgid "Gets the cryptographic hash of the dumped firmware"
767761 msgstr "Lekéri a kiírt firmware kriptográfiai hash-ét"
768762
769763 #. TRANSLATORS: command description
770 #: src/fu-util.c:1655
764 #: src/fu-util.c:1682
771765 msgid "Unlocks the device for firmware access"
772766 msgstr "Eszköz feloldása a firmware eléréséhez"
773767
774768 #. TRANSLATORS: command description
775 #: src/fu-util.c:1661
769 #: src/fu-util.c:1688
776770 msgid "Clears the results from the last update"
777771 msgstr "Törli a legutóbbi frissítésből származó eredményeket"
778772
779773 #. TRANSLATORS: command description
780 #: src/fu-util.c:1667
774 #: src/fu-util.c:1694
775 msgid "Clears any updates scheduled to be updated offline"
776 msgstr ""
777
778 #. TRANSLATORS: command description
779 #: src/fu-util.c:1700
781780 msgid "Gets the results from the last update"
782781 msgstr "A legutóbbi frissítésből származó eredményeket kéri le"
783782
784783 #. TRANSLATORS: command description
785 #: src/fu-util.c:1673
784 #: src/fu-util.c:1706
786785 msgid "Gets the releases for a device"
787786 msgstr "Lekéri az eszközhöz tartozó kiadásokat"
788787
789788 #. TRANSLATORS: command description
790 #: src/fu-util.c:1679
789 #: src/fu-util.c:1712
791790 msgid "Gets the configured remotes"
792791 msgstr ""
793792
794793 #. TRANSLATORS: command description
795 #: src/fu-util.c:1685
794 #: src/fu-util.c:1718
796795 msgid "Downgrades the firmware on a device"
797796 msgstr "A firmware visszafejlesztése az eszközön"
798797
799798 #. TRANSLATORS: command description
800 #: src/fu-util.c:1691
799 #: src/fu-util.c:1724
801800 msgid "Refresh metadata from remote server"
802801 msgstr "Metaadatok frissítése a távoli kiszolgálóról"
803802
804803 #. TRANSLATORS: command description
805 #: src/fu-util.c:1697
804 #: src/fu-util.c:1730
806805 msgid "Update the stored metadata with current ROM contents"
807806 msgstr "A tárolt metaadatok frissítése a jelenlegi ROM tartalmával"
808807
809808 #. TRANSLATORS: command description
810 #: src/fu-util.c:1703
809 #: src/fu-util.c:1736
811810 msgid "Monitor the daemon for events"
812811 msgstr "A démon eseményeinek figyelése"
813812
814813 #. TRANSLATORS: command description
815 #: src/fu-util.c:1709
814 #: src/fu-util.c:1742
816815 msgid "Build firmware using a sandbox"
817816 msgstr ""
818817
818 #. TRANSLATORS: command description
819 #: src/fu-util.c:1748
820 msgid "Dump SMBIOS data from a file"
821 msgstr ""
822
823 #. TRANSLATORS: command description
824 #: src/fu-util.c:1754
825 msgid "Modifies a given remote"
826 msgstr ""
827
819828 #. TRANSLATORS: program name
820 #: src/fu-util.c:1728
829 #: src/fu-util.c:1773
821830 msgid "Firmware Utility"
822831 msgstr "Firmware segédprogram"
+184
-175
po/id.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Indonesian (http://www.transifex.com/freedesktop/fwupd/language/id/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr "Otentikasi diperlukan untuk memutakhirkan checksum tersimpan bagi perangkat"
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Alias ke %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Perintah tidak ditemukan"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Membaca"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Menulis"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Memverifikasi"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Menghapus"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Melepas"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "Mencantol"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Ditambahkan"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Dihapus"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Diubah"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Dibatalkan"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Nama"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Cipher"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Wilayah"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Ditemukan"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protokol"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Status"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Tidak diketahui: izin ditolak"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Serial"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Mode"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Keadaan"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Ukuran Transfer"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Keanehan"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Konversikan firmware ke format DFU"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Gabungkan beberapa berkas firmware menjadi satu"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Atur ID vendor pada berkas firmware"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Atur ID produk pada berkas firmware"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr "Atur alamat elemen pada berkas firmware"
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr "Atur ukuran firmware bagi target"
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Atur versi rilis pada berkas firmware"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Atur nomor alternatif pada berkas firmware"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Atur nama alternatif pada berkas firmware"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Cantolkan kembali perangkat mampu-DFU ke runtime"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Baca firmware dari perangkat ke dalam suatu berkas"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Baca firmware dari satu partisi ke dalam suatu berkas"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Tulis firmware dari berkas ke dalam perangkat"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Tulis firmware dari berkas ke dalam suatu partisi"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "Tampilkan daftar perangkat mampu-DFU yang kini tercantol"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Lepas perangkat mampu-DFU yang kini tercantol"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Curahkan rincian tentang suatu berkas firmware"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Amati perangkat DFU yang sedang di-hotplug"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Enkripsikan data firmware"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Dekripsikan data firmware"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Atur metadata pada suatu berkas firmware"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr "Gantikan data dalam suatu berkas firmware yang telah ada"
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr "Buat suatu patch biner mamakai dua berkas"
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr "Terapkan sebuah patch biner"
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr "Curahkan informasi tentang suatu patch biner ke layar"
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "Utilitas DFU"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Gagal mengurai argumen"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr "Enumerasikan semua perangkat MST Synaptics"
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr "Flash-kan berkas firmware ke perangkat MST"
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr "Utilitas Transport Multistream Synaptics"
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr "Sedang memasang pembaruan firmware..."
393376
407390 msgstr "Tampilkan opsi pengawakutuan"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Keluar setelah tundaan sejenak"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Keluar setelah mesin telah dimuat"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Daemon Pemutakhiran Firmware"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Layanan D-Bus Pemutakhiran Firmware"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Menganggur..."
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "Mendekompresi..."
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "Memuat..."
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "Memulai ulang perangkat..."
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "Menulis..."
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "Verifikasi..."
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Menjadwalkan..."
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr "Sedang mengunduh..."
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Tidak diketahui"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Tidak terdeteksi perangkat keras dengan kapabilitas pemutakhiran firmware"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Mencoba lagi sebagai pemutakhiran luring"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Memasang ulang %s dengan %s..."
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Menuruntingkatkan %s dari %s ke %s..."
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Memutakhirkan %s dari %s ke %s..."
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Selesai!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "OK"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr "Sedang mengambil tanda tangan"
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr "Sedang mengambil metadata"
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr "Sedang mengambil firmware"
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr "Sedang mengambil berkas"
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Versi"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr "URI"
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Deskripsi"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "Checksum"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr "Pilih sebuah rilis:"
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "%s memiliki pemutakhiran firmware:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Mutakhirkan Versi"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr "Mutakhirkan ID Remote"
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Mutakhirkan Checksum"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Mutakhirkan Lokasi"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Mutakhirkan Keterangan"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr "ID Remote"
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr "Tipe"
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr "Difungsikan"
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr "Usia"
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr "Prioritas"
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr "Nama Pengguna"
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr "Kata Sandi"
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr "Nama Berkas"
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr "Tanda Tangan Nama Berkas"
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Lokasi"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Perangkat ditambahkan:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Perangkat dilepas:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "Perangkat diubah:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Tampilkan informasi pengawakutuan ekstra"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr "Tampilkan versi daemon dan klien"
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr "Jadwalkan instalasi untuk boot ulang selanjutnya bila mungkin"
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Izinkan pemasangan ulang versi firmware yang telah ada"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Izinkan penuruntingkatan versi firmware"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr "Timpa peringatan plugin"
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Dapatkan semua perangkat yang mendukung pemutakhiran firmware"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr "Kembalikan semua ID perangkat keras bagi mesin"
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Pasang pemutakhiran yang disiapkan sekarang"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Pasang suatu berkas firmware pada perangkat keras ini"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Dapatkan rincian tentang suatu berkas firmware"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Dapatkan daftar pemutakhiran bagi perangkat keras yang tersambung"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Mutakhirkan semua firmware ke versi terbaru yang tersedia"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Dapatkan hash kriptografis dari firmware yang dicurahkan"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "Buka kunci perangkat bagi akses firmware"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Bersihkan hasil dari pemutakhiran terakhir"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Dapatkan hasil dari pemutakhiran terakhir"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr "Dapatkan rilis-rilis bagi sebuah peranti"
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr "Dapatkan remote-remote yang terkonfigurasi"
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr "Turuntingkatkan firmware pada suatu peranti"
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Segarkan metadata dari server remote"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "Mutakhirkan metadata tersimpan dengan isi ROM saat ini"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "Pantau daemon untuk kejadian"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Utilitas Firmware"
+184
-175
po/it.po less more
88 msgstr ""
99 "Project-Id-Version: fwupd\n"
1010 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
12 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
11 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
12 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1313 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1414 "Language-Team: Italian (http://www.transifex.com/freedesktop/fwupd/language/it/)\n"
1515 "MIME-Version: 1.0\n"
105105 "Authentication is required to update the stored checksums for the device"
106106 msgstr "È richiesta l'autenticazione per aggiornare il codice di controllo del dispositivo salvato"
107107
108 #: policy/org.freedesktop.fwupd.policy.in:105
109 msgid "Modify a configured remote"
110 msgstr ""
111
112 #. TRANSLATORS: this is the PolicyKit modal dialog
113 #: policy/org.freedesktop.fwupd.policy.in:107
114 msgid ""
115 "Authentication is required to modify a configured remote used for firmware "
116 "updates"
117 msgstr ""
118
108119 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
109 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
120 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
110121 #: src/fu-util.c:112
111122 #, c-format
112123 msgid "Alias to %s"
113124 msgstr "Alias di %s"
114125
115126 #. TRANSLATORS: error message
116 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
127 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
117128 #: src/fu-util.c:176
118129 msgid "Command not found"
119130 msgstr "Comando non trovato"
120131
121 #. TRANSLATORS: read from device to host
122 #: libdfu/dfu-tool.c:1236
123 msgid "Reading"
124 msgstr "Lettura"
125
126 #. TRANSLATORS: write from host to device
127 #: libdfu/dfu-tool.c:1242
128 msgid "Writing"
129 msgstr "Scrittura"
130
131 #. TRANSLATORS: read from device to host
132 #: libdfu/dfu-tool.c:1248
133 msgid "Verifying"
134 msgstr "Verifica"
135
136 #. TRANSLATORS: read from device to host
137 #: libdfu/dfu-tool.c:1254
138 msgid "Erasing"
139 msgstr "Eliminazione"
140
141 #. TRANSLATORS: waiting for device
142 #: libdfu/dfu-tool.c:1260
143 msgid "Detaching"
144 msgstr "Rimozione"
145
146 #. TRANSLATORS: waiting for device
147 #: libdfu/dfu-tool.c:1266
148 msgid "Attaching"
149 msgstr "Collegamento"
150
151132 #. TRANSLATORS: this is when a device is hotplugged
152 #: libdfu/dfu-tool.c:1487
133 #: plugins/dfu/dfu-tool.c:1440
153134 msgid "Added"
154135 msgstr "Aggiunto"
155136
156137 #. TRANSLATORS: this is when a device is hotplugged
157 #: libdfu/dfu-tool.c:1498
138 #: plugins/dfu/dfu-tool.c:1451
158139 msgid "Removed"
159140 msgstr "Rimosso"
160141
161142 #. TRANSLATORS: this is when a device is hotplugged
162143 #. TRANSLATORS: this is when the daemon state changes
163 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
144 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
164145 msgid "Changed"
165146 msgstr "Modificato"
166147
167148 #. TRANSLATORS: this is when a device ctrl+c's a watch
168 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
149 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
169150 msgid "Cancelled"
170151 msgstr "Annullato"
171152
172153 #. TRANSLATORS: Appstream ID for the hardware type
173 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
154 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
174155 msgid "ID"
175156 msgstr "Identificativo"
176157
177158 #. TRANSLATORS: interface name, e.g. "Flash"
178159 #. TRANSLATORS: device name, e.g. 'ColorHug2'
179 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
160 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
161 #: plugins/dfu/dfu-tool.c:2065
180162 msgid "Name"
181163 msgstr "Nome"
182164
183165 #. TRANSLATORS: this is the encryption method used when writing
184 #: libdfu/dfu-tool.c:2043
166 #: plugins/dfu/dfu-tool.c:1985
185167 msgid "Cipher"
186168 msgstr "Cifratura"
187169
188170 #. TRANSLATORS: these are areas of memory on the chip
189 #: libdfu/dfu-tool.c:2057
171 #: plugins/dfu/dfu-tool.c:1999
190172 msgid "Region"
191173 msgstr "Regione"
192174
193175 #. TRANSLATORS: detected a DFU device
194 #: libdfu/dfu-tool.c:2092
176 #: plugins/dfu/dfu-tool.c:2033
195177 msgid "Found"
196178 msgstr "Trovato"
197179
198180 #. TRANSLATORS: DFU protocol version, e.g. 1.1
199 #: libdfu/dfu-tool.c:2100
181 #: plugins/dfu/dfu-tool.c:2041
200182 msgid "Protocol"
201183 msgstr "Protocollo"
202184
203185 #. TRANSLATORS: probably not run as root...
204186 #. TRANSLATORS: device has failed to report status
205187 #. TRANSLATORS: device status, e.g. "OK"
206 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
188 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
189 #: plugins/dfu/dfu-tool.c:2080
207190 msgid "Status"
208191 msgstr "Stato"
209192
210 #: libdfu/dfu-tool.c:2112
193 #: plugins/dfu/dfu-tool.c:2054
211194 msgid "Unknown: permission denied"
212195 msgstr "Sconosciuto: permesso negato"
213196
214197 #. TRANSLATORS: serial number, e.g. '00012345'
215 #: libdfu/dfu-tool.c:2129
198 #: plugins/dfu/dfu-tool.c:2071
216199 msgid "Serial"
217200 msgstr "Seriale"
218201
219202 #. TRANSLATORS: device mode, e.g. runtime or DFU
220 #: libdfu/dfu-tool.c:2134
203 #: plugins/dfu/dfu-tool.c:2076
221204 msgid "Mode"
222205 msgstr "Modalità"
223206
224207 #. TRANSLATORS: device state, i.e. appIDLE
225 #: libdfu/dfu-tool.c:2142
208 #: plugins/dfu/dfu-tool.c:2084
226209 msgid "State"
227210 msgstr "Stato"
228211
229212 #. TRANSLATORS: transfer size in bytes
230 #: libdfu/dfu-tool.c:2150
213 #: plugins/dfu/dfu-tool.c:2092
231214 msgid "Transfer Size"
232215 msgstr "Dimensione trasferimento"
233216
234217 #. TRANSLATORS: device quirks, i.e. things that
235218 #. * it does that we have to work around
236 #: libdfu/dfu-tool.c:2158
219 #: plugins/dfu/dfu-tool.c:2100
237220 msgid "Quirks"
238221 msgstr "Stranezze"
239222
240223 #. TRANSLATORS: command description
241 #: libdfu/dfu-tool.c:2237
224 #: plugins/dfu/dfu-tool.c:2181
242225 msgid "Convert firmware to DFU format"
243226 msgstr "Converte il firmware nel formato DFU"
244227
245228 #. TRANSLATORS: command description
246 #: libdfu/dfu-tool.c:2243
229 #: plugins/dfu/dfu-tool.c:2187
247230 msgid "Merge multiple firmware files into one"
248231 msgstr "Unisce più file di firmware in uno"
249232
250233 #. TRANSLATORS: command description
251 #: libdfu/dfu-tool.c:2249
234 #: plugins/dfu/dfu-tool.c:2193
252235 msgid "Set vendor ID on firmware file"
253236 msgstr "Imposta l'identificativo del produttore sul file del firmware"
254237
255238 #. TRANSLATORS: command description
256 #: libdfu/dfu-tool.c:2255
239 #: plugins/dfu/dfu-tool.c:2199
257240 msgid "Set product ID on firmware file"
258241 msgstr "Imposta l'identificativo del prodotto sul file del firmware"
259242
260243 #. TRANSLATORS: command description
261 #: libdfu/dfu-tool.c:2261
244 #: plugins/dfu/dfu-tool.c:2205
262245 msgid "Set element address on firmware file"
263246 msgstr "Imposta l'indirizzo dell'elemento sul file del firmware"
264247
265248 #. TRANSLATORS: command description
266 #: libdfu/dfu-tool.c:2267
249 #: plugins/dfu/dfu-tool.c:2211
267250 msgid "Set the firmware size for the target"
268251 msgstr "Imposta la dimensione del firmware per la destinazione"
269252
270253 #. TRANSLATORS: command description
271 #: libdfu/dfu-tool.c:2273
254 #: plugins/dfu/dfu-tool.c:2217
272255 msgid "Set release version on firmware file"
273256 msgstr "Imposta la versione di rilascio sul file del firmware"
274257
275258 #. TRANSLATORS: command description
276 #: libdfu/dfu-tool.c:2279
259 #: plugins/dfu/dfu-tool.c:2223
277260 msgid "Set alternative number on firmware file"
278261 msgstr "Imposta il numero alternativo sul file del firmware"
279262
280263 #. TRANSLATORS: command description
281 #: libdfu/dfu-tool.c:2285
264 #: plugins/dfu/dfu-tool.c:2229
282265 msgid "Set alternative name on firmware file"
283266 msgstr "Imposta il nome alternativo sul file del firmware"
284267
285268 #. TRANSLATORS: command description
286 #: libdfu/dfu-tool.c:2291
269 #: plugins/dfu/dfu-tool.c:2235
287270 msgid "Attach DFU capable device back to runtime"
288271 msgstr "Collega dispositivo DFU al runtime"
289272
290273 #. TRANSLATORS: command description
291 #: libdfu/dfu-tool.c:2297
274 #: plugins/dfu/dfu-tool.c:2241
292275 msgid "Read firmware from device into a file"
293276 msgstr "Legge il firmware dal dispositivo in un file"
294277
295278 #. TRANSLATORS: command description
296 #: libdfu/dfu-tool.c:2303
279 #: plugins/dfu/dfu-tool.c:2247
297280 msgid "Read firmware from one partition into a file"
298281 msgstr "Legge il firmware da una partizione in un file"
299282
300283 #. TRANSLATORS: command description
301 #: libdfu/dfu-tool.c:2309
284 #: plugins/dfu/dfu-tool.c:2253
302285 msgid "Write firmware from file into device"
303286 msgstr "Scrive il firmware dal file nel dispositivo"
304287
305288 #. TRANSLATORS: command description
306 #: libdfu/dfu-tool.c:2315
289 #: plugins/dfu/dfu-tool.c:2259
307290 msgid "Write firmware from file into one partition"
308291 msgstr "Scrive il firmware dal file in una partizione"
309292
310293 #. TRANSLATORS: command description
311 #: libdfu/dfu-tool.c:2321
294 #: plugins/dfu/dfu-tool.c:2265
312295 msgid "List currently attached DFU capable devices"
313296 msgstr "Elenca gli attuali dispositivi collegati con supporto DFU"
314297
315298 #. TRANSLATORS: command description
316 #: libdfu/dfu-tool.c:2327
299 #: plugins/dfu/dfu-tool.c:2271
317300 msgid "Detach currently attached DFU capable device"
318301 msgstr "Rimuove l'attuale dispositivo collegato con supporto DFU"
319302
320303 #. TRANSLATORS: command description
321 #: libdfu/dfu-tool.c:2333
304 #: plugins/dfu/dfu-tool.c:2277
322305 msgid "Dump details about a firmware file"
323306 msgstr "Scarta informazioni su un file di firmware"
324307
325308 #. TRANSLATORS: command description
326 #: libdfu/dfu-tool.c:2339
309 #: plugins/dfu/dfu-tool.c:2283
327310 msgid "Watch DFU devices being hotplugged"
328311 msgstr "Controlla i dispositivi DFU che sono collegati a caldo"
329312
330313 #. TRANSLATORS: command description
331 #: libdfu/dfu-tool.c:2345
314 #: plugins/dfu/dfu-tool.c:2289
332315 msgid "Encrypt firmware data"
333316 msgstr "Cifra i dati del firmware"
334317
335318 #. TRANSLATORS: command description
336 #: libdfu/dfu-tool.c:2351
319 #: plugins/dfu/dfu-tool.c:2295
337320 msgid "Decrypt firmware data"
338321 msgstr "Decifra i dati del firmware"
339322
340323 #. TRANSLATORS: command description
341 #: libdfu/dfu-tool.c:2357
324 #: plugins/dfu/dfu-tool.c:2301
342325 msgid "Sets metadata on a firmware file"
343326 msgstr "Imposta i metadati su un file di firmware"
344327
345328 #. TRANSLATORS: command description
346 #: libdfu/dfu-tool.c:2363
329 #: plugins/dfu/dfu-tool.c:2307
347330 msgid "Replace data in an existing firmware file"
348331 msgstr "Sostituisce i dati su un file di firmware esistente"
349332
350333 #. TRANSLATORS: command description
351 #: libdfu/dfu-tool.c:2369
334 #: plugins/dfu/dfu-tool.c:2313
352335 msgid "Create a binary patch using two files"
353336 msgstr ""
354337
355338 #. TRANSLATORS: command description
356 #: libdfu/dfu-tool.c:2375
339 #: plugins/dfu/dfu-tool.c:2319
357340 msgid "Apply a binary patch"
358341 msgstr ""
359342
360343 #. TRANSLATORS: command description
361 #: libdfu/dfu-tool.c:2381
344 #: plugins/dfu/dfu-tool.c:2325
362345 msgid "Dump information about a binary patch to the screen"
363346 msgstr ""
364347
365348 #. TRANSLATORS: DFU stands for device firmware update
366 #: libdfu/dfu-tool.c:2407
349 #: plugins/dfu/dfu-tool.c:2351
367350 msgid "DFU Utility"
368351 msgstr "Strumento DFU"
369352
370353 #. TRANSLATORS: the user didn't read the man page
371 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
372 #: src/fu-util.c:1733
354 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
355 #: src/fu-util.c:1778
373356 msgid "Failed to parse arguments"
374357 msgstr "Analisi degli argomenti non riuscita"
375358
376359 #. TRANSLATORS: command description
377 #: plugins/synapticsmst/synapticsmst-tool.c:408
360 #: plugins/synapticsmst/synapticsmst-tool.c:400
378361 msgid "Enumerate all Synaptics MST devices"
379362 msgstr "Elenca tutti i dispositivi Synaptics MST"
380363
381364 #. TRANSLATORS: command description
382 #: plugins/synapticsmst/synapticsmst-tool.c:414
365 #: plugins/synapticsmst/synapticsmst-tool.c:406
383366 msgid "Flash firmware file to MST device"
384367 msgstr "Scrive il file di firmware sul dispositivo MST"
385368
386 #: plugins/synapticsmst/synapticsmst-tool.c:434
369 #: plugins/synapticsmst/synapticsmst-tool.c:426
387370 msgid "Synaptics Multistream Transport Utility"
388371 msgstr "Strumento «Synaptics Multistream Transport»"
389372
390373 #. TRANSLATORS: this is shown when updating the firmware after the reboot
391 #: plugins/uefi/fu-plugin-uefi.c:194
374 #: plugins/uefi/fu-plugin-uefi.c:396
392375 msgid "Installing firmware update…"
393376 msgstr "Installazione aggiornamento firmware…"
394377
408391 msgstr "Mostra le opzioni di debug"
409392
410393 #. TRANSLATORS: exit after we've started up, used for user profiling
411 #: src/fu-main.c:863
394 #: src/fu-main.c:960
412395 msgid "Exit after a small delay"
413396 msgstr "Esce dopo una breve attesa"
414397
415398 #. TRANSLATORS: exit straight away, used for automatic profiling
416 #: src/fu-main.c:866
399 #: src/fu-main.c:963
417400 msgid "Exit after the engine has loaded"
418401 msgstr "Esce dopo che il motore è stato caricato"
419402
420403 #. TRANSLATORS: program name
421 #: src/fu-main.c:880
404 #: src/fu-main.c:977
422405 msgid "Firmware Update Daemon"
423406 msgstr "Demone di aggiornamento firmware"
424407
425408 #. TRANSLATORS: program summary
426 #: src/fu-main.c:885
409 #: src/fu-main.c:982
427410 msgid "Firmware Update D-Bus Service"
428411 msgstr "Servizio D-Bus di aggiornamento firmware"
429412
430413 #. TRANSLATORS: daemon is inactive
431 #: src/fu-progressbar.c:51
414 #: src/fu-progressbar.c:52
432415 msgid "Idle…"
433416 msgstr "Inattivo…"
434417
435418 #. TRANSLATORS: decompressing the firmware file
436 #: src/fu-progressbar.c:55
419 #: src/fu-progressbar.c:56
437420 msgid "Decompressing…"
438421 msgstr "Estrazione…"
439422
440423 #. TRANSLATORS: parsing the firmware information
441 #: src/fu-progressbar.c:59
424 #: src/fu-progressbar.c:60
442425 msgid "Loading…"
443426 msgstr "Caricamento…"
444427
445428 #. TRANSLATORS: restarting the device to pick up new F/W
446 #: src/fu-progressbar.c:63
429 #: src/fu-progressbar.c:64
447430 msgid "Restarting device…"
448431 msgstr "Riavvio del dispositivo…"
449432
433 #. TRANSLATORS: reading from the flash chips
434 #: src/fu-progressbar.c:68
435 msgid "Reading…"
436 msgstr ""
437
450438 #. TRANSLATORS: writing to the flash chips
451 #: src/fu-progressbar.c:67
439 #: src/fu-progressbar.c:72
452440 msgid "Writing…"
453441 msgstr "Scrittura…"
454442
443 #. TRANSLATORS: erasing contents of the flash chips
444 #: src/fu-progressbar.c:76
445 msgid "Erasing…"
446 msgstr ""
447
455448 #. TRANSLATORS: verifying we wrote the firmware correctly
456 #: src/fu-progressbar.c:71
449 #: src/fu-progressbar.c:80
457450 msgid "Verifying…"
458451 msgstr "Verifica…"
459452
460453 #. TRANSLATORS: scheduing an update to be done on the next boot
461 #: src/fu-progressbar.c:75
454 #: src/fu-progressbar.c:84
462455 msgid "Scheduling…"
463456 msgstr "Pianificazione…"
464457
465458 #. TRANSLATORS: downloading from a remote server
466 #: src/fu-progressbar.c:79
459 #: src/fu-progressbar.c:88
467460 msgid "Downloading…"
468461 msgstr ""
469462
463 #. TRANSLATORS: waiting for user to authenticate
464 #: src/fu-progressbar.c:92
465 msgid "Authenticating…"
466 msgstr ""
467
470468 #. TRANSLATORS: currect daemon status is unknown
471 #: src/fu-progressbar.c:86
469 #: src/fu-progressbar.c:99
472470 msgid "Unknown"
473471 msgstr "Sconosciuto"
474472
488486 msgid "No hardware detected with firmware update capability"
489487 msgstr "Non è stato rilevato nessun hardware con capacità di aggiornamento del firmware"
490488
491 #. TRANSLATOR: the plugin only supports offline
492 #: src/fu-util.c:337
493 msgid "Retrying as an offline update"
494 msgstr "Ritentare con un aggiornamento fuori rete"
495
496489 #. TRANSLATORS: the first replacement is a display name
497490 #. * e.g. "ColorHugALS" and the second is a version number
498491 #. * e.g. "1.2.3"
499 #: src/fu-util.c:501
492 #: src/fu-util.c:474
500493 #, c-format
501494 msgid "Reinstalling %s with %s... "
502495 msgstr "Reinstallazione di %s con %s..."
504497 #. TRANSLATORS: the first replacement is a display name
505498 #. * e.g. "ColorHugALS" and the second and third are
506499 #. * version numbers e.g. "1.2.3"
507 #: src/fu-util.c:508
500 #: src/fu-util.c:481
508501 #, c-format
509502 msgid "Downgrading %s from %s to %s... "
510503 msgstr "Arretramento di %s da %s a %s..."
512505 #. TRANSLATORS: the first replacement is a display name
513506 #. * e.g. "ColorHugALS" and the second and third are
514507 #. * version numbers e.g. "1.2.3"
515 #: src/fu-util.c:516
508 #: src/fu-util.c:489
516509 #, c-format
517510 msgid "Updating %s from %s to %s... "
518511 msgstr "Aggiornamento di %s da %s a %s..."
519512
520 #: src/fu-util.c:543
513 #: src/fu-util.c:516
521514 msgid "Done!"
522515 msgstr "Fatto."
523516
524 #: src/fu-util.c:585 src/fu-util.c:985
517 #: src/fu-util.c:565 src/fu-util.c:978
525518 msgid "OK"
526519 msgstr "Fatto"
527520
528521 #. TRANSLATORS: downloading new signing file
529 #: src/fu-util.c:719
522 #: src/fu-util.c:699
530523 msgid "Fetching signature"
531524 msgstr ""
532525
533526 #. TRANSLATORS: downloading new metadata file
534 #: src/fu-util.c:722
527 #: src/fu-util.c:702
535528 msgid "Fetching metadata"
536529 msgstr ""
537530
538531 #. TRANSLATORS: downloading new firmware file
539 #: src/fu-util.c:725
532 #: src/fu-util.c:705
540533 msgid "Fetching firmware"
541534 msgstr ""
542535
543536 #. TRANSLATORS: downloading unknown file
544 #: src/fu-util.c:728
537 #: src/fu-util.c:708
545538 msgid "Fetching file"
546539 msgstr ""
547540
548541 #. TRANSLATORS: section header for release version number
549 #: src/fu-util.c:898
542 #: src/fu-util.c:888
550543 msgid "Version"
551544 msgstr "Versione"
552545
546 #. TRANSLATORS: section header for the remote the file is coming from
547 #: src/fu-util.c:891
548 msgid "Remote"
549 msgstr ""
550
553551 #. TRANSLATORS: section header for firmware URI
554 #: src/fu-util.c:901
552 #: src/fu-util.c:894
555553 msgid "URI"
556554 msgstr "URI"
557555
558556 #. TRANSLATORS: section header for firmware description
559 #: src/fu-util.c:907
557 #: src/fu-util.c:900
560558 msgid "Description"
561559 msgstr "Descrizione"
562560
563561 #. TRANSLATORS: section header for firmware checksum
564 #: src/fu-util.c:915
562 #. TRANSLATORS: remote checksum
563 #: src/fu-util.c:908 src/fu-util.c:1136
565564 msgid "Checksum"
566565 msgstr "Codice di controllo"
567566
568567 #. TRANSLATORS: get interactive prompt
569 #: src/fu-util.c:947
568 #: src/fu-util.c:940
570569 msgid "Choose a release:"
571570 msgstr "Scegliere un rilascio:"
572571
573572 #. TRANSLATORS: first replacement is device name
574 #: src/fu-util.c:1036
573 #: src/fu-util.c:1041
575574 #, c-format
576575 msgid "%s has firmware updates:"
577576 msgstr "%s ha degli aggiornamenti del firmware:"
578577
579 #: src/fu-util.c:1046
578 #: src/fu-util.c:1048
580579 msgid "GUID"
581580 msgstr "GUID"
582581
583582 #. TRANSLATORS: section header for firmware version
584 #: src/fu-util.c:1050
583 #: src/fu-util.c:1060
585584 msgid "Update Version"
586585 msgstr "Versione aggiornamento"
587586
588587 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
589 #: src/fu-util.c:1054
588 #: src/fu-util.c:1064
590589 msgid "Update Remote ID"
591590 msgstr "ID remoto aggiornamento"
592591
593592 #. TRANSLATORS: section header for firmware checksum
594 #: src/fu-util.c:1063
593 #: src/fu-util.c:1073
595594 msgid "Update Checksum"
596595 msgstr "Codice di controllo aggiornamento"
597596
598597 #. TRANSLATORS: section header for firmware remote http://
599 #: src/fu-util.c:1067
598 #: src/fu-util.c:1077
600599 msgid "Update Location"
601600 msgstr "Posizione aggiornamento"
602601
603602 #. TRANSLATORS: section header for long firmware desc
604 #: src/fu-util.c:1078
603 #: src/fu-util.c:1088
605604 msgid "Update Description"
606605 msgstr "Descrizione aggiornamento"
607606
608607 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
609 #: src/fu-util.c:1104
608 #: src/fu-util.c:1114
610609 msgid "Remote ID"
611610 msgstr ""
612611
612 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
613 #: src/fu-util.c:1118
614 msgid "Title"
615 msgstr ""
616
613617 #. TRANSLATORS: remote type, e.g. remote or local
614 #: src/fu-util.c:1108
618 #: src/fu-util.c:1122
615619 msgid "Type"
616620 msgstr ""
617621
618 #: src/fu-util.c:1113
622 #: src/fu-util.c:1127
619623 msgid "Keyring"
620624 msgstr ""
621625
622626 #. TRANSLATORS: if the remote is enabled
623 #: src/fu-util.c:1118
627 #: src/fu-util.c:1132
624628 msgid "Enabled"
625629 msgstr ""
626630
627631 #. TRANSLATORS: the age of the metadata
628 #: src/fu-util.c:1145
632 #: src/fu-util.c:1163
629633 msgid "Age"
630634 msgstr ""
631635
632636 #. TRANSLATORS: the numeric priority
633 #: src/fu-util.c:1152
637 #: src/fu-util.c:1170
634638 msgid "Priority"
635639 msgstr ""
636640
637641 #. TRANSLATORS: remote filename base
638 #: src/fu-util.c:1157
642 #: src/fu-util.c:1175
639643 msgid "Username"
640644 msgstr ""
641645
642646 #. TRANSLATORS: remote filename base
643 #: src/fu-util.c:1162
647 #: src/fu-util.c:1180
644648 msgid "Password"
645649 msgstr ""
646650
647 #. TRANSLATORS: remote filename base
648 #: src/fu-util.c:1167
651 #. TRANSLATORS: filename of the local file
652 #: src/fu-util.c:1185
649653 msgid "Filename"
650654 msgstr ""
651655
652 #. TRANSLATORS: remote filename base
653 #: src/fu-util.c:1172
656 #. TRANSLATORS: filename of the local file
657 #: src/fu-util.c:1190
654658 msgid "Filename Signature"
655659 msgstr ""
656660
657 #. TRANSLATORS: locatation of the local file
658 #: src/fu-util.c:1177
659 msgid "Location"
660 msgstr ""
661
662 #. TRANSLATORS: locatation of the local file
663 #: src/fu-util.c:1182
664 msgid "Location Signature"
665 msgstr ""
666
667661 #. TRANSLATORS: remote URI
668 #: src/fu-util.c:1187
662 #: src/fu-util.c:1195
669663 msgid "Metadata URI"
670664 msgstr ""
671665
672666 #. TRANSLATORS: remote URI
673 #: src/fu-util.c:1192
667 #: src/fu-util.c:1200
674668 msgid "Metadata URI Signature"
675669 msgstr ""
676670
677671 #. TRANSLATORS: remote URI
678 #: src/fu-util.c:1197
672 #: src/fu-util.c:1205
679673 msgid "Firmware Base URI"
680674 msgstr ""
681675
682676 #. TRANSLATORS: this is when a device is hotplugged
683 #: src/fu-util.c:1224
677 #: src/fu-util.c:1232
684678 msgid "Device added:"
685679 msgstr "Dispositivo aggiunto:"
686680
687681 #. TRANSLATORS: this is when a device is hotplugged
688 #: src/fu-util.c:1234
682 #: src/fu-util.c:1242
689683 msgid "Device removed:"
690684 msgstr "Dispositivo rimosso:"
691685
692686 #. TRANSLATORS: this is when a device has been updated
693 #: src/fu-util.c:1244
687 #: src/fu-util.c:1252
694688 msgid "Device changed:"
695689 msgstr "Dispositivo modificato:"
696690
697691 #. TRANSLATORS: command line option
698 #: src/fu-util.c:1568
692 #: src/fu-util.c:1595
699693 msgid "Show extra debugging information"
700694 msgstr "Mostra maggiori informazioni di debug"
701695
702696 #. TRANSLATORS: command line option
703 #: src/fu-util.c:1571
697 #: src/fu-util.c:1598
704698 msgid "Show client and daemon versions"
705699 msgstr ""
706700
707701 #. TRANSLATORS: command line option
708 #: src/fu-util.c:1574
702 #: src/fu-util.c:1601
709703 msgid "Schedule installation for next reboot when possible"
710704 msgstr "Pianifica l'installazione al prossimo riavvio quando è possibile"
711705
712706 #. TRANSLATORS: command line option
713 #: src/fu-util.c:1577
707 #: src/fu-util.c:1604
714708 msgid "Allow re-installing existing firmware versions"
715709 msgstr "Consente di reinstallare versioni del firmware esistenti"
716710
717711 #. TRANSLATORS: command line option
718 #: src/fu-util.c:1580
712 #: src/fu-util.c:1607
719713 msgid "Allow downgrading firmware versions"
720714 msgstr "Consente di tornare alle precedenti versioni del firmware"
721715
722716 #. TRANSLATORS: command line option
723 #: src/fu-util.c:1583
717 #: src/fu-util.c:1610
724718 msgid "Override plugin warning"
725719 msgstr "Scavalca l'avviso sul plugin"
726720
727721 #. TRANSLATORS: command description
728 #: src/fu-util.c:1607
722 #: src/fu-util.c:1634
729723 msgid "Get all devices that support firmware updates"
730724 msgstr "Ottiene tutti i dispositivi che supportano gli aggiornamenti del firmware"
731725
732726 #. TRANSLATORS: command description
733 #: src/fu-util.c:1613
727 #: src/fu-util.c:1640
734728 msgid "Return all the hardware IDs for the machine"
735729 msgstr "Fornisce tutti gli ID hardware per un dispositivo"
736730
737731 #. TRANSLATORS: command description
738 #: src/fu-util.c:1619
732 #: src/fu-util.c:1646
739733 msgid "Install prepared updates now"
740734 msgstr "Installa ora gli aggiornamenti preparati"
741735
742736 #. TRANSLATORS: command description
743 #: src/fu-util.c:1625
737 #: src/fu-util.c:1652
744738 msgid "Install a firmware file on this hardware"
745739 msgstr "Installa un file di firmware su questo hardware"
746740
747741 #. TRANSLATORS: command description
748 #: src/fu-util.c:1631
742 #: src/fu-util.c:1658
749743 msgid "Gets details about a firmware file"
750744 msgstr "Ottiene le informazioni su un file di firmware"
751745
752746 #. TRANSLATORS: command description
753 #: src/fu-util.c:1637
747 #: src/fu-util.c:1664
754748 msgid "Gets the list of updates for connected hardware"
755749 msgstr "Ottiene l'elenco degli aggiornamenti per l'hardware connesso"
756750
757751 #. TRANSLATORS: command description
758 #: src/fu-util.c:1643
752 #: src/fu-util.c:1670
759753 msgid "Updates all firmware to latest versions available"
760754 msgstr "Aggiorna tutti i firmware all'ultima versione disponibile"
761755
762756 #. TRANSLATORS: command description
763 #: src/fu-util.c:1649
757 #: src/fu-util.c:1676
764758 msgid "Gets the cryptographic hash of the dumped firmware"
765759 msgstr "Ottiene l'hash crittografico del firmware scartato"
766760
767761 #. TRANSLATORS: command description
768 #: src/fu-util.c:1655
762 #: src/fu-util.c:1682
769763 msgid "Unlocks the device for firmware access"
770764 msgstr "Sblocca il dispositivo per accedere al firmware"
771765
772766 #. TRANSLATORS: command description
773 #: src/fu-util.c:1661
767 #: src/fu-util.c:1688
774768 msgid "Clears the results from the last update"
775769 msgstr "Pulisce i risultati dell'ultimo aggiornamento"
776770
777771 #. TRANSLATORS: command description
778 #: src/fu-util.c:1667
772 #: src/fu-util.c:1694
773 msgid "Clears any updates scheduled to be updated offline"
774 msgstr ""
775
776 #. TRANSLATORS: command description
777 #: src/fu-util.c:1700
779778 msgid "Gets the results from the last update"
780779 msgstr "Ottiene i risultati dell'ultimo aggiornamento"
781780
782781 #. TRANSLATORS: command description
783 #: src/fu-util.c:1673
782 #: src/fu-util.c:1706
784783 msgid "Gets the releases for a device"
785784 msgstr "Ottiene i rilasci di un dispositivo"
786785
787786 #. TRANSLATORS: command description
788 #: src/fu-util.c:1679
787 #: src/fu-util.c:1712
789788 msgid "Gets the configured remotes"
790789 msgstr ""
791790
792791 #. TRANSLATORS: command description
793 #: src/fu-util.c:1685
792 #: src/fu-util.c:1718
794793 msgid "Downgrades the firmware on a device"
795794 msgstr "Ripristina una vecchia versione del firmare su un dispositivo"
796795
797796 #. TRANSLATORS: command description
798 #: src/fu-util.c:1691
797 #: src/fu-util.c:1724
799798 msgid "Refresh metadata from remote server"
800799 msgstr "Ricarica i metadati dal server remoto"
801800
802801 #. TRANSLATORS: command description
803 #: src/fu-util.c:1697
802 #: src/fu-util.c:1730
804803 msgid "Update the stored metadata with current ROM contents"
805804 msgstr "Aggiorna i metadati salvati con gli attuali contenuti della ROM"
806805
807806 #. TRANSLATORS: command description
808 #: src/fu-util.c:1703
807 #: src/fu-util.c:1736
809808 msgid "Monitor the daemon for events"
810809 msgstr "Controlla il demone per gli eventi"
811810
812811 #. TRANSLATORS: command description
813 #: src/fu-util.c:1709
812 #: src/fu-util.c:1742
814813 msgid "Build firmware using a sandbox"
815814 msgstr ""
816815
816 #. TRANSLATORS: command description
817 #: src/fu-util.c:1748
818 msgid "Dump SMBIOS data from a file"
819 msgstr ""
820
821 #. TRANSLATORS: command description
822 #: src/fu-util.c:1754
823 msgid "Modifies a given remote"
824 msgstr ""
825
817826 #. TRANSLATORS: program name
818 #: src/fu-util.c:1728
827 #: src/fu-util.c:1773
819828 msgid "Firmware Utility"
820829 msgstr "Strumento gestione firmware"
5555 self.domain = "fwupd"
5656 self.font_face = "sans-serif"
5757 self.pattern = "{directory}/{language}/LC_IMAGES/fwupd-{width}-{height}.{suffix}"
58 self.fontmap = PangoCairo.font_map_get_default()
5958
6059 gettext.textdomain(self.domain)
6160 gettext.bind_textdomain_codeset(self.domain, 'UTF8')
+184
-175
po/nl.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Dutch (http://www.transifex.com/freedesktop/fwupd/language/nl/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr "Om de opgeslagen controlesommen op het apparaat bij te werken moet u toestemming verlenen"
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Alias voor %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "De opdracht kon niet worden gevonden"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Bezig met lezen"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Bezig met schrijven"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Bezig met verfiëren"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Bezig met wissen"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Bezig met afkoppelen"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "Bezig met aankoppelen"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Toegevoegd"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Verwijderd"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Gewijzigd"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Geannuleerd"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Naam"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Cipher"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Gebied"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Gevonden"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protocol"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Status"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Onbekend: toestemming is geweigerd"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Serienummer"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Modus"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Status"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Overdrachtsgrootte"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Eigenaardigheden"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Firmware converteren naar DFU-formaat"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Meerdere firmware-bestanden samenvoegen tot één bestand"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Leveranciers-ID instellen op het firmware-bestand"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Product-ID instellen op het firmware-bestand"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr "Elementadres instellen op het firmware-bestand"
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr "Firmwaregrootte instellen voor het doel"
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Uitgave-versie instellen op het firmware-bestand"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Alternatief nummer instellen op het firmware-bestand"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Alternatieve naam instellen op het firmware-bestand"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Apparaat geschikt voor DFU aankoppelen aan de runtime"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Firmware van het apparaat uitlezen naar een bestand"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Firmware van één partitie uitlezen naar een bestand"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Firmware van een bestand naar een apparaat schrijven"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Firmware van een bestand naar één partitie schrijven"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "Lijst weergeven van momenteel aangekoppelde voor DFU geschikte apparaten"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Momenteel aangekoppeld voor DFU geschikt apparaat afkoppelen"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Details over een firmware-bestand wegschrijven"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Het hotpluggen van DFU-apparaten weergeven"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Firmware-gegevens versleutelen"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Firmware-gegevens ontsleutelen"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Stelt metadata in op een firmware-bestand"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr "Gegevens vervangen in een bestaand firmwarebestand"
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "DFU-hulpmiddel"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Het doorvoeren van argumenten is mislukt"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr "Lijst weergeven van alle Synaptics MST-apparaten"
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr "Firmwarebestand flashen naar MST-apparaat"
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr "Synaptics Multistream Transport Utility"
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr "Foutopsporingsopties weergeven"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Afsluiten na een korte vertraging"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Afsluiten nadat de engine geladen is"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Firmware Update Daemon"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Firmware Update D-Bus-dienst"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Slaapt..."
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "Bezig met uitpakken..."
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "Bezig met laden..."
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "Bezig met herstarten van apparaat..."
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "Bezig met schrijven..."
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "Bezig met valideren..."
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Bezig met inplannen..."
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Onbekend"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Geen hardware aangetroffen die in staat is firmware bij te werken"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Bezig met opnieuw proberen als een offline update"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Bezig met herinstalleren van %s met %s..."
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Bezig met downgraden van %s van %s naar %s..."
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Bezig met bijwerken van %s van %s naar %s..."
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Afgerond!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "Oké"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr ""
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr ""
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "%s heeft firmware-updates:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Versie bijwerken"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Controlesom bijwerken"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Locatie bijwerken"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Omschrijving bijwerken"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr ""
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Apparaat toegevoegd:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Apparaat verwijderd:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "Apparaat gewijzigd:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Extra foutopsporingsinformatie weergeven"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr "De installatie inplannen voor de volgende herstart, indien mogelijk"
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Herinstalleren van bestaande firmware-versies toestaan"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Downgraden van oude firmware-versies toestaan"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr "Pluginwaarschuwing negeren"
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Alle apparaten verkrijgen die firmware-updates ondersteunen"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Voorbereide updates nu installeren"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Een firmware-bestand op deze hardware installeren"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Verkrijgt details over een firmware-bestand"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Verkrijgt een lijst van updates voor verbonden hardware"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Werkt alle firmware bij naar de nieuwste versies die beschikbaar zijn"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Verkrijgen cryptografische som van de weggeschreven firmware"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "Ontgrendelt het apparaat voor firmware-toegang"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Wist de resultaten van de laatste update"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Verkrijgt de resultaten van de laatste update"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Metadata verversen vanuit externe server"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "De opgeslagen metadata bijwerken met de huidige ROM-inhoud"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "De achtergrondservice controleren op gebeurtenissen"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Firmware-hulpmiddel"
+184
-175
po/oc.po less more
88 msgstr ""
99 "Project-Id-Version: fwupd\n"
1010 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
12 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
11 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
12 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1313 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1414 "Language-Team: Occitan (post 1500) (http://www.transifex.com/freedesktop/fwupd/language/oc/)\n"
1515 "MIME-Version: 1.0\n"
105105 "Authentication is required to update the stored checksums for the device"
106106 msgstr ""
107107
108 #: policy/org.freedesktop.fwupd.policy.in:105
109 msgid "Modify a configured remote"
110 msgstr ""
111
112 #. TRANSLATORS: this is the PolicyKit modal dialog
113 #: policy/org.freedesktop.fwupd.policy.in:107
114 msgid ""
115 "Authentication is required to modify a configured remote used for firmware "
116 "updates"
117 msgstr ""
118
108119 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
109 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
120 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
110121 #: src/fu-util.c:112
111122 #, c-format
112123 msgid "Alias to %s"
113124 msgstr "Aliàs de %s"
114125
115126 #. TRANSLATORS: error message
116 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
127 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
117128 #: src/fu-util.c:176
118129 msgid "Command not found"
119130 msgstr "Comanda pas trobada"
120131
121 #. TRANSLATORS: read from device to host
122 #: libdfu/dfu-tool.c:1236
123 msgid "Reading"
124 msgstr ""
125
126 #. TRANSLATORS: write from host to device
127 #: libdfu/dfu-tool.c:1242
128 msgid "Writing"
129 msgstr ""
130
131 #. TRANSLATORS: read from device to host
132 #: libdfu/dfu-tool.c:1248
133 msgid "Verifying"
134 msgstr ""
135
136 #. TRANSLATORS: read from device to host
137 #: libdfu/dfu-tool.c:1254
138 msgid "Erasing"
139 msgstr ""
140
141 #. TRANSLATORS: waiting for device
142 #: libdfu/dfu-tool.c:1260
143 msgid "Detaching"
144 msgstr "Destacament"
145
146 #. TRANSLATORS: waiting for device
147 #: libdfu/dfu-tool.c:1266
148 msgid "Attaching"
149 msgstr "Estacament"
150
151132 #. TRANSLATORS: this is when a device is hotplugged
152 #: libdfu/dfu-tool.c:1487
133 #: plugins/dfu/dfu-tool.c:1440
153134 msgid "Added"
154135 msgstr "Apondut"
155136
156137 #. TRANSLATORS: this is when a device is hotplugged
157 #: libdfu/dfu-tool.c:1498
138 #: plugins/dfu/dfu-tool.c:1451
158139 msgid "Removed"
159140 msgstr "Suprimit"
160141
161142 #. TRANSLATORS: this is when a device is hotplugged
162143 #. TRANSLATORS: this is when the daemon state changes
163 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
144 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
164145 msgid "Changed"
165146 msgstr "Cambiat"
166147
167148 #. TRANSLATORS: this is when a device ctrl+c's a watch
168 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
149 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
169150 msgid "Cancelled"
170151 msgstr "Anullat"
171152
172153 #. TRANSLATORS: Appstream ID for the hardware type
173 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
154 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
174155 msgid "ID"
175156 msgstr "ID"
176157
177158 #. TRANSLATORS: interface name, e.g. "Flash"
178159 #. TRANSLATORS: device name, e.g. 'ColorHug2'
179 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
160 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
161 #: plugins/dfu/dfu-tool.c:2065
180162 msgid "Name"
181163 msgstr "Nom"
182164
183165 #. TRANSLATORS: this is the encryption method used when writing
184 #: libdfu/dfu-tool.c:2043
166 #: plugins/dfu/dfu-tool.c:1985
185167 msgid "Cipher"
186168 msgstr "Cipher"
187169
188170 #. TRANSLATORS: these are areas of memory on the chip
189 #: libdfu/dfu-tool.c:2057
171 #: plugins/dfu/dfu-tool.c:1999
190172 msgid "Region"
191173 msgstr "Region"
192174
193175 #. TRANSLATORS: detected a DFU device
194 #: libdfu/dfu-tool.c:2092
176 #: plugins/dfu/dfu-tool.c:2033
195177 msgid "Found"
196178 msgstr "Trobat"
197179
198180 #. TRANSLATORS: DFU protocol version, e.g. 1.1
199 #: libdfu/dfu-tool.c:2100
181 #: plugins/dfu/dfu-tool.c:2041
200182 msgid "Protocol"
201183 msgstr ""
202184
203185 #. TRANSLATORS: probably not run as root...
204186 #. TRANSLATORS: device has failed to report status
205187 #. TRANSLATORS: device status, e.g. "OK"
206 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
188 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
189 #: plugins/dfu/dfu-tool.c:2080
207190 msgid "Status"
208191 msgstr "Estatut"
209192
210 #: libdfu/dfu-tool.c:2112
193 #: plugins/dfu/dfu-tool.c:2054
211194 msgid "Unknown: permission denied"
212195 msgstr ""
213196
214197 #. TRANSLATORS: serial number, e.g. '00012345'
215 #: libdfu/dfu-tool.c:2129
198 #: plugins/dfu/dfu-tool.c:2071
216199 msgid "Serial"
217200 msgstr ""
218201
219202 #. TRANSLATORS: device mode, e.g. runtime or DFU
220 #: libdfu/dfu-tool.c:2134
203 #: plugins/dfu/dfu-tool.c:2076
221204 msgid "Mode"
222205 msgstr "Mòde"
223206
224207 #. TRANSLATORS: device state, i.e. appIDLE
225 #: libdfu/dfu-tool.c:2142
208 #: plugins/dfu/dfu-tool.c:2084
226209 msgid "State"
227210 msgstr "Estat"
228211
229212 #. TRANSLATORS: transfer size in bytes
230 #: libdfu/dfu-tool.c:2150
213 #: plugins/dfu/dfu-tool.c:2092
231214 msgid "Transfer Size"
232215 msgstr ""
233216
234217 #. TRANSLATORS: device quirks, i.e. things that
235218 #. * it does that we have to work around
236 #: libdfu/dfu-tool.c:2158
219 #: plugins/dfu/dfu-tool.c:2100
237220 msgid "Quirks"
238221 msgstr "Quirks"
239222
240223 #. TRANSLATORS: command description
241 #: libdfu/dfu-tool.c:2237
224 #: plugins/dfu/dfu-tool.c:2181
242225 msgid "Convert firmware to DFU format"
243226 msgstr ""
244227
245228 #. TRANSLATORS: command description
246 #: libdfu/dfu-tool.c:2243
229 #: plugins/dfu/dfu-tool.c:2187
247230 msgid "Merge multiple firmware files into one"
248231 msgstr ""
249232
250233 #. TRANSLATORS: command description
251 #: libdfu/dfu-tool.c:2249
234 #: plugins/dfu/dfu-tool.c:2193
252235 msgid "Set vendor ID on firmware file"
253236 msgstr ""
254237
255238 #. TRANSLATORS: command description
256 #: libdfu/dfu-tool.c:2255
239 #: plugins/dfu/dfu-tool.c:2199
257240 msgid "Set product ID on firmware file"
258241 msgstr ""
259242
260243 #. TRANSLATORS: command description
261 #: libdfu/dfu-tool.c:2261
244 #: plugins/dfu/dfu-tool.c:2205
262245 msgid "Set element address on firmware file"
263246 msgstr ""
264247
265248 #. TRANSLATORS: command description
266 #: libdfu/dfu-tool.c:2267
249 #: plugins/dfu/dfu-tool.c:2211
267250 msgid "Set the firmware size for the target"
268251 msgstr ""
269252
270253 #. TRANSLATORS: command description
271 #: libdfu/dfu-tool.c:2273
254 #: plugins/dfu/dfu-tool.c:2217
272255 msgid "Set release version on firmware file"
273256 msgstr ""
274257
275258 #. TRANSLATORS: command description
276 #: libdfu/dfu-tool.c:2279
259 #: plugins/dfu/dfu-tool.c:2223
277260 msgid "Set alternative number on firmware file"
278261 msgstr ""
279262
280263 #. TRANSLATORS: command description
281 #: libdfu/dfu-tool.c:2285
264 #: plugins/dfu/dfu-tool.c:2229
282265 msgid "Set alternative name on firmware file"
283266 msgstr ""
284267
285268 #. TRANSLATORS: command description
286 #: libdfu/dfu-tool.c:2291
269 #: plugins/dfu/dfu-tool.c:2235
287270 msgid "Attach DFU capable device back to runtime"
288271 msgstr ""
289272
290273 #. TRANSLATORS: command description
291 #: libdfu/dfu-tool.c:2297
274 #: plugins/dfu/dfu-tool.c:2241
292275 msgid "Read firmware from device into a file"
293276 msgstr ""
294277
295278 #. TRANSLATORS: command description
296 #: libdfu/dfu-tool.c:2303
279 #: plugins/dfu/dfu-tool.c:2247
297280 msgid "Read firmware from one partition into a file"
298281 msgstr ""
299282
300283 #. TRANSLATORS: command description
301 #: libdfu/dfu-tool.c:2309
284 #: plugins/dfu/dfu-tool.c:2253
302285 msgid "Write firmware from file into device"
303286 msgstr ""
304287
305288 #. TRANSLATORS: command description
306 #: libdfu/dfu-tool.c:2315
289 #: plugins/dfu/dfu-tool.c:2259
307290 msgid "Write firmware from file into one partition"
308291 msgstr ""
309292
310293 #. TRANSLATORS: command description
311 #: libdfu/dfu-tool.c:2321
294 #: plugins/dfu/dfu-tool.c:2265
312295 msgid "List currently attached DFU capable devices"
313296 msgstr ""
314297
315298 #. TRANSLATORS: command description
316 #: libdfu/dfu-tool.c:2327
299 #: plugins/dfu/dfu-tool.c:2271
317300 msgid "Detach currently attached DFU capable device"
318301 msgstr ""
319302
320303 #. TRANSLATORS: command description
321 #: libdfu/dfu-tool.c:2333
304 #: plugins/dfu/dfu-tool.c:2277
322305 msgid "Dump details about a firmware file"
323306 msgstr ""
324307
325308 #. TRANSLATORS: command description
326 #: libdfu/dfu-tool.c:2339
309 #: plugins/dfu/dfu-tool.c:2283
327310 msgid "Watch DFU devices being hotplugged"
328311 msgstr ""
329312
330313 #. TRANSLATORS: command description
331 #: libdfu/dfu-tool.c:2345
314 #: plugins/dfu/dfu-tool.c:2289
332315 msgid "Encrypt firmware data"
333316 msgstr ""
334317
335318 #. TRANSLATORS: command description
336 #: libdfu/dfu-tool.c:2351
319 #: plugins/dfu/dfu-tool.c:2295
337320 msgid "Decrypt firmware data"
338321 msgstr ""
339322
340323 #. TRANSLATORS: command description
341 #: libdfu/dfu-tool.c:2357
324 #: plugins/dfu/dfu-tool.c:2301
342325 msgid "Sets metadata on a firmware file"
343326 msgstr ""
344327
345328 #. TRANSLATORS: command description
346 #: libdfu/dfu-tool.c:2363
329 #: plugins/dfu/dfu-tool.c:2307
347330 msgid "Replace data in an existing firmware file"
348331 msgstr ""
349332
350333 #. TRANSLATORS: command description
351 #: libdfu/dfu-tool.c:2369
334 #: plugins/dfu/dfu-tool.c:2313
352335 msgid "Create a binary patch using two files"
353336 msgstr ""
354337
355338 #. TRANSLATORS: command description
356 #: libdfu/dfu-tool.c:2375
339 #: plugins/dfu/dfu-tool.c:2319
357340 msgid "Apply a binary patch"
358341 msgstr ""
359342
360343 #. TRANSLATORS: command description
361 #: libdfu/dfu-tool.c:2381
344 #: plugins/dfu/dfu-tool.c:2325
362345 msgid "Dump information about a binary patch to the screen"
363346 msgstr ""
364347
365348 #. TRANSLATORS: DFU stands for device firmware update
366 #: libdfu/dfu-tool.c:2407
349 #: plugins/dfu/dfu-tool.c:2351
367350 msgid "DFU Utility"
368351 msgstr ""
369352
370353 #. TRANSLATORS: the user didn't read the man page
371 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
372 #: src/fu-util.c:1733
354 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
355 #: src/fu-util.c:1778
373356 msgid "Failed to parse arguments"
374357 msgstr "Fracàs de l'analisi dels paramètres"
375358
376359 #. TRANSLATORS: command description
377 #: plugins/synapticsmst/synapticsmst-tool.c:408
360 #: plugins/synapticsmst/synapticsmst-tool.c:400
378361 msgid "Enumerate all Synaptics MST devices"
379362 msgstr ""
380363
381364 #. TRANSLATORS: command description
382 #: plugins/synapticsmst/synapticsmst-tool.c:414
365 #: plugins/synapticsmst/synapticsmst-tool.c:406
383366 msgid "Flash firmware file to MST device"
384367 msgstr ""
385368
386 #: plugins/synapticsmst/synapticsmst-tool.c:434
369 #: plugins/synapticsmst/synapticsmst-tool.c:426
387370 msgid "Synaptics Multistream Transport Utility"
388371 msgstr ""
389372
390373 #. TRANSLATORS: this is shown when updating the firmware after the reboot
391 #: plugins/uefi/fu-plugin-uefi.c:194
374 #: plugins/uefi/fu-plugin-uefi.c:396
392375 msgid "Installing firmware update…"
393376 msgstr ""
394377
408391 msgstr "Mostrar las opcions de desbugatge"
409392
410393 #. TRANSLATORS: exit after we've started up, used for user profiling
411 #: src/fu-main.c:863
394 #: src/fu-main.c:960
412395 msgid "Exit after a small delay"
413396 msgstr "Quitar aprèp un brèu relambi"
414397
415398 #. TRANSLATORS: exit straight away, used for automatic profiling
416 #: src/fu-main.c:866
399 #: src/fu-main.c:963
417400 msgid "Exit after the engine has loaded"
418401 msgstr "Quitar aprèp lo cargament del motor"
419402
420403 #. TRANSLATORS: program name
421 #: src/fu-main.c:880
404 #: src/fu-main.c:977
422405 msgid "Firmware Update Daemon"
423406 msgstr ""
424407
425408 #. TRANSLATORS: program summary
426 #: src/fu-main.c:885
409 #: src/fu-main.c:982
427410 msgid "Firmware Update D-Bus Service"
428411 msgstr "Servici D-Bus de mesa a jorn dels micrologicials"
429412
430413 #. TRANSLATORS: daemon is inactive
431 #: src/fu-progressbar.c:51
414 #: src/fu-progressbar.c:52
432415 msgid "Idle…"
433416 msgstr ""
434417
435418 #. TRANSLATORS: decompressing the firmware file
436 #: src/fu-progressbar.c:55
419 #: src/fu-progressbar.c:56
437420 msgid "Decompressing…"
438421 msgstr ""
439422
440423 #. TRANSLATORS: parsing the firmware information
441 #: src/fu-progressbar.c:59
424 #: src/fu-progressbar.c:60
442425 msgid "Loading…"
443426 msgstr ""
444427
445428 #. TRANSLATORS: restarting the device to pick up new F/W
446 #: src/fu-progressbar.c:63
429 #: src/fu-progressbar.c:64
447430 msgid "Restarting device…"
448431 msgstr ""
449432
433 #. TRANSLATORS: reading from the flash chips
434 #: src/fu-progressbar.c:68
435 msgid "Reading…"
436 msgstr ""
437
450438 #. TRANSLATORS: writing to the flash chips
451 #: src/fu-progressbar.c:67
439 #: src/fu-progressbar.c:72
452440 msgid "Writing…"
453441 msgstr ""
454442
443 #. TRANSLATORS: erasing contents of the flash chips
444 #: src/fu-progressbar.c:76
445 msgid "Erasing…"
446 msgstr ""
447
455448 #. TRANSLATORS: verifying we wrote the firmware correctly
456 #: src/fu-progressbar.c:71
449 #: src/fu-progressbar.c:80
457450 msgid "Verifying…"
458451 msgstr ""
459452
460453 #. TRANSLATORS: scheduing an update to be done on the next boot
461 #: src/fu-progressbar.c:75
454 #: src/fu-progressbar.c:84
462455 msgid "Scheduling…"
463456 msgstr ""
464457
465458 #. TRANSLATORS: downloading from a remote server
466 #: src/fu-progressbar.c:79
459 #: src/fu-progressbar.c:88
467460 msgid "Downloading…"
468461 msgstr ""
469462
463 #. TRANSLATORS: waiting for user to authenticate
464 #: src/fu-progressbar.c:92
465 msgid "Authenticating…"
466 msgstr ""
467
470468 #. TRANSLATORS: currect daemon status is unknown
471 #: src/fu-progressbar.c:86
469 #: src/fu-progressbar.c:99
472470 msgid "Unknown"
473471 msgstr ""
474472
488486 msgid "No hardware detected with firmware update capability"
489487 msgstr "Cap de material amb de capacitats de mesa a jorn del micrologicial es pas estat detectat"
490488
491 #. TRANSLATOR: the plugin only supports offline
492 #: src/fu-util.c:337
493 msgid "Retrying as an offline update"
494 msgstr ""
495
496489 #. TRANSLATORS: the first replacement is a display name
497490 #. * e.g. "ColorHugALS" and the second is a version number
498491 #. * e.g. "1.2.3"
499 #: src/fu-util.c:501
492 #: src/fu-util.c:474
500493 #, c-format
501494 msgid "Reinstalling %s with %s... "
502495 msgstr "Reïnstallacion de %s en %s "
504497 #. TRANSLATORS: the first replacement is a display name
505498 #. * e.g. "ColorHugALS" and the second and third are
506499 #. * version numbers e.g. "1.2.3"
507 #: src/fu-util.c:508
500 #: src/fu-util.c:481
508501 #, c-format
509502 msgid "Downgrading %s from %s to %s... "
510503 msgstr "Retrogradacion de %s de %s en %s "
512505 #. TRANSLATORS: the first replacement is a display name
513506 #. * e.g. "ColorHugALS" and the second and third are
514507 #. * version numbers e.g. "1.2.3"
515 #: src/fu-util.c:516
508 #: src/fu-util.c:489
516509 #, c-format
517510 msgid "Updating %s from %s to %s... "
518511 msgstr "Mesa a jorn de %s de %s en %s "
519512
520 #: src/fu-util.c:543
513 #: src/fu-util.c:516
521514 msgid "Done!"
522515 msgstr "Acabat !"
523516
524 #: src/fu-util.c:585 src/fu-util.c:985
517 #: src/fu-util.c:565 src/fu-util.c:978
525518 msgid "OK"
526519 msgstr "D'acòrdi"
527520
528521 #. TRANSLATORS: downloading new signing file
529 #: src/fu-util.c:719
522 #: src/fu-util.c:699
530523 msgid "Fetching signature"
531524 msgstr ""
532525
533526 #. TRANSLATORS: downloading new metadata file
534 #: src/fu-util.c:722
527 #: src/fu-util.c:702
535528 msgid "Fetching metadata"
536529 msgstr ""
537530
538531 #. TRANSLATORS: downloading new firmware file
539 #: src/fu-util.c:725
532 #: src/fu-util.c:705
540533 msgid "Fetching firmware"
541534 msgstr ""
542535
543536 #. TRANSLATORS: downloading unknown file
544 #: src/fu-util.c:728
537 #: src/fu-util.c:708
545538 msgid "Fetching file"
546539 msgstr ""
547540
548541 #. TRANSLATORS: section header for release version number
549 #: src/fu-util.c:898
542 #: src/fu-util.c:888
550543 msgid "Version"
551544 msgstr "Version"
552545
546 #. TRANSLATORS: section header for the remote the file is coming from
547 #: src/fu-util.c:891
548 msgid "Remote"
549 msgstr ""
550
553551 #. TRANSLATORS: section header for firmware URI
554 #: src/fu-util.c:901
552 #: src/fu-util.c:894
555553 msgid "URI"
556554 msgstr ""
557555
558556 #. TRANSLATORS: section header for firmware description
559 #: src/fu-util.c:907
557 #: src/fu-util.c:900
560558 msgid "Description"
561559 msgstr "Descripcion"
562560
563561 #. TRANSLATORS: section header for firmware checksum
564 #: src/fu-util.c:915
562 #. TRANSLATORS: remote checksum
563 #: src/fu-util.c:908 src/fu-util.c:1136
565564 msgid "Checksum"
566565 msgstr "Soma de contraròtle"
567566
568567 #. TRANSLATORS: get interactive prompt
569 #: src/fu-util.c:947
568 #: src/fu-util.c:940
570569 msgid "Choose a release:"
571570 msgstr ""
572571
573572 #. TRANSLATORS: first replacement is device name
574 #: src/fu-util.c:1036
573 #: src/fu-util.c:1041
575574 #, c-format
576575 msgid "%s has firmware updates:"
577576 msgstr ""
578577
579 #: src/fu-util.c:1046
578 #: src/fu-util.c:1048
580579 msgid "GUID"
581580 msgstr "GUID"
582581
583582 #. TRANSLATORS: section header for firmware version
584 #: src/fu-util.c:1050
583 #: src/fu-util.c:1060
585584 msgid "Update Version"
586585 msgstr ""
587586
588587 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
589 #: src/fu-util.c:1054
588 #: src/fu-util.c:1064
590589 msgid "Update Remote ID"
591590 msgstr ""
592591
593592 #. TRANSLATORS: section header for firmware checksum
594 #: src/fu-util.c:1063
593 #: src/fu-util.c:1073
595594 msgid "Update Checksum"
596595 msgstr ""
597596
598597 #. TRANSLATORS: section header for firmware remote http://
599 #: src/fu-util.c:1067
598 #: src/fu-util.c:1077
600599 msgid "Update Location"
601600 msgstr ""
602601
603602 #. TRANSLATORS: section header for long firmware desc
604 #: src/fu-util.c:1078
603 #: src/fu-util.c:1088
605604 msgid "Update Description"
606605 msgstr ""
607606
608607 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
609 #: src/fu-util.c:1104
608 #: src/fu-util.c:1114
610609 msgid "Remote ID"
611610 msgstr ""
612611
612 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
613 #: src/fu-util.c:1118
614 msgid "Title"
615 msgstr ""
616
613617 #. TRANSLATORS: remote type, e.g. remote or local
614 #: src/fu-util.c:1108
618 #: src/fu-util.c:1122
615619 msgid "Type"
616620 msgstr ""
617621
618 #: src/fu-util.c:1113
622 #: src/fu-util.c:1127
619623 msgid "Keyring"
620624 msgstr ""
621625
622626 #. TRANSLATORS: if the remote is enabled
623 #: src/fu-util.c:1118
627 #: src/fu-util.c:1132
624628 msgid "Enabled"
625629 msgstr ""
626630
627631 #. TRANSLATORS: the age of the metadata
628 #: src/fu-util.c:1145
632 #: src/fu-util.c:1163
629633 msgid "Age"
630634 msgstr ""
631635
632636 #. TRANSLATORS: the numeric priority
633 #: src/fu-util.c:1152
637 #: src/fu-util.c:1170
634638 msgid "Priority"
635639 msgstr ""
636640
637641 #. TRANSLATORS: remote filename base
638 #: src/fu-util.c:1157
642 #: src/fu-util.c:1175
639643 msgid "Username"
640644 msgstr ""
641645
642646 #. TRANSLATORS: remote filename base
643 #: src/fu-util.c:1162
647 #: src/fu-util.c:1180
644648 msgid "Password"
645649 msgstr ""
646650
647 #. TRANSLATORS: remote filename base
648 #: src/fu-util.c:1167
651 #. TRANSLATORS: filename of the local file
652 #: src/fu-util.c:1185
649653 msgid "Filename"
650654 msgstr ""
651655
652 #. TRANSLATORS: remote filename base
653 #: src/fu-util.c:1172
656 #. TRANSLATORS: filename of the local file
657 #: src/fu-util.c:1190
654658 msgid "Filename Signature"
655659 msgstr ""
656660
657 #. TRANSLATORS: locatation of the local file
658 #: src/fu-util.c:1177
659 msgid "Location"
660 msgstr "Emplaçament"
661
662 #. TRANSLATORS: locatation of the local file
663 #: src/fu-util.c:1182
664 msgid "Location Signature"
665 msgstr ""
666
667661 #. TRANSLATORS: remote URI
668 #: src/fu-util.c:1187
662 #: src/fu-util.c:1195
669663 msgid "Metadata URI"
670664 msgstr ""
671665
672666 #. TRANSLATORS: remote URI
673 #: src/fu-util.c:1192
667 #: src/fu-util.c:1200
674668 msgid "Metadata URI Signature"
675669 msgstr ""
676670
677671 #. TRANSLATORS: remote URI
678 #: src/fu-util.c:1197
672 #: src/fu-util.c:1205
679673 msgid "Firmware Base URI"
680674 msgstr ""
681675
682676 #. TRANSLATORS: this is when a device is hotplugged
683 #: src/fu-util.c:1224
677 #: src/fu-util.c:1232
684678 msgid "Device added:"
685679 msgstr ""
686680
687681 #. TRANSLATORS: this is when a device is hotplugged
688 #: src/fu-util.c:1234
682 #: src/fu-util.c:1242
689683 msgid "Device removed:"
690684 msgstr ""
691685
692686 #. TRANSLATORS: this is when a device has been updated
693 #: src/fu-util.c:1244
687 #: src/fu-util.c:1252
694688 msgid "Device changed:"
695689 msgstr ""
696690
697691 #. TRANSLATORS: command line option
698 #: src/fu-util.c:1568
692 #: src/fu-util.c:1595
699693 msgid "Show extra debugging information"
700694 msgstr "Mòstra d'informacions de desbugatge complementàrias"
701695
702696 #. TRANSLATORS: command line option
703 #: src/fu-util.c:1571
697 #: src/fu-util.c:1598
704698 msgid "Show client and daemon versions"
705699 msgstr ""
706700
707701 #. TRANSLATORS: command line option
708 #: src/fu-util.c:1574
702 #: src/fu-util.c:1601
709703 msgid "Schedule installation for next reboot when possible"
710704 msgstr ""
711705
712706 #. TRANSLATORS: command line option
713 #: src/fu-util.c:1577
707 #: src/fu-util.c:1604
714708 msgid "Allow re-installing existing firmware versions"
715709 msgstr ""
716710
717711 #. TRANSLATORS: command line option
718 #: src/fu-util.c:1580
712 #: src/fu-util.c:1607
719713 msgid "Allow downgrading firmware versions"
720714 msgstr ""
721715
722716 #. TRANSLATORS: command line option
723 #: src/fu-util.c:1583
717 #: src/fu-util.c:1610
724718 msgid "Override plugin warning"
725719 msgstr ""
726720
727721 #. TRANSLATORS: command description
728 #: src/fu-util.c:1607
722 #: src/fu-util.c:1634
729723 msgid "Get all devices that support firmware updates"
730724 msgstr "Obténer la lista dels periferics que supòrtan las mesas a jorn de micrologicial"
731725
732726 #. TRANSLATORS: command description
733 #: src/fu-util.c:1613
727 #: src/fu-util.c:1640
734728 msgid "Return all the hardware IDs for the machine"
735729 msgstr ""
736730
737731 #. TRANSLATORS: command description
738 #: src/fu-util.c:1619
732 #: src/fu-util.c:1646
739733 msgid "Install prepared updates now"
740734 msgstr "Installar immediatament las mesas a jorn preparadas"
741735
742736 #. TRANSLATORS: command description
743 #: src/fu-util.c:1625
737 #: src/fu-util.c:1652
744738 msgid "Install a firmware file on this hardware"
745739 msgstr "Installar un fichièr de micrologicial sus aqueste material"
746740
747741 #. TRANSLATORS: command description
748 #: src/fu-util.c:1631
742 #: src/fu-util.c:1658
749743 msgid "Gets details about a firmware file"
750744 msgstr "Obténer los detalhs d'un fichièr de micrologicial"
751745
752746 #. TRANSLATORS: command description
753 #: src/fu-util.c:1637
747 #: src/fu-util.c:1664
754748 msgid "Gets the list of updates for connected hardware"
755749 msgstr ""
756750
757751 #. TRANSLATORS: command description
758 #: src/fu-util.c:1643
752 #: src/fu-util.c:1670
759753 msgid "Updates all firmware to latest versions available"
760754 msgstr ""
761755
762756 #. TRANSLATORS: command description
763 #: src/fu-util.c:1649
757 #: src/fu-util.c:1676
764758 msgid "Gets the cryptographic hash of the dumped firmware"
765759 msgstr ""
766760
767761 #. TRANSLATORS: command description
768 #: src/fu-util.c:1655
762 #: src/fu-util.c:1682
769763 msgid "Unlocks the device for firmware access"
770764 msgstr ""
771765
772766 #. TRANSLATORS: command description
773 #: src/fu-util.c:1661
767 #: src/fu-util.c:1688
774768 msgid "Clears the results from the last update"
775769 msgstr ""
776770
777771 #. TRANSLATORS: command description
778 #: src/fu-util.c:1667
772 #: src/fu-util.c:1694
773 msgid "Clears any updates scheduled to be updated offline"
774 msgstr ""
775
776 #. TRANSLATORS: command description
777 #: src/fu-util.c:1700
779778 msgid "Gets the results from the last update"
780779 msgstr ""
781780
782781 #. TRANSLATORS: command description
783 #: src/fu-util.c:1673
782 #: src/fu-util.c:1706
784783 msgid "Gets the releases for a device"
785784 msgstr ""
786785
787786 #. TRANSLATORS: command description
788 #: src/fu-util.c:1679
787 #: src/fu-util.c:1712
789788 msgid "Gets the configured remotes"
790789 msgstr ""
791790
792791 #. TRANSLATORS: command description
793 #: src/fu-util.c:1685
792 #: src/fu-util.c:1718
794793 msgid "Downgrades the firmware on a device"
795794 msgstr ""
796795
797796 #. TRANSLATORS: command description
798 #: src/fu-util.c:1691
797 #: src/fu-util.c:1724
799798 msgid "Refresh metadata from remote server"
800799 msgstr ""
801800
802801 #. TRANSLATORS: command description
803 #: src/fu-util.c:1697
802 #: src/fu-util.c:1730
804803 msgid "Update the stored metadata with current ROM contents"
805804 msgstr ""
806805
807806 #. TRANSLATORS: command description
808 #: src/fu-util.c:1703
807 #: src/fu-util.c:1736
809808 msgid "Monitor the daemon for events"
810809 msgstr ""
811810
812811 #. TRANSLATORS: command description
813 #: src/fu-util.c:1709
812 #: src/fu-util.c:1742
814813 msgid "Build firmware using a sandbox"
815814 msgstr ""
816815
816 #. TRANSLATORS: command description
817 #: src/fu-util.c:1748
818 msgid "Dump SMBIOS data from a file"
819 msgstr ""
820
821 #. TRANSLATORS: command description
822 #: src/fu-util.c:1754
823 msgid "Modifies a given remote"
824 msgstr ""
825
817826 #. TRANSLATORS: program name
818 #: src/fu-util.c:1728
827 #: src/fu-util.c:1773
819828 msgid "Firmware Utility"
820829 msgstr ""
+188
-179
po/pl.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Polish (http://www.transifex.com/freedesktop/fwupd/language/pl/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr "Wymagane jest uwierzytelnienie, aby zaktualizować przechowywane sumy kontrolne dla urządzenia"
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Alias do „%s”"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Nie odnaleziono polecenia"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Odczytywanie"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Zapisywanie"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Sprawdzanie poprawności"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Usuwanie"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Odłączanie"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "Podłączanie"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Dodano"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Usunięto"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Zmieniono"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Anulowano"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "Identyfikator"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Nazwa"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Szyfr"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Region"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Odnaleziono"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protokół"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Stan"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Nieznane: brak uprawnień"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Numer seryjny"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Tryb"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Stan"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Rozmiar przesyłania"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Poprawki"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Konwertuje oprogramowanie sprzętowe do formatu DFU"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Łączy wiele plików oprogramowania sprzętowego w jeden plik"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Ustawia identyfikator producenta pliku oprogramowania sprzętowego"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Ustawia identyfikator produktu pliku oprogramowania sprzętowego"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr "Ustawia adres elementu pliku oprogramowania sprzętowego"
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr "Ustawia rozmiar oprogramowania sprzętowego dla celu"
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Ustawia wersję wydania pliku oprogramowania sprzętowego"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Ustawia alternatywny numer pliku oprogramowania sprzętowego"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Ustawia alternatywną nazwę pliku oprogramowania sprzętowego"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Podłącza urządzenie DFU z powrotem do uruchamiania systemu"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Odczytuje oprogramowanie sprzętowe z urządzenia do pliku"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Odczytuje oprogramowanie sprzętowe z jednej partycji do pliku"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Zapisuje oprogramowanie sprzętowe z pliku na urządzenie"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Zapisuje oprogramowanie sprzętowe z pliku na jedną partycję"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "Wyświetla listę obecnie podłączonych urządzeń DFU"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Odłącza obecnie podłączone urządzenie DFU"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Zrzuca informacje o pliku oprogramowania sprzętowego"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Obserwuje podłączanie urządzeń DFU w czasie działania"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Szyfruje dane oprogramowania sprzętowego"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Odszyfrowuje dane oprogramowania sprzętowego"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Ustawia metadane pliku oprogramowania sprzętowego"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr "Zastępuje dane w istniejącym pliku oprogramowania sprzętowego"
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr "Tworzy binarną łatę z dwóch plików"
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr "Zastosowuje binarną łatę"
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr "Zrzuca informacje o binarnej łacie na ekran"
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "Narzędzie DFU"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Przetworzenie parametrów się nie powiodło"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr "Wylicza wszystkie urządzenia MST firmy Synaptics"
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr "Zapisuje oprogramowanie sprzętowe w urządzeniu MST"
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr "Narzędzie wielostrumieniowego przesyłania Synaptics"
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr "Instalowanie aktualizacji oprogramowania sprzętowego…"
393376
407390 msgstr "Wyświetla opcje debugowania"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Kończy działanie po małym opóźnieniu"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Kończy działanie po wczytaniu mechanizmu"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Usługa aktualizacji oprogramowania sprzętowego"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Usługa D-Bus aktualizacji oprogramowania sprzętowego"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Bezczynne…"
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "Dekompresowanie…"
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "Wczytywanie…"
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "Ponowne uruchamianie urządzenia…"
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "Zapisywanie…"
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "Sprawdzanie poprawności…"
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Planowanie…"
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr "Pobieranie…"
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Nieznane"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Nie wykryto sprzętu z możliwością aktualizacji jego oprogramowania"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Próbowanie ponownie jako aktualizacja w trybie offline"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Ponowne instalowanie %s za pomocą %s… "
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Instalowanie poprzedniej wersji %s z %s do %s… "
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Aktualizowanie %s z wersji %s do %s… "
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Gotowe."
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "OK"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr "Pobieranie podpisu"
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr "Pobieranie metadanych"
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr "Pobieranie oprogramowania sprzętowego"
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr "Pobieranie pliku"
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Wersja"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr "Adres URI"
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Opis"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "Suma kontrolna"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr "Wybór wydania:"
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "Dostępne są aktualizacje oprogramowania sprzętowego dla urządzenia %s:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Wersja aktualizacji"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr "Identyfikator repozytorium aktualizacji"
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Suma kontrolna aktualizacji"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Położenie aktualizacji"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Opis aktualizacji"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr "Identyfikator repozytorium"
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr "Typ"
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619 msgstr ""
623 msgstr "Baza kluczy"
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr "Włączone"
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr "Wiek"
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr "Priorytet"
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr "Nazwa użytkownika"
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr "Hasło"
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr "Nazwa pliku"
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr "Podpis nazwy pliku"
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Położenie"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669 msgstr ""
663 msgstr "Adres URI metadanych"
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674 msgstr ""
668 msgstr "Podpis adresu URI metadanych"
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679 msgstr ""
673 msgstr "Podstawowy adres URI oprogramowania sprzętowego"
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Dodano urządzenie:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Usunięto urządzenie:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "Zmieniono urządzenie:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Wyświetla dodatkowe informacje o debugowaniu"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr "Wyświetla wersje klienta i usługi"
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr "Planuje instalację podczas następnego ponownego uruchomienia"
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Umożliwia ponowne instalowanie istniejących wersji oprogramowania sprzętowego"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Umożliwia instalowanie poprzednich wersji oprogramowania sprzętowego"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr "Zastępuje ostrzeżenie wtyczki"
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Uzyskuje wszystkie urządzenia obsługujące aktualizacje oprogramowania sprzętowego"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr "Zwraca wszystkie identyfikatory sprzętu dla komputera"
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Instaluje przygotowaną aktualizację teraz"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Instaluje plik oprogramowania sprzętowego na tym sprzęcie"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Uzyskuje informacje o pliku oprogramowania sprzętowego"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Uzyskuje listę aktualizacji dla podłączonego sprzętu"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Aktualizuje całe oprogramowanie sprzętowe do najnowszych dostępnych wersji"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Uzyskuje kryptograficzną sumę kontrolną zrzuconego oprogramowania sprzętowego"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "Odblokowuje urządzenie"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Czyści wyniki z ostatniej aktualizacji"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Uzyskuje wyniki z ostatniej aktualizacji"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr "Uzyskuje wydania dla urządzenia"
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr "Uzyskuje skonfigurowane repozytoria"
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr "Instaluje poprzednią wersję oprogramowania sprzętowego urządzenia"
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Odświeża metadane ze zdalnego serwera"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "Aktualizuje przechowywane metadane bieżącą zawartością pamięci ROM"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "Monitoruje zdarzenia usługi"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
813 msgstr "Buduje oprogramowanie sprzętowe za pomocą piaskownicy"
814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
814823 msgstr ""
815824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Narzędzie oprogramowania sprzętowego"
44 # Translators:
55 # Derek W. Stavis <dekestavis@gmail.com>, 2015
66 # Derek W. Stavis <dekestavis@gmail.com>, 2016
7 # Derek W. Stavis <dekestavis@gmail.com>, 2015-2016
8 # Rafael Fontenelle <rafaelff@gnome.org>, 2017
79 # Rafael Fontenelle <rffontenelle@gmail.com>, 2015-2017
810 msgid ""
911 msgstr ""
1012 "Project-Id-Version: fwupd\n"
1113 "Report-Msgid-Bugs-To: \n"
12 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
13 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
14 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
15 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1416 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1517 "Language-Team: Portuguese (Brazil) (http://www.transifex.com/freedesktop/fwupd/language/pt_BR/)\n"
1618 "MIME-Version: 1.0\n"
2123
2224 #: data/org.freedesktop.fwupd.metainfo.xml:7
2325 msgid "fwupd"
24 msgstr ""
26 msgstr "fwupd"
2527
2628 #: data/org.freedesktop.fwupd.metainfo.xml:8
2729 msgid "Update device firmware on Linux"
28 msgstr ""
30 msgstr "Atualize firmware de dispositivos no Linux"
2931
3032 #: data/org.freedesktop.fwupd.metainfo.xml:10
3133 msgid ""
3335 "reliable. You can either use a GUI software manager like GNOME Software to "
3436 "view and apply updates, the command-line tool or the D-Bus interface "
3537 "directly."
36 msgstr ""
38 msgstr "Esse projeto visa tornar a atualização de firmware no Linux automática, segura e confiável. você pode usar um gerenciador de software GUI, como o GNOME Software, para ver e aplicar atualizações, a ferramenta de linha de comando ou a interface D-Bus diretamente."
3739
3840 #: data/org.freedesktop.fwupd.metainfo.xml:16
3941 msgid ""
4042 "The fwupd process is a simple daemon to allow session software to update "
4143 "device firmware on your local machine. It is designed for desktops, but this"
4244 " project is also usable on phones, tablets and on headless servers."
43 msgstr ""
45 msgstr "O fwupd processa é um daemon simples para permitir que software sessão atualizem firmware de dispositivo em seu computador local. É projetado para computadores de mesa, mas esse projeto também é usável em telefones, tablets e em servidores \"headless\" (sem monitor, teclado e mouse)."
4446
4547 #: policy/org.freedesktop.fwupd.policy.in:17
4648 msgid "Install signed system firmware"
104106 #: policy/org.freedesktop.fwupd.policy.in:96
105107 msgid ""
106108 "Authentication is required to update the stored checksums for the device"
107 msgstr "É requerida autenticação para atualizar as somas de verificação armazenads para o dispositivo"
109 msgstr "É requerida autenticação para atualizar as somas de verificação armazenadas para o dispositivo"
110
111 #: policy/org.freedesktop.fwupd.policy.in:105
112 msgid "Modify a configured remote"
113 msgstr ""
114
115 #. TRANSLATORS: this is the PolicyKit modal dialog
116 #: policy/org.freedesktop.fwupd.policy.in:107
117 msgid ""
118 "Authentication is required to modify a configured remote used for firmware "
119 "updates"
120 msgstr ""
108121
109122 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
110 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
123 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
111124 #: src/fu-util.c:112
112125 #, c-format
113126 msgid "Alias to %s"
114127 msgstr "Atalho para %s"
115128
116129 #. TRANSLATORS: error message
117 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
130 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
118131 #: src/fu-util.c:176
119132 msgid "Command not found"
120133 msgstr "Comando não encontrado"
121134
122 #. TRANSLATORS: read from device to host
123 #: libdfu/dfu-tool.c:1236
124 msgid "Reading"
125 msgstr "Lendo"
126
127 #. TRANSLATORS: write from host to device
128 #: libdfu/dfu-tool.c:1242
129 msgid "Writing"
130 msgstr "Escrevendo"
131
132 #. TRANSLATORS: read from device to host
133 #: libdfu/dfu-tool.c:1248
134 msgid "Verifying"
135 msgstr "Verificando"
136
137 #. TRANSLATORS: read from device to host
138 #: libdfu/dfu-tool.c:1254
139 msgid "Erasing"
140 msgstr "Apagando"
141
142 #. TRANSLATORS: waiting for device
143 #: libdfu/dfu-tool.c:1260
144 msgid "Detaching"
145 msgstr "Desanexando"
146
147 #. TRANSLATORS: waiting for device
148 #: libdfu/dfu-tool.c:1266
149 msgid "Attaching"
150 msgstr "Anexando"
151
152135 #. TRANSLATORS: this is when a device is hotplugged
153 #: libdfu/dfu-tool.c:1487
136 #: plugins/dfu/dfu-tool.c:1440
154137 msgid "Added"
155138 msgstr "Adicionado"
156139
157140 #. TRANSLATORS: this is when a device is hotplugged
158 #: libdfu/dfu-tool.c:1498
141 #: plugins/dfu/dfu-tool.c:1451
159142 msgid "Removed"
160143 msgstr "Removido"
161144
162145 #. TRANSLATORS: this is when a device is hotplugged
163146 #. TRANSLATORS: this is when the daemon state changes
164 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
147 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
165148 msgid "Changed"
166149 msgstr "Alterado"
167150
168151 #. TRANSLATORS: this is when a device ctrl+c's a watch
169 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
152 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
170153 msgid "Cancelled"
171154 msgstr "Cancelado"
172155
173156 #. TRANSLATORS: Appstream ID for the hardware type
174 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
157 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
175158 msgid "ID"
176159 msgstr "ID"
177160
178161 #. TRANSLATORS: interface name, e.g. "Flash"
179162 #. TRANSLATORS: device name, e.g. 'ColorHug2'
180 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
163 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
164 #: plugins/dfu/dfu-tool.c:2065
181165 msgid "Name"
182166 msgstr "Nome"
183167
184168 #. TRANSLATORS: this is the encryption method used when writing
185 #: libdfu/dfu-tool.c:2043
169 #: plugins/dfu/dfu-tool.c:1985
186170 msgid "Cipher"
187171 msgstr "Cifra"
188172
189173 #. TRANSLATORS: these are areas of memory on the chip
190 #: libdfu/dfu-tool.c:2057
174 #: plugins/dfu/dfu-tool.c:1999
191175 msgid "Region"
192176 msgstr "Região"
193177
194178 #. TRANSLATORS: detected a DFU device
195 #: libdfu/dfu-tool.c:2092
179 #: plugins/dfu/dfu-tool.c:2033
196180 msgid "Found"
197181 msgstr "Encontrado"
198182
199183 #. TRANSLATORS: DFU protocol version, e.g. 1.1
200 #: libdfu/dfu-tool.c:2100
184 #: plugins/dfu/dfu-tool.c:2041
201185 msgid "Protocol"
202186 msgstr "Protocolo"
203187
204188 #. TRANSLATORS: probably not run as root...
205189 #. TRANSLATORS: device has failed to report status
206190 #. TRANSLATORS: device status, e.g. "OK"
207 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
191 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
192 #: plugins/dfu/dfu-tool.c:2080
208193 msgid "Status"
209194 msgstr "Status"
210195
211 #: libdfu/dfu-tool.c:2112
196 #: plugins/dfu/dfu-tool.c:2054
212197 msgid "Unknown: permission denied"
213198 msgstr "Desconhecido: permissão negada"
214199
215200 #. TRANSLATORS: serial number, e.g. '00012345'
216 #: libdfu/dfu-tool.c:2129
201 #: plugins/dfu/dfu-tool.c:2071
217202 msgid "Serial"
218203 msgstr "Serial"
219204
220205 #. TRANSLATORS: device mode, e.g. runtime or DFU
221 #: libdfu/dfu-tool.c:2134
206 #: plugins/dfu/dfu-tool.c:2076
222207 msgid "Mode"
223208 msgstr "Modo"
224209
225210 #. TRANSLATORS: device state, i.e. appIDLE
226 #: libdfu/dfu-tool.c:2142
211 #: plugins/dfu/dfu-tool.c:2084
227212 msgid "State"
228213 msgstr "Estado"
229214
230215 #. TRANSLATORS: transfer size in bytes
231 #: libdfu/dfu-tool.c:2150
216 #: plugins/dfu/dfu-tool.c:2092
232217 msgid "Transfer Size"
233218 msgstr "Tamanho da transferência"
234219
235220 #. TRANSLATORS: device quirks, i.e. things that
236221 #. * it does that we have to work around
237 #: libdfu/dfu-tool.c:2158
222 #: plugins/dfu/dfu-tool.c:2100
238223 msgid "Quirks"
239224 msgstr "Gambiarra"
240225
241226 #. TRANSLATORS: command description
242 #: libdfu/dfu-tool.c:2237
227 #: plugins/dfu/dfu-tool.c:2181
243228 msgid "Convert firmware to DFU format"
244229 msgstr "Converte um firmware para formato DFU"
245230
246231 #. TRANSLATORS: command description
247 #: libdfu/dfu-tool.c:2243
232 #: plugins/dfu/dfu-tool.c:2187
248233 msgid "Merge multiple firmware files into one"
249234 msgstr "Mescla múltiplos arquivos de firmware em um"
250235
251236 #. TRANSLATORS: command description
252 #: libdfu/dfu-tool.c:2249
237 #: plugins/dfu/dfu-tool.c:2193
253238 msgid "Set vendor ID on firmware file"
254239 msgstr "Define o ID de fabricante no arquivo de firmware"
255240
256241 #. TRANSLATORS: command description
257 #: libdfu/dfu-tool.c:2255
242 #: plugins/dfu/dfu-tool.c:2199
258243 msgid "Set product ID on firmware file"
259244 msgstr "Define o ID de produto no arquivo de firmware"
260245
261246 #. TRANSLATORS: command description
262 #: libdfu/dfu-tool.c:2261
247 #: plugins/dfu/dfu-tool.c:2205
263248 msgid "Set element address on firmware file"
264249 msgstr "Define o endereço do elemento no arquivo de firmware"
265250
266251 #. TRANSLATORS: command description
267 #: libdfu/dfu-tool.c:2267
252 #: plugins/dfu/dfu-tool.c:2211
268253 msgid "Set the firmware size for the target"
269254 msgstr "Define o tamanho do firmware para o alvo"
270255
271256 #. TRANSLATORS: command description
272 #: libdfu/dfu-tool.c:2273
257 #: plugins/dfu/dfu-tool.c:2217
273258 msgid "Set release version on firmware file"
274259 msgstr "Define a versão de lançamento no arquivo de firmware"
275260
276261 #. TRANSLATORS: command description
277 #: libdfu/dfu-tool.c:2279
262 #: plugins/dfu/dfu-tool.c:2223
278263 msgid "Set alternative number on firmware file"
279264 msgstr "Define o número alternativo no arquivo de firmware"
280265
281266 #. TRANSLATORS: command description
282 #: libdfu/dfu-tool.c:2285
267 #: plugins/dfu/dfu-tool.c:2229
283268 msgid "Set alternative name on firmware file"
284269 msgstr "Define o nome alternativo no arquivo de firmware"
285270
286271 #. TRANSLATORS: command description
287 #: libdfu/dfu-tool.c:2291
272 #: plugins/dfu/dfu-tool.c:2235
288273 msgid "Attach DFU capable device back to runtime"
289274 msgstr "Anexa um dispositivo com capacidade de DFU em tempo real"
290275
291276 #. TRANSLATORS: command description
292 #: libdfu/dfu-tool.c:2297
277 #: plugins/dfu/dfu-tool.c:2241
293278 msgid "Read firmware from device into a file"
294279 msgstr "Lê o firmware do dispositivo para um arquivo"
295280
296281 #. TRANSLATORS: command description
297 #: libdfu/dfu-tool.c:2303
282 #: plugins/dfu/dfu-tool.c:2247
298283 msgid "Read firmware from one partition into a file"
299284 msgstr "Lê o firmware de uma partição para um arquivo"
300285
301286 #. TRANSLATORS: command description
302 #: libdfu/dfu-tool.c:2309
287 #: plugins/dfu/dfu-tool.c:2253
303288 msgid "Write firmware from file into device"
304289 msgstr "Escreve um firmware do arquivo para o dispositivo"
305290
306291 #. TRANSLATORS: command description
307 #: libdfu/dfu-tool.c:2315
292 #: plugins/dfu/dfu-tool.c:2259
308293 msgid "Write firmware from file into one partition"
309294 msgstr "Escreve um firmware do arquivo para uma partição"
310295
311296 #. TRANSLATORS: command description
312 #: libdfu/dfu-tool.c:2321
297 #: plugins/dfu/dfu-tool.c:2265
313298 msgid "List currently attached DFU capable devices"
314299 msgstr "Lista os dispositivos atualmente anexados com capacidade de DFU"
315300
316301 #. TRANSLATORS: command description
317 #: libdfu/dfu-tool.c:2327
302 #: plugins/dfu/dfu-tool.c:2271
318303 msgid "Detach currently attached DFU capable device"
319304 msgstr "Desanexa dispositivos atualmente anexados com capacidade de DFU"
320305
321306 #. TRANSLATORS: command description
322 #: libdfu/dfu-tool.c:2333
307 #: plugins/dfu/dfu-tool.c:2277
323308 msgid "Dump details about a firmware file"
324309 msgstr "Despeja os detalhes sobre um arquivo firmware"
325310
326311 #. TRANSLATORS: command description
327 #: libdfu/dfu-tool.c:2339
312 #: plugins/dfu/dfu-tool.c:2283
328313 msgid "Watch DFU devices being hotplugged"
329314 msgstr "Monitora dispositivos DFU sendo conectados"
330315
331316 #. TRANSLATORS: command description
332 #: libdfu/dfu-tool.c:2345
317 #: plugins/dfu/dfu-tool.c:2289
333318 msgid "Encrypt firmware data"
334319 msgstr "Criptografa os dados do firmware"
335320
336321 #. TRANSLATORS: command description
337 #: libdfu/dfu-tool.c:2351
322 #: plugins/dfu/dfu-tool.c:2295
338323 msgid "Decrypt firmware data"
339324 msgstr "Descriptografa os dados do firmware"
340325
341326 #. TRANSLATORS: command description
342 #: libdfu/dfu-tool.c:2357
327 #: plugins/dfu/dfu-tool.c:2301
343328 msgid "Sets metadata on a firmware file"
344329 msgstr "Define os metadados em um arquivo de firmware"
345330
346331 #. TRANSLATORS: command description
347 #: libdfu/dfu-tool.c:2363
332 #: plugins/dfu/dfu-tool.c:2307
348333 msgid "Replace data in an existing firmware file"
349334 msgstr "Substitui os dados em um arquivo de firmware existente"
350335
351336 #. TRANSLATORS: command description
352 #: libdfu/dfu-tool.c:2369
337 #: plugins/dfu/dfu-tool.c:2313
353338 msgid "Create a binary patch using two files"
354 msgstr ""
355
356 #. TRANSLATORS: command description
357 #: libdfu/dfu-tool.c:2375
339 msgstr "Cria um patch binário usando dois arquivos"
340
341 #. TRANSLATORS: command description
342 #: plugins/dfu/dfu-tool.c:2319
358343 msgid "Apply a binary patch"
359 msgstr ""
360
361 #. TRANSLATORS: command description
362 #: libdfu/dfu-tool.c:2381
344 msgstr "Aplicar um patch binário"
345
346 #. TRANSLATORS: command description
347 #: plugins/dfu/dfu-tool.c:2325
363348 msgid "Dump information about a binary patch to the screen"
364 msgstr ""
349 msgstr "Despeja informações sobre um patch binário na tela"
365350
366351 #. TRANSLATORS: DFU stands for device firmware update
367 #: libdfu/dfu-tool.c:2407
352 #: plugins/dfu/dfu-tool.c:2351
368353 msgid "DFU Utility"
369354 msgstr "Utilitário DFU"
370355
371356 #. TRANSLATORS: the user didn't read the man page
372 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
373 #: src/fu-util.c:1733
357 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
358 #: src/fu-util.c:1778
374359 msgid "Failed to parse arguments"
375360 msgstr "Falha ao interpretar argumentos"
376361
377362 #. TRANSLATORS: command description
378 #: plugins/synapticsmst/synapticsmst-tool.c:408
363 #: plugins/synapticsmst/synapticsmst-tool.c:400
379364 msgid "Enumerate all Synaptics MST devices"
380365 msgstr "Enumera todos os dispositivos MST da Synaptics"
381366
382367 #. TRANSLATORS: command description
383 #: plugins/synapticsmst/synapticsmst-tool.c:414
368 #: plugins/synapticsmst/synapticsmst-tool.c:406
384369 msgid "Flash firmware file to MST device"
385370 msgstr "Instala o arquivo firmware em um dispositivo MST"
386371
387 #: plugins/synapticsmst/synapticsmst-tool.c:434
372 #: plugins/synapticsmst/synapticsmst-tool.c:426
388373 msgid "Synaptics Multistream Transport Utility"
389 msgstr "Utiliário de Synaptics Multistream Transport"
374 msgstr "Utilitário de Synaptics Multistream Transport"
390375
391376 #. TRANSLATORS: this is shown when updating the firmware after the reboot
392 #: plugins/uefi/fu-plugin-uefi.c:194
377 #: plugins/uefi/fu-plugin-uefi.c:396
393378 msgid "Installing firmware update…"
394 msgstr ""
379 msgstr "Instalando atualização de firmware…"
395380
396381 #. TRANSLATORS: turn on all debugging
397382 #: src/fu-debug.c:130
409394 msgstr "Mostrar opções de depuração"
410395
411396 #. TRANSLATORS: exit after we've started up, used for user profiling
412 #: src/fu-main.c:863
397 #: src/fu-main.c:960
413398 msgid "Exit after a small delay"
414399 msgstr "Sair após pequeno atraso"
415400
416401 #. TRANSLATORS: exit straight away, used for automatic profiling
417 #: src/fu-main.c:866
402 #: src/fu-main.c:963
418403 msgid "Exit after the engine has loaded"
419404 msgstr "Sair após o carregamento do motor"
420405
421406 #. TRANSLATORS: program name
422 #: src/fu-main.c:880
407 #: src/fu-main.c:977
423408 msgid "Firmware Update Daemon"
424409 msgstr "Daemon de Atualização de Firmware"
425410
426411 #. TRANSLATORS: program summary
427 #: src/fu-main.c:885
412 #: src/fu-main.c:982
428413 msgid "Firmware Update D-Bus Service"
429414 msgstr "Serviço D-Bus de Atualização de Firmware"
430415
431416 #. TRANSLATORS: daemon is inactive
432 #: src/fu-progressbar.c:51
417 #: src/fu-progressbar.c:52
433418 msgid "Idle…"
434419 msgstr "Ocioso…"
435420
436421 #. TRANSLATORS: decompressing the firmware file
437 #: src/fu-progressbar.c:55
422 #: src/fu-progressbar.c:56
438423 msgid "Decompressing…"
439424 msgstr "Descomprimindo…"
440425
441426 #. TRANSLATORS: parsing the firmware information
442 #: src/fu-progressbar.c:59
427 #: src/fu-progressbar.c:60
443428 msgid "Loading…"
444429 msgstr "Carregando…"
445430
446431 #. TRANSLATORS: restarting the device to pick up new F/W
447 #: src/fu-progressbar.c:63
432 #: src/fu-progressbar.c:64
448433 msgid "Restarting device…"
449434 msgstr "Reiniciando dispositivo…"
450435
436 #. TRANSLATORS: reading from the flash chips
437 #: src/fu-progressbar.c:68
438 msgid "Reading…"
439 msgstr ""
440
451441 #. TRANSLATORS: writing to the flash chips
452 #: src/fu-progressbar.c:67
442 #: src/fu-progressbar.c:72
453443 msgid "Writing…"
454444 msgstr "Escrevendo…"
455445
446 #. TRANSLATORS: erasing contents of the flash chips
447 #: src/fu-progressbar.c:76
448 msgid "Erasing…"
449 msgstr ""
450
456451 #. TRANSLATORS: verifying we wrote the firmware correctly
457 #: src/fu-progressbar.c:71
452 #: src/fu-progressbar.c:80
458453 msgid "Verifying…"
459454 msgstr "Verificando…"
460455
461456 #. TRANSLATORS: scheduing an update to be done on the next boot
462 #: src/fu-progressbar.c:75
457 #: src/fu-progressbar.c:84
463458 msgid "Scheduling…"
464459 msgstr "Agendando…"
465460
466461 #. TRANSLATORS: downloading from a remote server
467 #: src/fu-progressbar.c:79
462 #: src/fu-progressbar.c:88
468463 msgid "Downloading…"
464 msgstr "Baixando…"
465
466 #. TRANSLATORS: waiting for user to authenticate
467 #: src/fu-progressbar.c:92
468 msgid "Authenticating…"
469469 msgstr ""
470470
471471 #. TRANSLATORS: currect daemon status is unknown
472 #: src/fu-progressbar.c:86
472 #: src/fu-progressbar.c:99
473473 msgid "Unknown"
474474 msgstr "Desconhecido"
475475
477477 #: src/fu-util.c:234
478478 #, c-format
479479 msgid "Please enter a number from 1 to %u: "
480 msgstr ""
480 msgstr "Por favor, insira um número de 1 a %u: "
481481
482482 #. TRANSLATORS: get interactive prompt
483483 #: src/fu-util.c:277
484484 msgid "Choose a device:"
485 msgstr ""
485 msgstr "Escolha um dispositivo:"
486486
487487 #. TRANSLATORS: nothing attached that can be upgraded
488488 #: src/fu-util.c:303
489489 msgid "No hardware detected with firmware update capability"
490490 msgstr "Nenhum periférico com capacidade de atualização de firmware foi detectado"
491491
492 #. TRANSLATOR: the plugin only supports offline
493 #: src/fu-util.c:337
494 msgid "Retrying as an offline update"
495 msgstr "Tentando novamente como atualização offline"
496
497492 #. TRANSLATORS: the first replacement is a display name
498493 #. * e.g. "ColorHugALS" and the second is a version number
499494 #. * e.g. "1.2.3"
500 #: src/fu-util.c:501
495 #: src/fu-util.c:474
501496 #, c-format
502497 msgid "Reinstalling %s with %s... "
503498 msgstr "Reinstalando %s com %s..."
505500 #. TRANSLATORS: the first replacement is a display name
506501 #. * e.g. "ColorHugALS" and the second and third are
507502 #. * version numbers e.g. "1.2.3"
508 #: src/fu-util.c:508
503 #: src/fu-util.c:481
509504 #, c-format
510505 msgid "Downgrading %s from %s to %s... "
511506 msgstr "Revertendo %s de %s para %s..."
513508 #. TRANSLATORS: the first replacement is a display name
514509 #. * e.g. "ColorHugALS" and the second and third are
515510 #. * version numbers e.g. "1.2.3"
516 #: src/fu-util.c:516
511 #: src/fu-util.c:489
517512 #, c-format
518513 msgid "Updating %s from %s to %s... "
519514 msgstr "Atualizando %s de %s para %s..."
520515
521 #: src/fu-util.c:543
516 #: src/fu-util.c:516
522517 msgid "Done!"
523518 msgstr "Feito!"
524519
525 #: src/fu-util.c:585 src/fu-util.c:985
520 #: src/fu-util.c:565 src/fu-util.c:978
526521 msgid "OK"
527522 msgstr "OK"
528523
529524 #. TRANSLATORS: downloading new signing file
530 #: src/fu-util.c:719
525 #: src/fu-util.c:699
531526 msgid "Fetching signature"
532 msgstr ""
527 msgstr "Obtendo assinatura"
533528
534529 #. TRANSLATORS: downloading new metadata file
535 #: src/fu-util.c:722
530 #: src/fu-util.c:702
536531 msgid "Fetching metadata"
537 msgstr ""
532 msgstr "Obtendo metadados"
538533
539534 #. TRANSLATORS: downloading new firmware file
540 #: src/fu-util.c:725
535 #: src/fu-util.c:705
541536 msgid "Fetching firmware"
542 msgstr ""
537 msgstr "Obtendo firmware"
543538
544539 #. TRANSLATORS: downloading unknown file
545 #: src/fu-util.c:728
540 #: src/fu-util.c:708
546541 msgid "Fetching file"
547 msgstr ""
542 msgstr "Obtendo arquivo"
548543
549544 #. TRANSLATORS: section header for release version number
550 #: src/fu-util.c:898
545 #: src/fu-util.c:888
551546 msgid "Version"
552547 msgstr "Versão"
553548
549 #. TRANSLATORS: section header for the remote the file is coming from
550 #: src/fu-util.c:891
551 msgid "Remote"
552 msgstr ""
553
554554 #. TRANSLATORS: section header for firmware URI
555 #: src/fu-util.c:901
555 #: src/fu-util.c:894
556556 msgid "URI"
557 msgstr ""
557 msgstr "URI"
558558
559559 #. TRANSLATORS: section header for firmware description
560 #: src/fu-util.c:907
560 #: src/fu-util.c:900
561561 msgid "Description"
562562 msgstr "Descrição"
563563
564564 #. TRANSLATORS: section header for firmware checksum
565 #: src/fu-util.c:915
565 #. TRANSLATORS: remote checksum
566 #: src/fu-util.c:908 src/fu-util.c:1136
566567 msgid "Checksum"
567568 msgstr "Soma de verificação"
568569
569570 #. TRANSLATORS: get interactive prompt
570 #: src/fu-util.c:947
571 #: src/fu-util.c:940
571572 msgid "Choose a release:"
572 msgstr ""
573 msgstr "Escolha um lançamento:"
573574
574575 #. TRANSLATORS: first replacement is device name
575 #: src/fu-util.c:1036
576 #: src/fu-util.c:1041
576577 #, c-format
577578 msgid "%s has firmware updates:"
578579 msgstr "%s tem atualizações:"
579580
580 #: src/fu-util.c:1046
581 #: src/fu-util.c:1048
581582 msgid "GUID"
582583 msgstr "GUID"
583584
584585 #. TRANSLATORS: section header for firmware version
585 #: src/fu-util.c:1050
586 #: src/fu-util.c:1060
586587 msgid "Update Version"
587588 msgstr "Versão da atualização"
588589
589590 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
590 #: src/fu-util.c:1054
591 #: src/fu-util.c:1064
591592 msgid "Update Remote ID"
592 msgstr ""
593 msgstr "Atualização de ID remoto"
593594
594595 #. TRANSLATORS: section header for firmware checksum
595 #: src/fu-util.c:1063
596 #: src/fu-util.c:1073
596597 msgid "Update Checksum"
597598 msgstr "Soma de verificação da atualização"
598599
599600 #. TRANSLATORS: section header for firmware remote http://
600 #: src/fu-util.c:1067
601 #: src/fu-util.c:1077
601602 msgid "Update Location"
602603 msgstr "Local da atualização"
603604
604605 #. TRANSLATORS: section header for long firmware desc
605 #: src/fu-util.c:1078
606 #: src/fu-util.c:1088
606607 msgid "Update Description"
607608 msgstr "Descrição da atualização"
608609
609610 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
610 #: src/fu-util.c:1104
611 #: src/fu-util.c:1114
611612 msgid "Remote ID"
613 msgstr "ID remoto"
614
615 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
616 #: src/fu-util.c:1118
617 msgid "Title"
612618 msgstr ""
613619
614620 #. TRANSLATORS: remote type, e.g. remote or local
615 #: src/fu-util.c:1108
621 #: src/fu-util.c:1122
616622 msgid "Type"
617 msgstr ""
618
619 #: src/fu-util.c:1113
623 msgstr "Tipo"
624
625 #: src/fu-util.c:1127
620626 msgid "Keyring"
621 msgstr ""
627 msgstr "Chaveiro"
622628
623629 #. TRANSLATORS: if the remote is enabled
624 #: src/fu-util.c:1118
630 #: src/fu-util.c:1132
625631 msgid "Enabled"
626 msgstr ""
632 msgstr "Habilitado"
627633
628634 #. TRANSLATORS: the age of the metadata
629 #: src/fu-util.c:1145
635 #: src/fu-util.c:1163
630636 msgid "Age"
631 msgstr ""
637 msgstr "Idade"
632638
633639 #. TRANSLATORS: the numeric priority
634 #: src/fu-util.c:1152
640 #: src/fu-util.c:1170
635641 msgid "Priority"
636 msgstr ""
642 msgstr "Prioridade"
637643
638644 #. TRANSLATORS: remote filename base
639 #: src/fu-util.c:1157
645 #: src/fu-util.c:1175
640646 msgid "Username"
641 msgstr ""
647 msgstr "Nome de usuário"
642648
643649 #. TRANSLATORS: remote filename base
644 #: src/fu-util.c:1162
650 #: src/fu-util.c:1180
645651 msgid "Password"
646 msgstr ""
647
648 #. TRANSLATORS: remote filename base
649 #: src/fu-util.c:1167
652 msgstr "Senha"
653
654 #. TRANSLATORS: filename of the local file
655 #: src/fu-util.c:1185
650656 msgid "Filename"
651 msgstr ""
652
653 #. TRANSLATORS: remote filename base
654 #: src/fu-util.c:1172
657 msgstr "Nome de arquivo"
658
659 #. TRANSLATORS: filename of the local file
660 #: src/fu-util.c:1190
655661 msgid "Filename Signature"
656 msgstr ""
657
658 #. TRANSLATORS: locatation of the local file
659 #: src/fu-util.c:1177
660 msgid "Location"
661 msgstr "Local"
662
663 #. TRANSLATORS: locatation of the local file
664 #: src/fu-util.c:1182
665 msgid "Location Signature"
666 msgstr ""
662 msgstr "Assinatura de nome de arquivo"
667663
668664 #. TRANSLATORS: remote URI
669 #: src/fu-util.c:1187
665 #: src/fu-util.c:1195
670666 msgid "Metadata URI"
671 msgstr ""
667 msgstr "URI de metadados"
672668
673669 #. TRANSLATORS: remote URI
674 #: src/fu-util.c:1192
670 #: src/fu-util.c:1200
675671 msgid "Metadata URI Signature"
676 msgstr ""
672 msgstr "Assinatura de URI de metadados"
677673
678674 #. TRANSLATORS: remote URI
679 #: src/fu-util.c:1197
675 #: src/fu-util.c:1205
680676 msgid "Firmware Base URI"
681 msgstr ""
677 msgstr "URI base de firmware"
682678
683679 #. TRANSLATORS: this is when a device is hotplugged
684 #: src/fu-util.c:1224
680 #: src/fu-util.c:1232
685681 msgid "Device added:"
686682 msgstr "Dispositivo adicionado:"
687683
688684 #. TRANSLATORS: this is when a device is hotplugged
689 #: src/fu-util.c:1234
685 #: src/fu-util.c:1242
690686 msgid "Device removed:"
691687 msgstr "Dispositivo removido:"
692688
693689 #. TRANSLATORS: this is when a device has been updated
694 #: src/fu-util.c:1244
690 #: src/fu-util.c:1252
695691 msgid "Device changed:"
696692 msgstr "Dispositivo modificado:"
697693
698694 #. TRANSLATORS: command line option
699 #: src/fu-util.c:1568
695 #: src/fu-util.c:1595
700696 msgid "Show extra debugging information"
701697 msgstr "Mostrar informações adicionais de depuração"
702698
703699 #. TRANSLATORS: command line option
704 #: src/fu-util.c:1571
700 #: src/fu-util.c:1598
705701 msgid "Show client and daemon versions"
706 msgstr ""
702 msgstr "Mostra as versões do cliente e do daemon"
707703
708704 #. TRANSLATORS: command line option
709 #: src/fu-util.c:1574
705 #: src/fu-util.c:1601
710706 msgid "Schedule installation for next reboot when possible"
711707 msgstr "Agenda instalação para próxima reinicialização quando possível"
712708
713709 #. TRANSLATORS: command line option
714 #: src/fu-util.c:1577
710 #: src/fu-util.c:1604
715711 msgid "Allow re-installing existing firmware versions"
716712 msgstr "Permitir reinstalar versões existentes de firmware"
717713
718714 #. TRANSLATORS: command line option
719 #: src/fu-util.c:1580
715 #: src/fu-util.c:1607
720716 msgid "Allow downgrading firmware versions"
721717 msgstr "Permitir reverter versões de firmware"
722718
723719 #. TRANSLATORS: command line option
724 #: src/fu-util.c:1583
720 #: src/fu-util.c:1610
725721 msgid "Override plugin warning"
726722 msgstr "Sobrepõe um aviso de plug-in"
727723
728724 #. TRANSLATORS: command description
729 #: src/fu-util.c:1607
725 #: src/fu-util.c:1634
730726 msgid "Get all devices that support firmware updates"
731727 msgstr "Obter todos os dispositivos que suportam atualizações de firmware"
732728
733729 #. TRANSLATORS: command description
734 #: src/fu-util.c:1613
730 #: src/fu-util.c:1640
735731 msgid "Return all the hardware IDs for the machine"
736 msgstr ""
737
738 #. TRANSLATORS: command description
739 #: src/fu-util.c:1619
732 msgstr "Retorna todos os IDs de hardware para a máquina"
733
734 #. TRANSLATORS: command description
735 #: src/fu-util.c:1646
740736 msgid "Install prepared updates now"
741737 msgstr "Instalar as atualizações preparadas agora"
742738
743739 #. TRANSLATORS: command description
744 #: src/fu-util.c:1625
740 #: src/fu-util.c:1652
745741 msgid "Install a firmware file on this hardware"
746742 msgstr "Instalar um arquivo de firmware neste periférico"
747743
748744 #. TRANSLATORS: command description
749 #: src/fu-util.c:1631
745 #: src/fu-util.c:1658
750746 msgid "Gets details about a firmware file"
751747 msgstr "Obtém detalhes sobre um arquivo de firmware"
752748
753749 #. TRANSLATORS: command description
754 #: src/fu-util.c:1637
750 #: src/fu-util.c:1664
755751 msgid "Gets the list of updates for connected hardware"
756752 msgstr "Obtém a lista de atualizações para os periféricos conectados"
757753
758754 #. TRANSLATORS: command description
759 #: src/fu-util.c:1643
755 #: src/fu-util.c:1670
760756 msgid "Updates all firmware to latest versions available"
761757 msgstr "Atualiza todos os firmwares para a última versão disponível"
762758
763759 #. TRANSLATORS: command description
764 #: src/fu-util.c:1649
760 #: src/fu-util.c:1676
765761 msgid "Gets the cryptographic hash of the dumped firmware"
766762 msgstr "Obtém o hash criptográfico do firmware despejado"
767763
768764 #. TRANSLATORS: command description
769 #: src/fu-util.c:1655
765 #: src/fu-util.c:1682
770766 msgid "Unlocks the device for firmware access"
771767 msgstr "Desbloqueia o dispositivo para acesso do firmware"
772768
773769 #. TRANSLATORS: command description
774 #: src/fu-util.c:1661
770 #: src/fu-util.c:1688
775771 msgid "Clears the results from the last update"
776772 msgstr "Limpa os resultados da última atualização"
777773
778774 #. TRANSLATORS: command description
779 #: src/fu-util.c:1667
775 #: src/fu-util.c:1694
776 msgid "Clears any updates scheduled to be updated offline"
777 msgstr ""
778
779 #. TRANSLATORS: command description
780 #: src/fu-util.c:1700
780781 msgid "Gets the results from the last update"
781782 msgstr "Obtém os resultados da última atualização"
782783
783784 #. TRANSLATORS: command description
784 #: src/fu-util.c:1673
785 #: src/fu-util.c:1706
785786 msgid "Gets the releases for a device"
786 msgstr ""
787
788 #. TRANSLATORS: command description
789 #: src/fu-util.c:1679
787 msgstr "Obtém os lançamentos para um dispositivo"
788
789 #. TRANSLATORS: command description
790 #: src/fu-util.c:1712
790791 msgid "Gets the configured remotes"
791 msgstr ""
792
793 #. TRANSLATORS: command description
794 #: src/fu-util.c:1685
792 msgstr "Obtém os remotos configurados"
793
794 #. TRANSLATORS: command description
795 #: src/fu-util.c:1718
795796 msgid "Downgrades the firmware on a device"
796 msgstr ""
797
798 #. TRANSLATORS: command description
799 #: src/fu-util.c:1691
797 msgstr "Retrocede a versão do firmware em um dispositivo"
798
799 #. TRANSLATORS: command description
800 #: src/fu-util.c:1724
800801 msgid "Refresh metadata from remote server"
801802 msgstr "Renova metadados do servidor remoto"
802803
803804 #. TRANSLATORS: command description
804 #: src/fu-util.c:1697
805 #: src/fu-util.c:1730
805806 msgid "Update the stored metadata with current ROM contents"
806807 msgstr "Atualiza os metadados armazenados com o conteúdo da ROM atual"
807808
808809 #. TRANSLATORS: command description
809 #: src/fu-util.c:1703
810 #: src/fu-util.c:1736
810811 msgid "Monitor the daemon for events"
811812 msgstr "Monitora o daemon por eventos"
812813
813814 #. TRANSLATORS: command description
814 #: src/fu-util.c:1709
815 #: src/fu-util.c:1742
815816 msgid "Build firmware using a sandbox"
817 msgstr "Compila o firmware usando um sandbox"
818
819 #. TRANSLATORS: command description
820 #: src/fu-util.c:1748
821 msgid "Dump SMBIOS data from a file"
822 msgstr ""
823
824 #. TRANSLATORS: command description
825 #: src/fu-util.c:1754
826 msgid "Modifies a given remote"
816827 msgstr ""
817828
818829 #. TRANSLATORS: program name
819 #: src/fu-util.c:1728
830 #: src/fu-util.c:1773
820831 msgid "Firmware Utility"
821832 msgstr "Utilitário de Firmware"
+184
-175
po/ru.po less more
88 msgstr ""
99 "Project-Id-Version: fwupd\n"
1010 "Report-Msgid-Bugs-To: \n"
11 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
12 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
11 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
12 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1313 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1414 "Language-Team: Russian (http://www.transifex.com/freedesktop/fwupd/language/ru/)\n"
1515 "MIME-Version: 1.0\n"
105105 "Authentication is required to update the stored checksums for the device"
106106 msgstr "Для обновления хранимых контрольных сумм устройства требуется аутентификация"
107107
108 #: policy/org.freedesktop.fwupd.policy.in:105
109 msgid "Modify a configured remote"
110 msgstr ""
111
112 #. TRANSLATORS: this is the PolicyKit modal dialog
113 #: policy/org.freedesktop.fwupd.policy.in:107
114 msgid ""
115 "Authentication is required to modify a configured remote used for firmware "
116 "updates"
117 msgstr ""
118
108119 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
109 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
120 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
110121 #: src/fu-util.c:112
111122 #, c-format
112123 msgid "Alias to %s"
113124 msgstr "Псевдоним %s"
114125
115126 #. TRANSLATORS: error message
116 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
127 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
117128 #: src/fu-util.c:176
118129 msgid "Command not found"
119130 msgstr "Команда не найдена"
120131
121 #. TRANSLATORS: read from device to host
122 #: libdfu/dfu-tool.c:1236
123 msgid "Reading"
124 msgstr "Чтение"
125
126 #. TRANSLATORS: write from host to device
127 #: libdfu/dfu-tool.c:1242
128 msgid "Writing"
129 msgstr "запись"
130
131 #. TRANSLATORS: read from device to host
132 #: libdfu/dfu-tool.c:1248
133 msgid "Verifying"
134 msgstr "Проверка"
135
136 #. TRANSLATORS: read from device to host
137 #: libdfu/dfu-tool.c:1254
138 msgid "Erasing"
139 msgstr "Стирание"
140
141 #. TRANSLATORS: waiting for device
142 #: libdfu/dfu-tool.c:1260
143 msgid "Detaching"
144 msgstr "Отсоединение"
145
146 #. TRANSLATORS: waiting for device
147 #: libdfu/dfu-tool.c:1266
148 msgid "Attaching"
149 msgstr "Присоединение"
150
151132 #. TRANSLATORS: this is when a device is hotplugged
152 #: libdfu/dfu-tool.c:1487
133 #: plugins/dfu/dfu-tool.c:1440
153134 msgid "Added"
154135 msgstr "Добавлено"
155136
156137 #. TRANSLATORS: this is when a device is hotplugged
157 #: libdfu/dfu-tool.c:1498
138 #: plugins/dfu/dfu-tool.c:1451
158139 msgid "Removed"
159140 msgstr "Удалено"
160141
161142 #. TRANSLATORS: this is when a device is hotplugged
162143 #. TRANSLATORS: this is when the daemon state changes
163 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
144 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
164145 msgid "Changed"
165146 msgstr "Изменено"
166147
167148 #. TRANSLATORS: this is when a device ctrl+c's a watch
168 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
149 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
169150 msgid "Cancelled"
170151 msgstr "Отменено"
171152
172153 #. TRANSLATORS: Appstream ID for the hardware type
173 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
154 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
174155 msgid "ID"
175156 msgstr "ID"
176157
177158 #. TRANSLATORS: interface name, e.g. "Flash"
178159 #. TRANSLATORS: device name, e.g. 'ColorHug2'
179 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
160 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
161 #: plugins/dfu/dfu-tool.c:2065
180162 msgid "Name"
181163 msgstr "Наименование"
182164
183165 #. TRANSLATORS: this is the encryption method used when writing
184 #: libdfu/dfu-tool.c:2043
166 #: plugins/dfu/dfu-tool.c:1985
185167 msgid "Cipher"
186168 msgstr "Шифр"
187169
188170 #. TRANSLATORS: these are areas of memory on the chip
189 #: libdfu/dfu-tool.c:2057
171 #: plugins/dfu/dfu-tool.c:1999
190172 msgid "Region"
191173 msgstr "Регион"
192174
193175 #. TRANSLATORS: detected a DFU device
194 #: libdfu/dfu-tool.c:2092
176 #: plugins/dfu/dfu-tool.c:2033
195177 msgid "Found"
196178 msgstr "Найдено"
197179
198180 #. TRANSLATORS: DFU protocol version, e.g. 1.1
199 #: libdfu/dfu-tool.c:2100
181 #: plugins/dfu/dfu-tool.c:2041
200182 msgid "Protocol"
201183 msgstr "Протокол"
202184
203185 #. TRANSLATORS: probably not run as root...
204186 #. TRANSLATORS: device has failed to report status
205187 #. TRANSLATORS: device status, e.g. "OK"
206 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
188 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
189 #: plugins/dfu/dfu-tool.c:2080
207190 msgid "Status"
208191 msgstr "Статус"
209192
210 #: libdfu/dfu-tool.c:2112
193 #: plugins/dfu/dfu-tool.c:2054
211194 msgid "Unknown: permission denied"
212195 msgstr "Неизвестно: доступ запрещён"
213196
214197 #. TRANSLATORS: serial number, e.g. '00012345'
215 #: libdfu/dfu-tool.c:2129
198 #: plugins/dfu/dfu-tool.c:2071
216199 msgid "Serial"
217200 msgstr "Порядковое"
218201
219202 #. TRANSLATORS: device mode, e.g. runtime or DFU
220 #: libdfu/dfu-tool.c:2134
203 #: plugins/dfu/dfu-tool.c:2076
221204 msgid "Mode"
222205 msgstr "Режим"
223206
224207 #. TRANSLATORS: device state, i.e. appIDLE
225 #: libdfu/dfu-tool.c:2142
208 #: plugins/dfu/dfu-tool.c:2084
226209 msgid "State"
227210 msgstr "Состояние"
228211
229212 #. TRANSLATORS: transfer size in bytes
230 #: libdfu/dfu-tool.c:2150
213 #: plugins/dfu/dfu-tool.c:2092
231214 msgid "Transfer Size"
232215 msgstr "Размер передачи"
233216
234217 #. TRANSLATORS: device quirks, i.e. things that
235218 #. * it does that we have to work around
236 #: libdfu/dfu-tool.c:2158
219 #: plugins/dfu/dfu-tool.c:2100
237220 msgid "Quirks"
238221 msgstr "Проблемы"
239222
240223 #. TRANSLATORS: command description
241 #: libdfu/dfu-tool.c:2237
224 #: plugins/dfu/dfu-tool.c:2181
242225 msgid "Convert firmware to DFU format"
243226 msgstr "Преобразовать микропрограмму в формат DFU"
244227
245228 #. TRANSLATORS: command description
246 #: libdfu/dfu-tool.c:2243
229 #: plugins/dfu/dfu-tool.c:2187
247230 msgid "Merge multiple firmware files into one"
248231 msgstr "Объединить несколько файлов микропрограмм в один"
249232
250233 #. TRANSLATORS: command description
251 #: libdfu/dfu-tool.c:2249
234 #: plugins/dfu/dfu-tool.c:2193
252235 msgid "Set vendor ID on firmware file"
253236 msgstr "Установить идентификатор производителя для файла микропрограммы"
254237
255238 #. TRANSLATORS: command description
256 #: libdfu/dfu-tool.c:2255
239 #: plugins/dfu/dfu-tool.c:2199
257240 msgid "Set product ID on firmware file"
258241 msgstr "Установить идентификатор продукта для файла микропрограммы"
259242
260243 #. TRANSLATORS: command description
261 #: libdfu/dfu-tool.c:2261
244 #: plugins/dfu/dfu-tool.c:2205
262245 msgid "Set element address on firmware file"
263246 msgstr "Установить адрес элемента для файла микропрограммы"
264247
265248 #. TRANSLATORS: command description
266 #: libdfu/dfu-tool.c:2267
249 #: plugins/dfu/dfu-tool.c:2211
267250 msgid "Set the firmware size for the target"
268251 msgstr "Установить размер микропрограммы для конечного объекта"
269252
270253 #. TRANSLATORS: command description
271 #: libdfu/dfu-tool.c:2273
254 #: plugins/dfu/dfu-tool.c:2217
272255 msgid "Set release version on firmware file"
273256 msgstr "Установить версию выпуска для файла микропрограммы"
274257
275258 #. TRANSLATORS: command description
276 #: libdfu/dfu-tool.c:2279
259 #: plugins/dfu/dfu-tool.c:2223
277260 msgid "Set alternative number on firmware file"
278261 msgstr "Установить альтернативный номер для файла микропрограммы"
279262
280263 #. TRANSLATORS: command description
281 #: libdfu/dfu-tool.c:2285
264 #: plugins/dfu/dfu-tool.c:2229
282265 msgid "Set alternative name on firmware file"
283266 msgstr "Установить альтернативное наименование для файла микропрограммы"
284267
285268 #. TRANSLATORS: command description
286 #: libdfu/dfu-tool.c:2291
269 #: plugins/dfu/dfu-tool.c:2235
287270 msgid "Attach DFU capable device back to runtime"
288271 msgstr "Вернуть устройство с возможностями DFU к использованию"
289272
290273 #. TRANSLATORS: command description
291 #: libdfu/dfu-tool.c:2297
274 #: plugins/dfu/dfu-tool.c:2241
292275 msgid "Read firmware from device into a file"
293276 msgstr "Считать микропрограмму из устройства файл"
294277
295278 #. TRANSLATORS: command description
296 #: libdfu/dfu-tool.c:2303
279 #: plugins/dfu/dfu-tool.c:2247
297280 msgid "Read firmware from one partition into a file"
298281 msgstr "Считать микропрограмму из одного раздела в файл"
299282
300283 #. TRANSLATORS: command description
301 #: libdfu/dfu-tool.c:2309
284 #: plugins/dfu/dfu-tool.c:2253
302285 msgid "Write firmware from file into device"
303286 msgstr "Записать микропрограмму из файла на устройство"
304287
305288 #. TRANSLATORS: command description
306 #: libdfu/dfu-tool.c:2315
289 #: plugins/dfu/dfu-tool.c:2259
307290 msgid "Write firmware from file into one partition"
308291 msgstr "Записать микропрограмму из файла на один раздел"
309292
310293 #. TRANSLATORS: command description
311 #: libdfu/dfu-tool.c:2321
294 #: plugins/dfu/dfu-tool.c:2265
312295 msgid "List currently attached DFU capable devices"
313296 msgstr "Вывести список подсоединённых сейчас устройств с возможностями DFU"
314297
315298 #. TRANSLATORS: command description
316 #: libdfu/dfu-tool.c:2327
299 #: plugins/dfu/dfu-tool.c:2271
317300 msgid "Detach currently attached DFU capable device"
318301 msgstr "Отсоединить подсоединённое сейчас устройство с возможностями DFU"
319302
320303 #. TRANSLATORS: command description
321 #: libdfu/dfu-tool.c:2333
304 #: plugins/dfu/dfu-tool.c:2277
322305 msgid "Dump details about a firmware file"
323306 msgstr "Создать дамп данных по файлу микропрограммы"
324307
325308 #. TRANSLATORS: command description
326 #: libdfu/dfu-tool.c:2339
309 #: plugins/dfu/dfu-tool.c:2283
327310 msgid "Watch DFU devices being hotplugged"
328311 msgstr "Наблюдать за устройствами DFU, которые являются подключёнными"
329312
330313 #. TRANSLATORS: command description
331 #: libdfu/dfu-tool.c:2345
314 #: plugins/dfu/dfu-tool.c:2289
332315 msgid "Encrypt firmware data"
333316 msgstr "Зашифровать данные микропрограммы"
334317
335318 #. TRANSLATORS: command description
336 #: libdfu/dfu-tool.c:2351
319 #: plugins/dfu/dfu-tool.c:2295
337320 msgid "Decrypt firmware data"
338321 msgstr "Расшифровать данные микропрограммы"
339322
340323 #. TRANSLATORS: command description
341 #: libdfu/dfu-tool.c:2357
324 #: plugins/dfu/dfu-tool.c:2301
342325 msgid "Sets metadata on a firmware file"
343326 msgstr "Устанавливает метаданные файла микропрограммы"
344327
345328 #. TRANSLATORS: command description
346 #: libdfu/dfu-tool.c:2363
329 #: plugins/dfu/dfu-tool.c:2307
347330 msgid "Replace data in an existing firmware file"
348331 msgstr "Заменить данные в существующем файле микропрограммы"
349332
350333 #. TRANSLATORS: command description
351 #: libdfu/dfu-tool.c:2369
334 #: plugins/dfu/dfu-tool.c:2313
352335 msgid "Create a binary patch using two files"
353336 msgstr ""
354337
355338 #. TRANSLATORS: command description
356 #: libdfu/dfu-tool.c:2375
339 #: plugins/dfu/dfu-tool.c:2319
357340 msgid "Apply a binary patch"
358341 msgstr ""
359342
360343 #. TRANSLATORS: command description
361 #: libdfu/dfu-tool.c:2381
344 #: plugins/dfu/dfu-tool.c:2325
362345 msgid "Dump information about a binary patch to the screen"
363346 msgstr ""
364347
365348 #. TRANSLATORS: DFU stands for device firmware update
366 #: libdfu/dfu-tool.c:2407
349 #: plugins/dfu/dfu-tool.c:2351
367350 msgid "DFU Utility"
368351 msgstr "Средство работы с DFU"
369352
370353 #. TRANSLATORS: the user didn't read the man page
371 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
372 #: src/fu-util.c:1733
354 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
355 #: src/fu-util.c:1778
373356 msgid "Failed to parse arguments"
374357 msgstr "Не удалось разобрать аргументы"
375358
376359 #. TRANSLATORS: command description
377 #: plugins/synapticsmst/synapticsmst-tool.c:408
360 #: plugins/synapticsmst/synapticsmst-tool.c:400
378361 msgid "Enumerate all Synaptics MST devices"
379362 msgstr "Перечислить все устройства Synaptics MST"
380363
381364 #. TRANSLATORS: command description
382 #: plugins/synapticsmst/synapticsmst-tool.c:414
365 #: plugins/synapticsmst/synapticsmst-tool.c:406
383366 msgid "Flash firmware file to MST device"
384367 msgstr "Записать файл микропрограммы на устройство MST"
385368
386 #: plugins/synapticsmst/synapticsmst-tool.c:434
369 #: plugins/synapticsmst/synapticsmst-tool.c:426
387370 msgid "Synaptics Multistream Transport Utility"
388371 msgstr "Средство многопоточной передачи Synaptics"
389372
390373 #. TRANSLATORS: this is shown when updating the firmware after the reboot
391 #: plugins/uefi/fu-plugin-uefi.c:194
374 #: plugins/uefi/fu-plugin-uefi.c:396
392375 msgid "Installing firmware update…"
393376 msgstr "Установка обновления микропрограммы..."
394377
408391 msgstr "Показать параметры отладки"
409392
410393 #. TRANSLATORS: exit after we've started up, used for user profiling
411 #: src/fu-main.c:863
394 #: src/fu-main.c:960
412395 msgid "Exit after a small delay"
413396 msgstr "Выйти после небольшой задержки"
414397
415398 #. TRANSLATORS: exit straight away, used for automatic profiling
416 #: src/fu-main.c:866
399 #: src/fu-main.c:963
417400 msgid "Exit after the engine has loaded"
418401 msgstr "Выйти после загрузки движка"
419402
420403 #. TRANSLATORS: program name
421 #: src/fu-main.c:880
404 #: src/fu-main.c:977
422405 msgid "Firmware Update Daemon"
423406 msgstr "Служба обновления микропрограммы"
424407
425408 #. TRANSLATORS: program summary
426 #: src/fu-main.c:885
409 #: src/fu-main.c:982
427410 msgid "Firmware Update D-Bus Service"
428411 msgstr "D-Bus служба обновления микропрограммы"
429412
430413 #. TRANSLATORS: daemon is inactive
431 #: src/fu-progressbar.c:51
414 #: src/fu-progressbar.c:52
432415 msgid "Idle…"
433416 msgstr "Бездействие…"
434417
435418 #. TRANSLATORS: decompressing the firmware file
436 #: src/fu-progressbar.c:55
419 #: src/fu-progressbar.c:56
437420 msgid "Decompressing…"
438421 msgstr "Распаковка…"
439422
440423 #. TRANSLATORS: parsing the firmware information
441 #: src/fu-progressbar.c:59
424 #: src/fu-progressbar.c:60
442425 msgid "Loading…"
443426 msgstr "Загрузка…"
444427
445428 #. TRANSLATORS: restarting the device to pick up new F/W
446 #: src/fu-progressbar.c:63
429 #: src/fu-progressbar.c:64
447430 msgid "Restarting device…"
448431 msgstr "Перезапуск устройства…"
449432
433 #. TRANSLATORS: reading from the flash chips
434 #: src/fu-progressbar.c:68
435 msgid "Reading…"
436 msgstr ""
437
450438 #. TRANSLATORS: writing to the flash chips
451 #: src/fu-progressbar.c:67
439 #: src/fu-progressbar.c:72
452440 msgid "Writing…"
453441 msgstr "Запись…"
454442
443 #. TRANSLATORS: erasing contents of the flash chips
444 #: src/fu-progressbar.c:76
445 msgid "Erasing…"
446 msgstr ""
447
455448 #. TRANSLATORS: verifying we wrote the firmware correctly
456 #: src/fu-progressbar.c:71
449 #: src/fu-progressbar.c:80
457450 msgid "Verifying…"
458451 msgstr "Проверка…"
459452
460453 #. TRANSLATORS: scheduing an update to be done on the next boot
461 #: src/fu-progressbar.c:75
454 #: src/fu-progressbar.c:84
462455 msgid "Scheduling…"
463456 msgstr "Планировка…"
464457
465458 #. TRANSLATORS: downloading from a remote server
466 #: src/fu-progressbar.c:79
459 #: src/fu-progressbar.c:88
467460 msgid "Downloading…"
468461 msgstr "Получение..."
469462
463 #. TRANSLATORS: waiting for user to authenticate
464 #: src/fu-progressbar.c:92
465 msgid "Authenticating…"
466 msgstr ""
467
470468 #. TRANSLATORS: currect daemon status is unknown
471 #: src/fu-progressbar.c:86
469 #: src/fu-progressbar.c:99
472470 msgid "Unknown"
473471 msgstr "Неизвестно"
474472
488486 msgid "No hardware detected with firmware update capability"
489487 msgstr "Не обнаружено оборудования с возможностью обновления микропрограммы"
490488
491 #. TRANSLATOR: the plugin only supports offline
492 #: src/fu-util.c:337
493 msgid "Retrying as an offline update"
494 msgstr "Повторная попытка как в режиме автономного обновления"
495
496489 #. TRANSLATORS: the first replacement is a display name
497490 #. * e.g. "ColorHugALS" and the second is a version number
498491 #. * e.g. "1.2.3"
499 #: src/fu-util.c:501
492 #: src/fu-util.c:474
500493 #, c-format
501494 msgid "Reinstalling %s with %s... "
502495 msgstr "Переустановка %s с %s…"
504497 #. TRANSLATORS: the first replacement is a display name
505498 #. * e.g. "ColorHugALS" and the second and third are
506499 #. * version numbers e.g. "1.2.3"
507 #: src/fu-util.c:508
500 #: src/fu-util.c:481
508501 #, c-format
509502 msgid "Downgrading %s from %s to %s... "
510503 msgstr "Понижение версии %s с %s на %s…"
512505 #. TRANSLATORS: the first replacement is a display name
513506 #. * e.g. "ColorHugALS" and the second and third are
514507 #. * version numbers e.g. "1.2.3"
515 #: src/fu-util.c:516
508 #: src/fu-util.c:489
516509 #, c-format
517510 msgid "Updating %s from %s to %s... "
518511 msgstr "Обновление %s с %s на %s…"
519512
520 #: src/fu-util.c:543
513 #: src/fu-util.c:516
521514 msgid "Done!"
522515 msgstr "Готово!"
523516
524 #: src/fu-util.c:585 src/fu-util.c:985
517 #: src/fu-util.c:565 src/fu-util.c:978
525518 msgid "OK"
526519 msgstr "ОК"
527520
528521 #. TRANSLATORS: downloading new signing file
529 #: src/fu-util.c:719
522 #: src/fu-util.c:699
530523 msgid "Fetching signature"
531524 msgstr "Получение подписи"
532525
533526 #. TRANSLATORS: downloading new metadata file
534 #: src/fu-util.c:722
527 #: src/fu-util.c:702
535528 msgid "Fetching metadata"
536529 msgstr "Получение метаданных"
537530
538531 #. TRANSLATORS: downloading new firmware file
539 #: src/fu-util.c:725
532 #: src/fu-util.c:705
540533 msgid "Fetching firmware"
541534 msgstr "Получение микропрограммы"
542535
543536 #. TRANSLATORS: downloading unknown file
544 #: src/fu-util.c:728
537 #: src/fu-util.c:708
545538 msgid "Fetching file"
546539 msgstr "Получение файла"
547540
548541 #. TRANSLATORS: section header for release version number
549 #: src/fu-util.c:898
542 #: src/fu-util.c:888
550543 msgid "Version"
551544 msgstr "Версия"
552545
546 #. TRANSLATORS: section header for the remote the file is coming from
547 #: src/fu-util.c:891
548 msgid "Remote"
549 msgstr ""
550
553551 #. TRANSLATORS: section header for firmware URI
554 #: src/fu-util.c:901
552 #: src/fu-util.c:894
555553 msgid "URI"
556554 msgstr "URI"
557555
558556 #. TRANSLATORS: section header for firmware description
559 #: src/fu-util.c:907
557 #: src/fu-util.c:900
560558 msgid "Description"
561559 msgstr "Описание"
562560
563561 #. TRANSLATORS: section header for firmware checksum
564 #: src/fu-util.c:915
562 #. TRANSLATORS: remote checksum
563 #: src/fu-util.c:908 src/fu-util.c:1136
565564 msgid "Checksum"
566565 msgstr "Контрольная сумма"
567566
568567 #. TRANSLATORS: get interactive prompt
569 #: src/fu-util.c:947
568 #: src/fu-util.c:940
570569 msgid "Choose a release:"
571570 msgstr "Выберите релиз:"
572571
573572 #. TRANSLATORS: first replacement is device name
574 #: src/fu-util.c:1036
573 #: src/fu-util.c:1041
575574 #, c-format
576575 msgid "%s has firmware updates:"
577576 msgstr "У %s есть обновления микропрограммы:"
578577
579 #: src/fu-util.c:1046
578 #: src/fu-util.c:1048
580579 msgid "GUID"
581580 msgstr "GUID"
582581
583582 #. TRANSLATORS: section header for firmware version
584 #: src/fu-util.c:1050
583 #: src/fu-util.c:1060
585584 msgid "Update Version"
586585 msgstr "Версия обновления"
587586
588587 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
589 #: src/fu-util.c:1054
588 #: src/fu-util.c:1064
590589 msgid "Update Remote ID"
591590 msgstr "Удалённый ID обновления"
592591
593592 #. TRANSLATORS: section header for firmware checksum
594 #: src/fu-util.c:1063
593 #: src/fu-util.c:1073
595594 msgid "Update Checksum"
596595 msgstr "Контрольная сумма обновления"
597596
598597 #. TRANSLATORS: section header for firmware remote http://
599 #: src/fu-util.c:1067
598 #: src/fu-util.c:1077
600599 msgid "Update Location"
601600 msgstr "Расположение обновления"
602601
603602 #. TRANSLATORS: section header for long firmware desc
604 #: src/fu-util.c:1078
603 #: src/fu-util.c:1088
605604 msgid "Update Description"
606605 msgstr "Описание обновления"
607606
608607 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
609 #: src/fu-util.c:1104
608 #: src/fu-util.c:1114
610609 msgid "Remote ID"
611610 msgstr "Удалённый ID"
612611
612 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
613 #: src/fu-util.c:1118
614 msgid "Title"
615 msgstr ""
616
613617 #. TRANSLATORS: remote type, e.g. remote or local
614 #: src/fu-util.c:1108
618 #: src/fu-util.c:1122
615619 msgid "Type"
616620 msgstr ""
617621
618 #: src/fu-util.c:1113
622 #: src/fu-util.c:1127
619623 msgid "Keyring"
620624 msgstr ""
621625
622626 #. TRANSLATORS: if the remote is enabled
623 #: src/fu-util.c:1118
627 #: src/fu-util.c:1132
624628 msgid "Enabled"
625629 msgstr "Включено"
626630
627631 #. TRANSLATORS: the age of the metadata
628 #: src/fu-util.c:1145
632 #: src/fu-util.c:1163
629633 msgid "Age"
630634 msgstr "Возраст"
631635
632636 #. TRANSLATORS: the numeric priority
633 #: src/fu-util.c:1152
637 #: src/fu-util.c:1170
634638 msgid "Priority"
635639 msgstr "Приоритет"
636640
637641 #. TRANSLATORS: remote filename base
638 #: src/fu-util.c:1157
642 #: src/fu-util.c:1175
639643 msgid "Username"
640644 msgstr "Имя пользователя"
641645
642646 #. TRANSLATORS: remote filename base
643 #: src/fu-util.c:1162
647 #: src/fu-util.c:1180
644648 msgid "Password"
645649 msgstr "Пароль"
646650
647 #. TRANSLATORS: remote filename base
648 #: src/fu-util.c:1167
651 #. TRANSLATORS: filename of the local file
652 #: src/fu-util.c:1185
649653 msgid "Filename"
650654 msgstr "Имя файла"
651655
652 #. TRANSLATORS: remote filename base
653 #: src/fu-util.c:1172
656 #. TRANSLATORS: filename of the local file
657 #: src/fu-util.c:1190
654658 msgid "Filename Signature"
655659 msgstr "Подпись имени файла"
656660
657 #. TRANSLATORS: locatation of the local file
658 #: src/fu-util.c:1177
659 msgid "Location"
660 msgstr "Расположение"
661
662 #. TRANSLATORS: locatation of the local file
663 #: src/fu-util.c:1182
664 msgid "Location Signature"
665 msgstr ""
666
667661 #. TRANSLATORS: remote URI
668 #: src/fu-util.c:1187
662 #: src/fu-util.c:1195
669663 msgid "Metadata URI"
670664 msgstr ""
671665
672666 #. TRANSLATORS: remote URI
673 #: src/fu-util.c:1192
667 #: src/fu-util.c:1200
674668 msgid "Metadata URI Signature"
675669 msgstr ""
676670
677671 #. TRANSLATORS: remote URI
678 #: src/fu-util.c:1197
672 #: src/fu-util.c:1205
679673 msgid "Firmware Base URI"
680674 msgstr ""
681675
682676 #. TRANSLATORS: this is when a device is hotplugged
683 #: src/fu-util.c:1224
677 #: src/fu-util.c:1232
684678 msgid "Device added:"
685679 msgstr "Добавлено устройство:"
686680
687681 #. TRANSLATORS: this is when a device is hotplugged
688 #: src/fu-util.c:1234
682 #: src/fu-util.c:1242
689683 msgid "Device removed:"
690684 msgstr "Изъято устройство:"
691685
692686 #. TRANSLATORS: this is when a device has been updated
693 #: src/fu-util.c:1244
687 #: src/fu-util.c:1252
694688 msgid "Device changed:"
695689 msgstr "Заменено устройство:"
696690
697691 #. TRANSLATORS: command line option
698 #: src/fu-util.c:1568
692 #: src/fu-util.c:1595
699693 msgid "Show extra debugging information"
700694 msgstr "Показать дополнительную отладочную информацию"
701695
702696 #. TRANSLATORS: command line option
703 #: src/fu-util.c:1571
697 #: src/fu-util.c:1598
704698 msgid "Show client and daemon versions"
705699 msgstr "Показать версии клиента и демона"
706700
707701 #. TRANSLATORS: command line option
708 #: src/fu-util.c:1574
702 #: src/fu-util.c:1601
709703 msgid "Schedule installation for next reboot when possible"
710704 msgstr "Планирование установки на следующую перезагрузку, если это возможно"
711705
712706 #. TRANSLATORS: command line option
713 #: src/fu-util.c:1577
707 #: src/fu-util.c:1604
714708 msgid "Allow re-installing existing firmware versions"
715709 msgstr "Разрешить повторную установку существующих версий микропрограмм"
716710
717711 #. TRANSLATORS: command line option
718 #: src/fu-util.c:1580
712 #: src/fu-util.c:1607
719713 msgid "Allow downgrading firmware versions"
720714 msgstr "Разрешить понижение версий микропрограмм"
721715
722716 #. TRANSLATORS: command line option
723 #: src/fu-util.c:1583
717 #: src/fu-util.c:1610
724718 msgid "Override plugin warning"
725719 msgstr "Переопределить предупреждение приложения"
726720
727721 #. TRANSLATORS: command description
728 #: src/fu-util.c:1607
722 #: src/fu-util.c:1634
729723 msgid "Get all devices that support firmware updates"
730724 msgstr "Получить все устройства, которые поддерживают обновления микропрограммы"
731725
732726 #. TRANSLATORS: command description
733 #: src/fu-util.c:1613
727 #: src/fu-util.c:1640
734728 msgid "Return all the hardware IDs for the machine"
735729 msgstr "Показать ID всех устройств на машине"
736730
737731 #. TRANSLATORS: command description
738 #: src/fu-util.c:1619
732 #: src/fu-util.c:1646
739733 msgid "Install prepared updates now"
740734 msgstr "Установить подготовленные обновления сейчас"
741735
742736 #. TRANSLATORS: command description
743 #: src/fu-util.c:1625
737 #: src/fu-util.c:1652
744738 msgid "Install a firmware file on this hardware"
745739 msgstr "Установить файл микропрограммы на это оборудование"
746740
747741 #. TRANSLATORS: command description
748 #: src/fu-util.c:1631
742 #: src/fu-util.c:1658
749743 msgid "Gets details about a firmware file"
750744 msgstr "Получает сведения о файле микропрограммы"
751745
752746 #. TRANSLATORS: command description
753 #: src/fu-util.c:1637
747 #: src/fu-util.c:1664
754748 msgid "Gets the list of updates for connected hardware"
755749 msgstr "Получает список обновлений для подключенного оборудования"
756750
757751 #. TRANSLATORS: command description
758 #: src/fu-util.c:1643
752 #: src/fu-util.c:1670
759753 msgid "Updates all firmware to latest versions available"
760754 msgstr "Обновляет все микропрограммы до их последних доступных версий"
761755
762756 #. TRANSLATORS: command description
763 #: src/fu-util.c:1649
757 #: src/fu-util.c:1676
764758 msgid "Gets the cryptographic hash of the dumped firmware"
765759 msgstr "Получает криптографической хэш дампа микропрограммы"
766760
767761 #. TRANSLATORS: command description
768 #: src/fu-util.c:1655
762 #: src/fu-util.c:1682
769763 msgid "Unlocks the device for firmware access"
770764 msgstr "Разблокирует устройство для доступа к микропрограмме"
771765
772766 #. TRANSLATORS: command description
773 #: src/fu-util.c:1661
767 #: src/fu-util.c:1688
774768 msgid "Clears the results from the last update"
775769 msgstr "Очищает результаты c последнего обновления"
776770
777771 #. TRANSLATORS: command description
778 #: src/fu-util.c:1667
772 #: src/fu-util.c:1694
773 msgid "Clears any updates scheduled to be updated offline"
774 msgstr ""
775
776 #. TRANSLATORS: command description
777 #: src/fu-util.c:1700
779778 msgid "Gets the results from the last update"
780779 msgstr "Получает результаты с последнего обновления"
781780
782781 #. TRANSLATORS: command description
783 #: src/fu-util.c:1673
782 #: src/fu-util.c:1706
784783 msgid "Gets the releases for a device"
785784 msgstr "Получает релизы для устройства"
786785
787786 #. TRANSLATORS: command description
788 #: src/fu-util.c:1679
787 #: src/fu-util.c:1712
789788 msgid "Gets the configured remotes"
790789 msgstr ""
791790
792791 #. TRANSLATORS: command description
793 #: src/fu-util.c:1685
792 #: src/fu-util.c:1718
794793 msgid "Downgrades the firmware on a device"
795794 msgstr "Скачивает микропрограмму на устройство"
796795
797796 #. TRANSLATORS: command description
798 #: src/fu-util.c:1691
797 #: src/fu-util.c:1724
799798 msgid "Refresh metadata from remote server"
800799 msgstr "Обновить метаданные с удаленного сервера"
801800
802801 #. TRANSLATORS: command description
803 #: src/fu-util.c:1697
802 #: src/fu-util.c:1730
804803 msgid "Update the stored metadata with current ROM contents"
805804 msgstr "Обновить хранимые метаданные с текущим содержимым ПЗУ"
806805
807806 #. TRANSLATORS: command description
808 #: src/fu-util.c:1703
807 #: src/fu-util.c:1736
809808 msgid "Monitor the daemon for events"
810809 msgstr "Следить за событиями в фоновой службе"
811810
812811 #. TRANSLATORS: command description
813 #: src/fu-util.c:1709
812 #: src/fu-util.c:1742
814813 msgid "Build firmware using a sandbox"
815814 msgstr ""
816815
816 #. TRANSLATORS: command description
817 #: src/fu-util.c:1748
818 msgid "Dump SMBIOS data from a file"
819 msgstr ""
820
821 #. TRANSLATORS: command description
822 #: src/fu-util.c:1754
823 msgid "Modifies a given remote"
824 msgstr ""
825
817826 #. TRANSLATORS: program name
818 #: src/fu-util.c:1728
827 #: src/fu-util.c:1773
819828 msgid "Firmware Utility"
820829 msgstr "Средство работы с микропрограммами"
+184
-175
po/sk.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Slovak (http://www.transifex.com/freedesktop/fwupd/language/sk/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Prezývka príkazu %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Príkaz nenájdený"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Čítanie"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Zapisovanie"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Overovanie"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Mazanie"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Uvoľňuje sa"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "Pripája sa"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Pridané"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Odstránené"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Zmenené"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Zrušené"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Názov"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Šifra"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Oblasť"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Nájdené"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Protokol"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Stav"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Neznáme: prístup zamietnutý"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Sériové číslo"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Režim"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Stav"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Veľkosť prenosu"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Neobvyklé požiadavky"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Skonvertuje firmvér do formátu DFU"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Zlúči viacero súborov s firmvérami do jedného"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Nastaví ID výrobcu pre súbor s firmvérom"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Nastaví ID produktu pre súbor s firmvérom"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Nastaví verziu vydania pre súbor s firmvérom"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Nastaví alternatívne číslo pre súbor s firmvérom"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Nastaví alternatívny názov pre súbor s firmvérom"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Zavedie zariadenie DFU späť do prevádzky"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Prečíta firmvér zo zariadenia do súboru"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Prečíta firmvér z jedného oddielu do súboru"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Zapíše firmvér zo súboru do zariadenia"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Zapíše firmvér zo súboru do jedného oddielu"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "Vypíše zoznam aktuálne pripojených zariadení DFU"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Odpojí aktuálne pripojené zariadenie DFU"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Zahodí podrobnosti o súbore s firmvérom"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Sleduje pripojenie zariadení DFU"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Zašifruje údaje firmvéru"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Dešifruje údaje firmvéru"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Nastaví metaúdaje pre súbor s firmvérom"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "Nástroj pre DFU"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Zlyhalo analyzovanie parametrov"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr "Zobrazí voľby ladenia"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Skončí po krátkom oneskorení"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Skončí po načítaní jadra"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Démon aktualizácie firmvéru"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Služba zbernice D-Bus na aktualizovanie firmvéru"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr ""
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr ""
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr ""
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr ""
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr ""
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr ""
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr ""
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr ""
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Nezistil sa žiadny hardvér s možnosťou aktualizácie firmvéru"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Skúša sa znovu ako aktualizácia bez pripojenia"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Preinštalováva sa %s verziou %s... "
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Vracia sa %s z verzie %s na verziu %s... "
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Aktualizuje sa %s z verzie %s na verziu %s... "
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Hotovo!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "OK"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Verzia"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Popis"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "Kontrolný medzisúčet"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "Pre zariadenie %s sú dostupné aktualizácie firmvéru:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Verzia aktualizácie"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Kontrolný medzisúčet aktualizácie"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Umiestnenie aktualizácie"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Popis aktualizácie"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Umiestnenie"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Pridané zariadenie:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Odstránené zariadenie:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "Zmenené zariadenie:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Zobrazovať dodatočné ladiace informácie"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Umožní preinštalovanie existujúcich vedzií firmvéru"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Umožní zníženie verzií firmvéru"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Získa všetky zariadenia, ktoré podporujú aktualizovanie firmvéru"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Nainštaluje pripravené aktualizácie ihneď"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Nainštaluje súbor firmvéru do tohoto hardvéru"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Získa podrobnosti o súbore firmvéru"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Získa zoznam aktualizácií pre pripojený hardvér"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Aktualizuje všetok firmvér na najnovšiu dostupnú verziu"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Získa kryptografický medzisúčet stiahnutého firmvéru"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "Odomkne zariadenie pre prístup k firmvéru"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Vymaže výsledky z poslednej aktualizácie"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Získa výsledky z poslednej aktualizácie"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Obnoví metaúdaje zo vzdialeného servera"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "Aktualizuje uložené metaúdaje s aktuálnym obsahom pamäte ROM"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "Sleduje démona kvôli udalostiam"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Nástroj pre firmvéry"
+184
-175
po/sr.po less more
99 msgstr ""
1010 "Project-Id-Version: fwupd\n"
1111 "Report-Msgid-Bugs-To: \n"
12 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
13 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
12 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
13 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1414 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1515 "Language-Team: Serbian (http://www.transifex.com/freedesktop/fwupd/language/sr/)\n"
1616 "MIME-Version: 1.0\n"
106106 "Authentication is required to update the stored checksums for the device"
107107 msgstr "Потребна је пријава за ажурирање причуваних сума провере за уређај"
108108
109 #: policy/org.freedesktop.fwupd.policy.in:105
110 msgid "Modify a configured remote"
111 msgstr ""
112
113 #. TRANSLATORS: this is the PolicyKit modal dialog
114 #: policy/org.freedesktop.fwupd.policy.in:107
115 msgid ""
116 "Authentication is required to modify a configured remote used for firmware "
117 "updates"
118 msgstr ""
119
109120 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
110 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
121 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
111122 #: src/fu-util.c:112
112123 #, c-format
113124 msgid "Alias to %s"
114125 msgstr "Алијас на %s"
115126
116127 #. TRANSLATORS: error message
117 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
128 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
118129 #: src/fu-util.c:176
119130 msgid "Command not found"
120131 msgstr "Наредба није пронађена"
121132
122 #. TRANSLATORS: read from device to host
123 #: libdfu/dfu-tool.c:1236
124 msgid "Reading"
125 msgstr "Читам"
126
127 #. TRANSLATORS: write from host to device
128 #: libdfu/dfu-tool.c:1242
129 msgid "Writing"
130 msgstr "Пишем"
131
132 #. TRANSLATORS: read from device to host
133 #: libdfu/dfu-tool.c:1248
134 msgid "Verifying"
135 msgstr "Проверавам"
136
137 #. TRANSLATORS: read from device to host
138 #: libdfu/dfu-tool.c:1254
139 msgid "Erasing"
140 msgstr "Бришем"
141
142 #. TRANSLATORS: waiting for device
143 #: libdfu/dfu-tool.c:1260
144 msgid "Detaching"
145 msgstr "Откачињем"
146
147 #. TRANSLATORS: waiting for device
148 #: libdfu/dfu-tool.c:1266
149 msgid "Attaching"
150 msgstr "Качим"
151
152133 #. TRANSLATORS: this is when a device is hotplugged
153 #: libdfu/dfu-tool.c:1487
134 #: plugins/dfu/dfu-tool.c:1440
154135 msgid "Added"
155136 msgstr "Додао"
156137
157138 #. TRANSLATORS: this is when a device is hotplugged
158 #: libdfu/dfu-tool.c:1498
139 #: plugins/dfu/dfu-tool.c:1451
159140 msgid "Removed"
160141 msgstr "Уклонио"
161142
162143 #. TRANSLATORS: this is when a device is hotplugged
163144 #. TRANSLATORS: this is when the daemon state changes
164 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
145 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
165146 msgid "Changed"
166147 msgstr "Променио"
167148
168149 #. TRANSLATORS: this is when a device ctrl+c's a watch
169 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
150 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
170151 msgid "Cancelled"
171152 msgstr "Отказао"
172153
173154 #. TRANSLATORS: Appstream ID for the hardware type
174 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
155 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
175156 msgid "ID"
176157 msgstr "ИБ"
177158
178159 #. TRANSLATORS: interface name, e.g. "Flash"
179160 #. TRANSLATORS: device name, e.g. 'ColorHug2'
180 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
161 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
162 #: plugins/dfu/dfu-tool.c:2065
181163 msgid "Name"
182164 msgstr "Назив"
183165
184166 #. TRANSLATORS: this is the encryption method used when writing
185 #: libdfu/dfu-tool.c:2043
167 #: plugins/dfu/dfu-tool.c:1985
186168 msgid "Cipher"
187169 msgstr "Шифрар"
188170
189171 #. TRANSLATORS: these are areas of memory on the chip
190 #: libdfu/dfu-tool.c:2057
172 #: plugins/dfu/dfu-tool.c:1999
191173 msgid "Region"
192174 msgstr "Област"
193175
194176 #. TRANSLATORS: detected a DFU device
195 #: libdfu/dfu-tool.c:2092
177 #: plugins/dfu/dfu-tool.c:2033
196178 msgid "Found"
197179 msgstr "Нашао"
198180
199181 #. TRANSLATORS: DFU protocol version, e.g. 1.1
200 #: libdfu/dfu-tool.c:2100
182 #: plugins/dfu/dfu-tool.c:2041
201183 msgid "Protocol"
202184 msgstr "Протокол"
203185
204186 #. TRANSLATORS: probably not run as root...
205187 #. TRANSLATORS: device has failed to report status
206188 #. TRANSLATORS: device status, e.g. "OK"
207 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
189 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
190 #: plugins/dfu/dfu-tool.c:2080
208191 msgid "Status"
209192 msgstr "Статус"
210193
211 #: libdfu/dfu-tool.c:2112
194 #: plugins/dfu/dfu-tool.c:2054
212195 msgid "Unknown: permission denied"
213196 msgstr "Непознато: приступ одбијен"
214197
215198 #. TRANSLATORS: serial number, e.g. '00012345'
216 #: libdfu/dfu-tool.c:2129
199 #: plugins/dfu/dfu-tool.c:2071
217200 msgid "Serial"
218201 msgstr "Серијски"
219202
220203 #. TRANSLATORS: device mode, e.g. runtime or DFU
221 #: libdfu/dfu-tool.c:2134
204 #: plugins/dfu/dfu-tool.c:2076
222205 msgid "Mode"
223206 msgstr "Режим"
224207
225208 #. TRANSLATORS: device state, i.e. appIDLE
226 #: libdfu/dfu-tool.c:2142
209 #: plugins/dfu/dfu-tool.c:2084
227210 msgid "State"
228211 msgstr "Стање"
229212
230213 #. TRANSLATORS: transfer size in bytes
231 #: libdfu/dfu-tool.c:2150
214 #: plugins/dfu/dfu-tool.c:2092
232215 msgid "Transfer Size"
233216 msgstr "Величина преноса"
234217
235218 #. TRANSLATORS: device quirks, i.e. things that
236219 #. * it does that we have to work around
237 #: libdfu/dfu-tool.c:2158
220 #: plugins/dfu/dfu-tool.c:2100
238221 msgid "Quirks"
239222 msgstr "Непрецизности"
240223
241224 #. TRANSLATORS: command description
242 #: libdfu/dfu-tool.c:2237
225 #: plugins/dfu/dfu-tool.c:2181
243226 msgid "Convert firmware to DFU format"
244227 msgstr "Претвори фирмвер у ДФУ формат"
245228
246229 #. TRANSLATORS: command description
247 #: libdfu/dfu-tool.c:2243
230 #: plugins/dfu/dfu-tool.c:2187
248231 msgid "Merge multiple firmware files into one"
249232 msgstr "Споји више датотека са фирмвером у једну"
250233
251234 #. TRANSLATORS: command description
252 #: libdfu/dfu-tool.c:2249
235 #: plugins/dfu/dfu-tool.c:2193
253236 msgid "Set vendor ID on firmware file"
254237 msgstr "Подеси ИБ продавца на датотеци са фирмвером"
255238
256239 #. TRANSLATORS: command description
257 #: libdfu/dfu-tool.c:2255
240 #: plugins/dfu/dfu-tool.c:2199
258241 msgid "Set product ID on firmware file"
259242 msgstr "Подеси ИБ производа на датотеци са фирмвером"
260243
261244 #. TRANSLATORS: command description
262 #: libdfu/dfu-tool.c:2261
245 #: plugins/dfu/dfu-tool.c:2205
263246 msgid "Set element address on firmware file"
264247 msgstr "Подешава адресу елемента на датотеци фирмвера"
265248
266249 #. TRANSLATORS: command description
267 #: libdfu/dfu-tool.c:2267
250 #: plugins/dfu/dfu-tool.c:2211
268251 msgid "Set the firmware size for the target"
269252 msgstr "Подешава величину фирмвера за мету"
270253
271254 #. TRANSLATORS: command description
272 #: libdfu/dfu-tool.c:2273
255 #: plugins/dfu/dfu-tool.c:2217
273256 msgid "Set release version on firmware file"
274257 msgstr "Подеси издање објаве на датотеци са фирмвером"
275258
276259 #. TRANSLATORS: command description
277 #: libdfu/dfu-tool.c:2279
260 #: plugins/dfu/dfu-tool.c:2223
278261 msgid "Set alternative number on firmware file"
279262 msgstr "Подеси алтернативни број на датотеци са фирмвером"
280263
281264 #. TRANSLATORS: command description
282 #: libdfu/dfu-tool.c:2285
265 #: plugins/dfu/dfu-tool.c:2229
283266 msgid "Set alternative name on firmware file"
284267 msgstr "Подеси алтернативно име на датотеци са фирмвером"
285268
286269 #. TRANSLATORS: command description
287 #: libdfu/dfu-tool.c:2291
270 #: plugins/dfu/dfu-tool.c:2235
288271 msgid "Attach DFU capable device back to runtime"
289272 msgstr "Закачи уређај способан за ДФУ назад на извршно окружење"
290273
291274 #. TRANSLATORS: command description
292 #: libdfu/dfu-tool.c:2297
275 #: plugins/dfu/dfu-tool.c:2241
293276 msgid "Read firmware from device into a file"
294277 msgstr "Исчитај фирмвер са уређаја у датотеку"
295278
296279 #. TRANSLATORS: command description
297 #: libdfu/dfu-tool.c:2303
280 #: plugins/dfu/dfu-tool.c:2247
298281 msgid "Read firmware from one partition into a file"
299282 msgstr "Исчитај фирмвер са једне партиције у датотеку"
300283
301284 #. TRANSLATORS: command description
302 #: libdfu/dfu-tool.c:2309
285 #: plugins/dfu/dfu-tool.c:2253
303286 msgid "Write firmware from file into device"
304287 msgstr "Упиши фирмвер из датотеке у уређај"
305288
306289 #. TRANSLATORS: command description
307 #: libdfu/dfu-tool.c:2315
290 #: plugins/dfu/dfu-tool.c:2259
308291 msgid "Write firmware from file into one partition"
309292 msgstr "Упиши фирмвер из датотеке у једну партицију"
310293
311294 #. TRANSLATORS: command description
312 #: libdfu/dfu-tool.c:2321
295 #: plugins/dfu/dfu-tool.c:2265
313296 msgid "List currently attached DFU capable devices"
314297 msgstr "Прикажи списак закачених уређаја способних за ДФУ"
315298
316299 #. TRANSLATORS: command description
317 #: libdfu/dfu-tool.c:2327
300 #: plugins/dfu/dfu-tool.c:2271
318301 msgid "Detach currently attached DFU capable device"
319302 msgstr "Откачи тренутно закачен уређај способан за ДФУ"
320303
321304 #. TRANSLATORS: command description
322 #: libdfu/dfu-tool.c:2333
305 #: plugins/dfu/dfu-tool.c:2277
323306 msgid "Dump details about a firmware file"
324307 msgstr "Истовари детаље о датотеци са фирмвером"
325308
326309 #. TRANSLATORS: command description
327 #: libdfu/dfu-tool.c:2339
310 #: plugins/dfu/dfu-tool.c:2283
328311 msgid "Watch DFU devices being hotplugged"
329312 msgstr "Надгледај ДФУ уређаје док се каче на живо"
330313
331314 #. TRANSLATORS: command description
332 #: libdfu/dfu-tool.c:2345
315 #: plugins/dfu/dfu-tool.c:2289
333316 msgid "Encrypt firmware data"
334317 msgstr "Шифруј податке у фирмверу"
335318
336319 #. TRANSLATORS: command description
337 #: libdfu/dfu-tool.c:2351
320 #: plugins/dfu/dfu-tool.c:2295
338321 msgid "Decrypt firmware data"
339322 msgstr "Дешифруј податке у фирмверу"
340323
341324 #. TRANSLATORS: command description
342 #: libdfu/dfu-tool.c:2357
325 #: plugins/dfu/dfu-tool.c:2301
343326 msgid "Sets metadata on a firmware file"
344327 msgstr "Подешава метаподатке у датотеци фирмвера"
345328
346329 #. TRANSLATORS: command description
347 #: libdfu/dfu-tool.c:2363
330 #: plugins/dfu/dfu-tool.c:2307
348331 msgid "Replace data in an existing firmware file"
349332 msgstr "Замењује податке у постојећој датотеци фирмвера"
350333
351334 #. TRANSLATORS: command description
352 #: libdfu/dfu-tool.c:2369
335 #: plugins/dfu/dfu-tool.c:2313
353336 msgid "Create a binary patch using two files"
354337 msgstr ""
355338
356339 #. TRANSLATORS: command description
357 #: libdfu/dfu-tool.c:2375
340 #: plugins/dfu/dfu-tool.c:2319
358341 msgid "Apply a binary patch"
359342 msgstr ""
360343
361344 #. TRANSLATORS: command description
362 #: libdfu/dfu-tool.c:2381
345 #: plugins/dfu/dfu-tool.c:2325
363346 msgid "Dump information about a binary patch to the screen"
364347 msgstr ""
365348
366349 #. TRANSLATORS: DFU stands for device firmware update
367 #: libdfu/dfu-tool.c:2407
350 #: plugins/dfu/dfu-tool.c:2351
368351 msgid "DFU Utility"
369352 msgstr "ДФУ алатка"
370353
371354 #. TRANSLATORS: the user didn't read the man page
372 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
373 #: src/fu-util.c:1733
355 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
356 #: src/fu-util.c:1778
374357 msgid "Failed to parse arguments"
375358 msgstr "Не могу да обрадим аргументе"
376359
377360 #. TRANSLATORS: command description
378 #: plugins/synapticsmst/synapticsmst-tool.c:408
361 #: plugins/synapticsmst/synapticsmst-tool.c:400
379362 msgid "Enumerate all Synaptics MST devices"
380363 msgstr "Набраја све МСТ уређаје Синаптика"
381364
382365 #. TRANSLATORS: command description
383 #: plugins/synapticsmst/synapticsmst-tool.c:414
366 #: plugins/synapticsmst/synapticsmst-tool.c:406
384367 msgid "Flash firmware file to MST device"
385368 msgstr "Флешује датотеку фирмвера на МСТ уређај"
386369
387 #: plugins/synapticsmst/synapticsmst-tool.c:434
370 #: plugins/synapticsmst/synapticsmst-tool.c:426
388371 msgid "Synaptics Multistream Transport Utility"
389372 msgstr "Синаптикова вишетоковна алатка преноса"
390373
391374 #. TRANSLATORS: this is shown when updating the firmware after the reboot
392 #: plugins/uefi/fu-plugin-uefi.c:194
375 #: plugins/uefi/fu-plugin-uefi.c:396
393376 msgid "Installing firmware update…"
394377 msgstr "Инсталирам ажурирање фирмвера…"
395378
409392 msgstr "Прикажи опције за отклањање проблема"
410393
411394 #. TRANSLATORS: exit after we've started up, used for user profiling
412 #: src/fu-main.c:863
395 #: src/fu-main.c:960
413396 msgid "Exit after a small delay"
414397 msgstr "Изађи након малог застоја"
415398
416399 #. TRANSLATORS: exit straight away, used for automatic profiling
417 #: src/fu-main.c:866
400 #: src/fu-main.c:963
418401 msgid "Exit after the engine has loaded"
419402 msgstr "Изађи након учитавања мотора"
420403
421404 #. TRANSLATORS: program name
422 #: src/fu-main.c:880
405 #: src/fu-main.c:977
423406 msgid "Firmware Update Daemon"
424407 msgstr "Демон за ажурирање фирмвера"
425408
426409 #. TRANSLATORS: program summary
427 #: src/fu-main.c:885
410 #: src/fu-main.c:982
428411 msgid "Firmware Update D-Bus Service"
429412 msgstr "Д-Бус услуга ажурирања фирмвера"
430413
431414 #. TRANSLATORS: daemon is inactive
432 #: src/fu-progressbar.c:51
415 #: src/fu-progressbar.c:52
433416 msgid "Idle…"
434417 msgstr "Мирујем…"
435418
436419 #. TRANSLATORS: decompressing the firmware file
437 #: src/fu-progressbar.c:55
420 #: src/fu-progressbar.c:56
438421 msgid "Decompressing…"
439422 msgstr "Распакујем…"
440423
441424 #. TRANSLATORS: parsing the firmware information
442 #: src/fu-progressbar.c:59
425 #: src/fu-progressbar.c:60
443426 msgid "Loading…"
444427 msgstr "Учитавам…"
445428
446429 #. TRANSLATORS: restarting the device to pick up new F/W
447 #: src/fu-progressbar.c:63
430 #: src/fu-progressbar.c:64
448431 msgid "Restarting device…"
449432 msgstr "Поново покрећем уређај…"
450433
434 #. TRANSLATORS: reading from the flash chips
435 #: src/fu-progressbar.c:68
436 msgid "Reading…"
437 msgstr ""
438
451439 #. TRANSLATORS: writing to the flash chips
452 #: src/fu-progressbar.c:67
440 #: src/fu-progressbar.c:72
453441 msgid "Writing…"
454442 msgstr "Пишем…"
455443
444 #. TRANSLATORS: erasing contents of the flash chips
445 #: src/fu-progressbar.c:76
446 msgid "Erasing…"
447 msgstr ""
448
456449 #. TRANSLATORS: verifying we wrote the firmware correctly
457 #: src/fu-progressbar.c:71
450 #: src/fu-progressbar.c:80
458451 msgid "Verifying…"
459452 msgstr "Проверавам…"
460453
461454 #. TRANSLATORS: scheduing an update to be done on the next boot
462 #: src/fu-progressbar.c:75
455 #: src/fu-progressbar.c:84
463456 msgid "Scheduling…"
464457 msgstr "Заказујем…"
465458
466459 #. TRANSLATORS: downloading from a remote server
467 #: src/fu-progressbar.c:79
460 #: src/fu-progressbar.c:88
468461 msgid "Downloading…"
469462 msgstr "Преузимам…"
470463
464 #. TRANSLATORS: waiting for user to authenticate
465 #: src/fu-progressbar.c:92
466 msgid "Authenticating…"
467 msgstr ""
468
471469 #. TRANSLATORS: currect daemon status is unknown
472 #: src/fu-progressbar.c:86
470 #: src/fu-progressbar.c:99
473471 msgid "Unknown"
474472 msgstr "Непознато"
475473
489487 msgid "No hardware detected with firmware update capability"
490488 msgstr "Нема хардвера којем се може ажурирати фирмвер"
491489
492 #. TRANSLATOR: the plugin only supports offline
493 #: src/fu-util.c:337
494 msgid "Retrying as an offline update"
495 msgstr "Поново покушавам преко ванмрежног ажурирања"
496
497490 #. TRANSLATORS: the first replacement is a display name
498491 #. * e.g. "ColorHugALS" and the second is a version number
499492 #. * e.g. "1.2.3"
500 #: src/fu-util.c:501
493 #: src/fu-util.c:474
501494 #, c-format
502495 msgid "Reinstalling %s with %s... "
503496 msgstr "Поново инсталирам %s са %s..."
505498 #. TRANSLATORS: the first replacement is a display name
506499 #. * e.g. "ColorHugALS" and the second and third are
507500 #. * version numbers e.g. "1.2.3"
508 #: src/fu-util.c:508
501 #: src/fu-util.c:481
509502 #, c-format
510503 msgid "Downgrading %s from %s to %s... "
511504 msgstr "Уназађујем %s са %s на %s..."
513506 #. TRANSLATORS: the first replacement is a display name
514507 #. * e.g. "ColorHugALS" and the second and third are
515508 #. * version numbers e.g. "1.2.3"
516 #: src/fu-util.c:516
509 #: src/fu-util.c:489
517510 #, c-format
518511 msgid "Updating %s from %s to %s... "
519512 msgstr "Ажурирам %s са %s на %s..."
520513
521 #: src/fu-util.c:543
514 #: src/fu-util.c:516
522515 msgid "Done!"
523516 msgstr "Урађено!"
524517
525 #: src/fu-util.c:585 src/fu-util.c:985
518 #: src/fu-util.c:565 src/fu-util.c:978
526519 msgid "OK"
527520 msgstr "У реду"
528521
529522 #. TRANSLATORS: downloading new signing file
530 #: src/fu-util.c:719
523 #: src/fu-util.c:699
531524 msgid "Fetching signature"
532525 msgstr "Добављам потпис"
533526
534527 #. TRANSLATORS: downloading new metadata file
535 #: src/fu-util.c:722
528 #: src/fu-util.c:702
536529 msgid "Fetching metadata"
537530 msgstr "Добављам мета-податке"
538531
539532 #. TRANSLATORS: downloading new firmware file
540 #: src/fu-util.c:725
533 #: src/fu-util.c:705
541534 msgid "Fetching firmware"
542535 msgstr "Добављам фирмвер"
543536
544537 #. TRANSLATORS: downloading unknown file
545 #: src/fu-util.c:728
538 #: src/fu-util.c:708
546539 msgid "Fetching file"
547540 msgstr "Добављам датотеку"
548541
549542 #. TRANSLATORS: section header for release version number
550 #: src/fu-util.c:898
543 #: src/fu-util.c:888
551544 msgid "Version"
552545 msgstr "Издање"
553546
547 #. TRANSLATORS: section header for the remote the file is coming from
548 #: src/fu-util.c:891
549 msgid "Remote"
550 msgstr ""
551
554552 #. TRANSLATORS: section header for firmware URI
555 #: src/fu-util.c:901
553 #: src/fu-util.c:894
556554 msgid "URI"
557555 msgstr "УРИ"
558556
559557 #. TRANSLATORS: section header for firmware description
560 #: src/fu-util.c:907
558 #: src/fu-util.c:900
561559 msgid "Description"
562560 msgstr "Опис"
563561
564562 #. TRANSLATORS: section header for firmware checksum
565 #: src/fu-util.c:915
563 #. TRANSLATORS: remote checksum
564 #: src/fu-util.c:908 src/fu-util.c:1136
566565 msgid "Checksum"
567566 msgstr "Чек-сума"
568567
569568 #. TRANSLATORS: get interactive prompt
570 #: src/fu-util.c:947
569 #: src/fu-util.c:940
571570 msgid "Choose a release:"
572571 msgstr "Изаберите издање:"
573572
574573 #. TRANSLATORS: first replacement is device name
575 #: src/fu-util.c:1036
574 #: src/fu-util.c:1041
576575 #, c-format
577576 msgid "%s has firmware updates:"
578577 msgstr "%s има ажурирања за фирмвер:"
579578
580 #: src/fu-util.c:1046
579 #: src/fu-util.c:1048
581580 msgid "GUID"
582581 msgstr "ГУИД"
583582
584583 #. TRANSLATORS: section header for firmware version
585 #: src/fu-util.c:1050
584 #: src/fu-util.c:1060
586585 msgid "Update Version"
587586 msgstr "Верзија ажурирања"
588587
589588 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
590 #: src/fu-util.c:1054
589 #: src/fu-util.c:1064
591590 msgid "Update Remote ID"
592591 msgstr "ИБ удаљене исправке"
593592
594593 #. TRANSLATORS: section header for firmware checksum
595 #: src/fu-util.c:1063
594 #: src/fu-util.c:1073
596595 msgid "Update Checksum"
597596 msgstr "Сума провере ажурирања"
598597
599598 #. TRANSLATORS: section header for firmware remote http://
600 #: src/fu-util.c:1067
599 #: src/fu-util.c:1077
601600 msgid "Update Location"
602601 msgstr "Место ажурирања"
603602
604603 #. TRANSLATORS: section header for long firmware desc
605 #: src/fu-util.c:1078
604 #: src/fu-util.c:1088
606605 msgid "Update Description"
607606 msgstr "Опис ажурирања"
608607
609608 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
610 #: src/fu-util.c:1104
609 #: src/fu-util.c:1114
611610 msgid "Remote ID"
612611 msgstr "Удаљени ИБ"
613612
613 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
614 #: src/fu-util.c:1118
615 msgid "Title"
616 msgstr ""
617
614618 #. TRANSLATORS: remote type, e.g. remote or local
615 #: src/fu-util.c:1108
619 #: src/fu-util.c:1122
616620 msgid "Type"
617621 msgstr ""
618622
619 #: src/fu-util.c:1113
623 #: src/fu-util.c:1127
620624 msgid "Keyring"
621625 msgstr ""
622626
623627 #. TRANSLATORS: if the remote is enabled
624 #: src/fu-util.c:1118
628 #: src/fu-util.c:1132
625629 msgid "Enabled"
626630 msgstr "Омогућено"
627631
628632 #. TRANSLATORS: the age of the metadata
629 #: src/fu-util.c:1145
633 #: src/fu-util.c:1163
630634 msgid "Age"
631635 msgstr "Старост"
632636
633637 #. TRANSLATORS: the numeric priority
634 #: src/fu-util.c:1152
638 #: src/fu-util.c:1170
635639 msgid "Priority"
636640 msgstr "Важност"
637641
638642 #. TRANSLATORS: remote filename base
639 #: src/fu-util.c:1157
643 #: src/fu-util.c:1175
640644 msgid "Username"
641645 msgstr "Корисничко име"
642646
643647 #. TRANSLATORS: remote filename base
644 #: src/fu-util.c:1162
648 #: src/fu-util.c:1180
645649 msgid "Password"
646650 msgstr "Лозинка"
647651
648 #. TRANSLATORS: remote filename base
649 #: src/fu-util.c:1167
652 #. TRANSLATORS: filename of the local file
653 #: src/fu-util.c:1185
650654 msgid "Filename"
651655 msgstr "Назив датотеке"
652656
653 #. TRANSLATORS: remote filename base
654 #: src/fu-util.c:1172
657 #. TRANSLATORS: filename of the local file
658 #: src/fu-util.c:1190
655659 msgid "Filename Signature"
656660 msgstr "Потпис назива датотеке"
657661
658 #. TRANSLATORS: locatation of the local file
659 #: src/fu-util.c:1177
660 msgid "Location"
661 msgstr "Место"
662
663 #. TRANSLATORS: locatation of the local file
664 #: src/fu-util.c:1182
665 msgid "Location Signature"
666 msgstr ""
667
668662 #. TRANSLATORS: remote URI
669 #: src/fu-util.c:1187
663 #: src/fu-util.c:1195
670664 msgid "Metadata URI"
671665 msgstr ""
672666
673667 #. TRANSLATORS: remote URI
674 #: src/fu-util.c:1192
668 #: src/fu-util.c:1200
675669 msgid "Metadata URI Signature"
676670 msgstr ""
677671
678672 #. TRANSLATORS: remote URI
679 #: src/fu-util.c:1197
673 #: src/fu-util.c:1205
680674 msgid "Firmware Base URI"
681675 msgstr ""
682676
683677 #. TRANSLATORS: this is when a device is hotplugged
684 #: src/fu-util.c:1224
678 #: src/fu-util.c:1232
685679 msgid "Device added:"
686680 msgstr "Додат је уређај:"
687681
688682 #. TRANSLATORS: this is when a device is hotplugged
689 #: src/fu-util.c:1234
683 #: src/fu-util.c:1242
690684 msgid "Device removed:"
691685 msgstr "Уклоњен је уређај:"
692686
693687 #. TRANSLATORS: this is when a device has been updated
694 #: src/fu-util.c:1244
688 #: src/fu-util.c:1252
695689 msgid "Device changed:"
696690 msgstr "Промењен је уређај:"
697691
698692 #. TRANSLATORS: command line option
699 #: src/fu-util.c:1568
693 #: src/fu-util.c:1595
700694 msgid "Show extra debugging information"
701695 msgstr "Прикажи додатне податке за отклањање проблема"
702696
703697 #. TRANSLATORS: command line option
704 #: src/fu-util.c:1571
698 #: src/fu-util.c:1598
705699 msgid "Show client and daemon versions"
706700 msgstr ""
707701
708702 #. TRANSLATORS: command line option
709 #: src/fu-util.c:1574
703 #: src/fu-util.c:1601
710704 msgid "Schedule installation for next reboot when possible"
711705 msgstr "Заказује инсталирање за следеће подизање система када је могуће"
712706
713707 #. TRANSLATORS: command line option
714 #: src/fu-util.c:1577
708 #: src/fu-util.c:1604
715709 msgid "Allow re-installing existing firmware versions"
716710 msgstr "Дозволи поновно инсталирање већ постојећих издања фирмвера"
717711
718712 #. TRANSLATORS: command line option
719 #: src/fu-util.c:1580
713 #: src/fu-util.c:1607
720714 msgid "Allow downgrading firmware versions"
721715 msgstr "Дозволи уназађивање издања фирмвера"
722716
723717 #. TRANSLATORS: command line option
724 #: src/fu-util.c:1583
718 #: src/fu-util.c:1610
725719 msgid "Override plugin warning"
726720 msgstr "Превазилази упозорења прикључка"
727721
728722 #. TRANSLATORS: command description
729 #: src/fu-util.c:1607
723 #: src/fu-util.c:1634
730724 msgid "Get all devices that support firmware updates"
731725 msgstr "Добави све уређаје који подржавају ажурирање фирмвера"
732726
733727 #. TRANSLATORS: command description
734 #: src/fu-util.c:1613
728 #: src/fu-util.c:1640
735729 msgid "Return all the hardware IDs for the machine"
736730 msgstr "Враћа све ИБ-јеве хардвера на машини"
737731
738732 #. TRANSLATORS: command description
739 #: src/fu-util.c:1619
733 #: src/fu-util.c:1646
740734 msgid "Install prepared updates now"
741735 msgstr "Инсталирај припремљена ажурирања сад"
742736
743737 #. TRANSLATORS: command description
744 #: src/fu-util.c:1625
738 #: src/fu-util.c:1652
745739 msgid "Install a firmware file on this hardware"
746740 msgstr "Инсталирај датотеку са фирмвером на овај уређај"
747741
748742 #. TRANSLATORS: command description
749 #: src/fu-util.c:1631
743 #: src/fu-util.c:1658
750744 msgid "Gets details about a firmware file"
751745 msgstr "Добави појединости о датотеци са фирмвером"
752746
753747 #. TRANSLATORS: command description
754 #: src/fu-util.c:1637
748 #: src/fu-util.c:1664
755749 msgid "Gets the list of updates for connected hardware"
756750 msgstr "Добави списак свих ажурирања за повезани уређај"
757751
758752 #. TRANSLATORS: command description
759 #: src/fu-util.c:1643
753 #: src/fu-util.c:1670
760754 msgid "Updates all firmware to latest versions available"
761755 msgstr "Ажурира сав фирмвер на последња доступна издања"
762756
763757 #. TRANSLATORS: command description
764 #: src/fu-util.c:1649
758 #: src/fu-util.c:1676
765759 msgid "Gets the cryptographic hash of the dumped firmware"
766760 msgstr "Добавља криптографски хеш извађеног фирмвера"
767761
768762 #. TRANSLATORS: command description
769 #: src/fu-util.c:1655
763 #: src/fu-util.c:1682
770764 msgid "Unlocks the device for firmware access"
771765 msgstr "Откључава уређај за приступ фирмверу"
772766
773767 #. TRANSLATORS: command description
774 #: src/fu-util.c:1661
768 #: src/fu-util.c:1688
775769 msgid "Clears the results from the last update"
776770 msgstr "Чисти резултате последњег ажурирања"
777771
778772 #. TRANSLATORS: command description
779 #: src/fu-util.c:1667
773 #: src/fu-util.c:1694
774 msgid "Clears any updates scheduled to be updated offline"
775 msgstr ""
776
777 #. TRANSLATORS: command description
778 #: src/fu-util.c:1700
780779 msgid "Gets the results from the last update"
781780 msgstr "Добавља резултате последњег ажурирања"
782781
783782 #. TRANSLATORS: command description
784 #: src/fu-util.c:1673
783 #: src/fu-util.c:1706
785784 msgid "Gets the releases for a device"
786785 msgstr "Добавља издања за уређај"
787786
788787 #. TRANSLATORS: command description
789 #: src/fu-util.c:1679
788 #: src/fu-util.c:1712
790789 msgid "Gets the configured remotes"
791790 msgstr "Добавља подешена удаљена места"
792791
793792 #. TRANSLATORS: command description
794 #: src/fu-util.c:1685
793 #: src/fu-util.c:1718
795794 msgid "Downgrades the firmware on a device"
796795 msgstr "Уназађује фирмвер на уређају"
797796
798797 #. TRANSLATORS: command description
799 #: src/fu-util.c:1691
798 #: src/fu-util.c:1724
800799 msgid "Refresh metadata from remote server"
801800 msgstr "Освежава метаподатке са удаљеног сервера"
802801
803802 #. TRANSLATORS: command description
804 #: src/fu-util.c:1697
803 #: src/fu-util.c:1730
805804 msgid "Update the stored metadata with current ROM contents"
806805 msgstr "Ажурирај ускладиштене метаподатке са тренутним садржајима РОМ-а"
807806
808807 #. TRANSLATORS: command description
809 #: src/fu-util.c:1703
808 #: src/fu-util.c:1736
810809 msgid "Monitor the daemon for events"
811810 msgstr "Прати демона за догађајима"
812811
813812 #. TRANSLATORS: command description
814 #: src/fu-util.c:1709
813 #: src/fu-util.c:1742
815814 msgid "Build firmware using a sandbox"
816815 msgstr ""
817816
817 #. TRANSLATORS: command description
818 #: src/fu-util.c:1748
819 msgid "Dump SMBIOS data from a file"
820 msgstr ""
821
822 #. TRANSLATORS: command description
823 #: src/fu-util.c:1754
824 msgid "Modifies a given remote"
825 msgstr ""
826
818827 #. TRANSLATORS: program name
819 #: src/fu-util.c:1728
828 #: src/fu-util.c:1773
820829 msgid "Firmware Utility"
821830 msgstr "Алатка за фирмвер"
+184
-175
po/sv.po less more
99 msgstr ""
1010 "Project-Id-Version: fwupd\n"
1111 "Report-Msgid-Bugs-To: \n"
12 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
13 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
12 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
13 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1414 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1515 "Language-Team: Swedish (http://www.transifex.com/freedesktop/fwupd/language/sv/)\n"
1616 "MIME-Version: 1.0\n"
106106 "Authentication is required to update the stored checksums for the device"
107107 msgstr "Autentisering krävs för att uppdatera den lagrade kontrollsumman för enheten"
108108
109 #: policy/org.freedesktop.fwupd.policy.in:105
110 msgid "Modify a configured remote"
111 msgstr ""
112
113 #. TRANSLATORS: this is the PolicyKit modal dialog
114 #: policy/org.freedesktop.fwupd.policy.in:107
115 msgid ""
116 "Authentication is required to modify a configured remote used for firmware "
117 "updates"
118 msgstr ""
119
109120 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
110 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
121 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
111122 #: src/fu-util.c:112
112123 #, c-format
113124 msgid "Alias to %s"
114125 msgstr "Alias för %s"
115126
116127 #. TRANSLATORS: error message
117 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
128 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
118129 #: src/fu-util.c:176
119130 msgid "Command not found"
120131 msgstr "Kommandot hittades inte"
121132
122 #. TRANSLATORS: read from device to host
123 #: libdfu/dfu-tool.c:1236
124 msgid "Reading"
125 msgstr "Läser"
126
127 #. TRANSLATORS: write from host to device
128 #: libdfu/dfu-tool.c:1242
129 msgid "Writing"
130 msgstr "Skriver"
131
132 #. TRANSLATORS: read from device to host
133 #: libdfu/dfu-tool.c:1248
134 msgid "Verifying"
135 msgstr "Verifierar"
136
137 #. TRANSLATORS: read from device to host
138 #: libdfu/dfu-tool.c:1254
139 msgid "Erasing"
140 msgstr "Tar bort"
141
142 #. TRANSLATORS: waiting for device
143 #: libdfu/dfu-tool.c:1260
144 msgid "Detaching"
145 msgstr "Kopplar från"
146
147 #. TRANSLATORS: waiting for device
148 #: libdfu/dfu-tool.c:1266
149 msgid "Attaching"
150 msgstr "Fäster"
151
152133 #. TRANSLATORS: this is when a device is hotplugged
153 #: libdfu/dfu-tool.c:1487
134 #: plugins/dfu/dfu-tool.c:1440
154135 msgid "Added"
155136 msgstr "Tillagd"
156137
157138 #. TRANSLATORS: this is when a device is hotplugged
158 #: libdfu/dfu-tool.c:1498
139 #: plugins/dfu/dfu-tool.c:1451
159140 msgid "Removed"
160141 msgstr "Borttagen"
161142
162143 #. TRANSLATORS: this is when a device is hotplugged
163144 #. TRANSLATORS: this is when the daemon state changes
164 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
145 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
165146 msgid "Changed"
166147 msgstr "Ändrad"
167148
168149 #. TRANSLATORS: this is when a device ctrl+c's a watch
169 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
150 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
170151 msgid "Cancelled"
171152 msgstr "Avbruten"
172153
173154 #. TRANSLATORS: Appstream ID for the hardware type
174 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
155 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
175156 msgid "ID"
176157 msgstr "ID"
177158
178159 #. TRANSLATORS: interface name, e.g. "Flash"
179160 #. TRANSLATORS: device name, e.g. 'ColorHug2'
180 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
161 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
162 #: plugins/dfu/dfu-tool.c:2065
181163 msgid "Name"
182164 msgstr "Namn"
183165
184166 #. TRANSLATORS: this is the encryption method used when writing
185 #: libdfu/dfu-tool.c:2043
167 #: plugins/dfu/dfu-tool.c:1985
186168 msgid "Cipher"
187169 msgstr "Chiffer"
188170
189171 #. TRANSLATORS: these are areas of memory on the chip
190 #: libdfu/dfu-tool.c:2057
172 #: plugins/dfu/dfu-tool.c:1999
191173 msgid "Region"
192174 msgstr "Område"
193175
194176 #. TRANSLATORS: detected a DFU device
195 #: libdfu/dfu-tool.c:2092
177 #: plugins/dfu/dfu-tool.c:2033
196178 msgid "Found"
197179 msgstr "Hittad"
198180
199181 #. TRANSLATORS: DFU protocol version, e.g. 1.1
200 #: libdfu/dfu-tool.c:2100
182 #: plugins/dfu/dfu-tool.c:2041
201183 msgid "Protocol"
202184 msgstr "Protokoll"
203185
204186 #. TRANSLATORS: probably not run as root...
205187 #. TRANSLATORS: device has failed to report status
206188 #. TRANSLATORS: device status, e.g. "OK"
207 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
189 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
190 #: plugins/dfu/dfu-tool.c:2080
208191 msgid "Status"
209192 msgstr "Status"
210193
211 #: libdfu/dfu-tool.c:2112
194 #: plugins/dfu/dfu-tool.c:2054
212195 msgid "Unknown: permission denied"
213196 msgstr "Okänd: behörighet nekad"
214197
215198 #. TRANSLATORS: serial number, e.g. '00012345'
216 #: libdfu/dfu-tool.c:2129
199 #: plugins/dfu/dfu-tool.c:2071
217200 msgid "Serial"
218201 msgstr "Serienr"
219202
220203 #. TRANSLATORS: device mode, e.g. runtime or DFU
221 #: libdfu/dfu-tool.c:2134
204 #: plugins/dfu/dfu-tool.c:2076
222205 msgid "Mode"
223206 msgstr "Läge"
224207
225208 #. TRANSLATORS: device state, i.e. appIDLE
226 #: libdfu/dfu-tool.c:2142
209 #: plugins/dfu/dfu-tool.c:2084
227210 msgid "State"
228211 msgstr "Tillstånd"
229212
230213 #. TRANSLATORS: transfer size in bytes
231 #: libdfu/dfu-tool.c:2150
214 #: plugins/dfu/dfu-tool.c:2092
232215 msgid "Transfer Size"
233216 msgstr "Överföringsstorlek"
234217
235218 #. TRANSLATORS: device quirks, i.e. things that
236219 #. * it does that we have to work around
237 #: libdfu/dfu-tool.c:2158
220 #: plugins/dfu/dfu-tool.c:2100
238221 msgid "Quirks"
239222 msgstr "Speciallösningar"
240223
241224 #. TRANSLATORS: command description
242 #: libdfu/dfu-tool.c:2237
225 #: plugins/dfu/dfu-tool.c:2181
243226 msgid "Convert firmware to DFU format"
244227 msgstr "Konvertera fast programvara till DFU-format"
245228
246229 #. TRANSLATORS: command description
247 #: libdfu/dfu-tool.c:2243
230 #: plugins/dfu/dfu-tool.c:2187
248231 msgid "Merge multiple firmware files into one"
249232 msgstr "Sammanfoga flera fasta programvaror till en"
250233
251234 #. TRANSLATORS: command description
252 #: libdfu/dfu-tool.c:2249
235 #: plugins/dfu/dfu-tool.c:2193
253236 msgid "Set vendor ID on firmware file"
254237 msgstr "Ange tillverkar-ID för den fasta programvarufilen"
255238
256239 #. TRANSLATORS: command description
257 #: libdfu/dfu-tool.c:2255
240 #: plugins/dfu/dfu-tool.c:2199
258241 msgid "Set product ID on firmware file"
259242 msgstr "Ange produkt-ID för den fasta programvarufilen"
260243
261244 #. TRANSLATORS: command description
262 #: libdfu/dfu-tool.c:2261
245 #: plugins/dfu/dfu-tool.c:2205
263246 msgid "Set element address on firmware file"
264247 msgstr "Ange elementadress för den fasta programvarufilen"
265248
266249 #. TRANSLATORS: command description
267 #: libdfu/dfu-tool.c:2267
250 #: plugins/dfu/dfu-tool.c:2211
268251 msgid "Set the firmware size for the target"
269252 msgstr "Ange fast programvarustorlek för målet"
270253
271254 #. TRANSLATORS: command description
272 #: libdfu/dfu-tool.c:2273
255 #: plugins/dfu/dfu-tool.c:2217
273256 msgid "Set release version on firmware file"
274257 msgstr "Ange utgåveversion för den fasta programvarufilen"
275258
276259 #. TRANSLATORS: command description
277 #: libdfu/dfu-tool.c:2279
260 #: plugins/dfu/dfu-tool.c:2223
278261 msgid "Set alternative number on firmware file"
279262 msgstr "Ange alternativ siffra för den fasta programvarufilen"
280263
281264 #. TRANSLATORS: command description
282 #: libdfu/dfu-tool.c:2285
265 #: plugins/dfu/dfu-tool.c:2229
283266 msgid "Set alternative name on firmware file"
284267 msgstr "Ange alternativt namn för den fasta programvarufilen"
285268
286269 #. TRANSLATORS: command description
287 #: libdfu/dfu-tool.c:2291
270 #: plugins/dfu/dfu-tool.c:2235
288271 msgid "Attach DFU capable device back to runtime"
289272 msgstr "Anslut DFU-kapabel enhet till körtid"
290273
291274 #. TRANSLATORS: command description
292 #: libdfu/dfu-tool.c:2297
275 #: plugins/dfu/dfu-tool.c:2241
293276 msgid "Read firmware from device into a file"
294277 msgstr "Läs fast programvara från enhet till fil"
295278
296279 #. TRANSLATORS: command description
297 #: libdfu/dfu-tool.c:2303
280 #: plugins/dfu/dfu-tool.c:2247
298281 msgid "Read firmware from one partition into a file"
299282 msgstr "Läs fast programvara från en partition till fil"
300283
301284 #. TRANSLATORS: command description
302 #: libdfu/dfu-tool.c:2309
285 #: plugins/dfu/dfu-tool.c:2253
303286 msgid "Write firmware from file into device"
304287 msgstr "Skriv fast programvara från fil till enhet"
305288
306289 #. TRANSLATORS: command description
307 #: libdfu/dfu-tool.c:2315
290 #: plugins/dfu/dfu-tool.c:2259
308291 msgid "Write firmware from file into one partition"
309292 msgstr "Skriv fast programvara från fil till partition"
310293
311294 #. TRANSLATORS: command description
312 #: libdfu/dfu-tool.c:2321
295 #: plugins/dfu/dfu-tool.c:2265
313296 msgid "List currently attached DFU capable devices"
314297 msgstr "Lista aktuella anslutna DFU-kapabla enheter"
315298
316299 #. TRANSLATORS: command description
317 #: libdfu/dfu-tool.c:2327
300 #: plugins/dfu/dfu-tool.c:2271
318301 msgid "Detach currently attached DFU capable device"
319302 msgstr "Koppla från anslutna DFU-kapabla enheter"
320303
321304 #. TRANSLATORS: command description
322 #: libdfu/dfu-tool.c:2333
305 #: plugins/dfu/dfu-tool.c:2277
323306 msgid "Dump details about a firmware file"
324307 msgstr "Skriv ut detaljer om fast programvarufil"
325308
326309 #. TRANSLATORS: command description
327 #: libdfu/dfu-tool.c:2339
310 #: plugins/dfu/dfu-tool.c:2283
328311 msgid "Watch DFU devices being hotplugged"
329312 msgstr "Övervaka anslutna DFU-enheter"
330313
331314 #. TRANSLATORS: command description
332 #: libdfu/dfu-tool.c:2345
315 #: plugins/dfu/dfu-tool.c:2289
333316 msgid "Encrypt firmware data"
334317 msgstr "Kryptera fast programvarudata"
335318
336319 #. TRANSLATORS: command description
337 #: libdfu/dfu-tool.c:2351
320 #: plugins/dfu/dfu-tool.c:2295
338321 msgid "Decrypt firmware data"
339322 msgstr "Dekryptera fast programvarudata"
340323
341324 #. TRANSLATORS: command description
342 #: libdfu/dfu-tool.c:2357
325 #: plugins/dfu/dfu-tool.c:2301
343326 msgid "Sets metadata on a firmware file"
344327 msgstr "Ange metadata på fast programvarufil"
345328
346329 #. TRANSLATORS: command description
347 #: libdfu/dfu-tool.c:2363
330 #: plugins/dfu/dfu-tool.c:2307
348331 msgid "Replace data in an existing firmware file"
349332 msgstr "Ersätt data i en befintlig fast programvarufil"
350333
351334 #. TRANSLATORS: command description
352 #: libdfu/dfu-tool.c:2369
335 #: plugins/dfu/dfu-tool.c:2313
353336 msgid "Create a binary patch using two files"
354337 msgstr ""
355338
356339 #. TRANSLATORS: command description
357 #: libdfu/dfu-tool.c:2375
340 #: plugins/dfu/dfu-tool.c:2319
358341 msgid "Apply a binary patch"
359342 msgstr ""
360343
361344 #. TRANSLATORS: command description
362 #: libdfu/dfu-tool.c:2381
345 #: plugins/dfu/dfu-tool.c:2325
363346 msgid "Dump information about a binary patch to the screen"
364347 msgstr ""
365348
366349 #. TRANSLATORS: DFU stands for device firmware update
367 #: libdfu/dfu-tool.c:2407
350 #: plugins/dfu/dfu-tool.c:2351
368351 msgid "DFU Utility"
369352 msgstr "DFU-verktyg"
370353
371354 #. TRANSLATORS: the user didn't read the man page
372 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
373 #: src/fu-util.c:1733
355 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
356 #: src/fu-util.c:1778
374357 msgid "Failed to parse arguments"
375358 msgstr "Misslyckades med att tolka argument"
376359
377360 #. TRANSLATORS: command description
378 #: plugins/synapticsmst/synapticsmst-tool.c:408
361 #: plugins/synapticsmst/synapticsmst-tool.c:400
379362 msgid "Enumerate all Synaptics MST devices"
380363 msgstr "Räkna upp alla Synaptic MST-enheter"
381364
382365 #. TRANSLATORS: command description
383 #: plugins/synapticsmst/synapticsmst-tool.c:414
366 #: plugins/synapticsmst/synapticsmst-tool.c:406
384367 msgid "Flash firmware file to MST device"
385368 msgstr "Skriv fast programvarufil till MST-enhet"
386369
387 #: plugins/synapticsmst/synapticsmst-tool.c:434
370 #: plugins/synapticsmst/synapticsmst-tool.c:426
388371 msgid "Synaptics Multistream Transport Utility"
389372 msgstr "Synaptics Multistream Transport-verktyg"
390373
391374 #. TRANSLATORS: this is shown when updating the firmware after the reboot
392 #: plugins/uefi/fu-plugin-uefi.c:194
375 #: plugins/uefi/fu-plugin-uefi.c:396
393376 msgid "Installing firmware update…"
394377 msgstr "Installerar uppdatering för fast programvara…"
395378
409392 msgstr "Visa felsökningsalternativ"
410393
411394 #. TRANSLATORS: exit after we've started up, used for user profiling
412 #: src/fu-main.c:863
395 #: src/fu-main.c:960
413396 msgid "Exit after a small delay"
414397 msgstr "Avsluta efter en kort fördröjning"
415398
416399 #. TRANSLATORS: exit straight away, used for automatic profiling
417 #: src/fu-main.c:866
400 #: src/fu-main.c:963
418401 msgid "Exit after the engine has loaded"
419402 msgstr "Avsluta efter att motorn har lästs in"
420403
421404 #. TRANSLATORS: program name
422 #: src/fu-main.c:880
405 #: src/fu-main.c:977
423406 msgid "Firmware Update Daemon"
424407 msgstr "Uppgraderingsdemon för fast programvara"
425408
426409 #. TRANSLATORS: program summary
427 #: src/fu-main.c:885
410 #: src/fu-main.c:982
428411 msgid "Firmware Update D-Bus Service"
429412 msgstr "Firmware Update D-Bus-tjänst"
430413
431414 #. TRANSLATORS: daemon is inactive
432 #: src/fu-progressbar.c:51
415 #: src/fu-progressbar.c:52
433416 msgid "Idle…"
434417 msgstr "Väntar…"
435418
436419 #. TRANSLATORS: decompressing the firmware file
437 #: src/fu-progressbar.c:55
420 #: src/fu-progressbar.c:56
438421 msgid "Decompressing…"
439422 msgstr "Dekomprimerar…"
440423
441424 #. TRANSLATORS: parsing the firmware information
442 #: src/fu-progressbar.c:59
425 #: src/fu-progressbar.c:60
443426 msgid "Loading…"
444427 msgstr "Läser in…"
445428
446429 #. TRANSLATORS: restarting the device to pick up new F/W
447 #: src/fu-progressbar.c:63
430 #: src/fu-progressbar.c:64
448431 msgid "Restarting device…"
449432 msgstr "Startar om enhet…"
450433
434 #. TRANSLATORS: reading from the flash chips
435 #: src/fu-progressbar.c:68
436 msgid "Reading…"
437 msgstr ""
438
451439 #. TRANSLATORS: writing to the flash chips
452 #: src/fu-progressbar.c:67
440 #: src/fu-progressbar.c:72
453441 msgid "Writing…"
454442 msgstr "Skriver…"
455443
444 #. TRANSLATORS: erasing contents of the flash chips
445 #: src/fu-progressbar.c:76
446 msgid "Erasing…"
447 msgstr ""
448
456449 #. TRANSLATORS: verifying we wrote the firmware correctly
457 #: src/fu-progressbar.c:71
450 #: src/fu-progressbar.c:80
458451 msgid "Verifying…"
459452 msgstr "Verifierar…"
460453
461454 #. TRANSLATORS: scheduing an update to be done on the next boot
462 #: src/fu-progressbar.c:75
455 #: src/fu-progressbar.c:84
463456 msgid "Scheduling…"
464457 msgstr "Schemalägger…"
465458
466459 #. TRANSLATORS: downloading from a remote server
467 #: src/fu-progressbar.c:79
460 #: src/fu-progressbar.c:88
468461 msgid "Downloading…"
469462 msgstr ""
470463
464 #. TRANSLATORS: waiting for user to authenticate
465 #: src/fu-progressbar.c:92
466 msgid "Authenticating…"
467 msgstr ""
468
471469 #. TRANSLATORS: currect daemon status is unknown
472 #: src/fu-progressbar.c:86
470 #: src/fu-progressbar.c:99
473471 msgid "Unknown"
474472 msgstr "Okänd"
475473
489487 msgid "No hardware detected with firmware update capability"
490488 msgstr "Ingen uppdateringsbar hårdvara upptäcktes"
491489
492 #. TRANSLATOR: the plugin only supports offline
493 #: src/fu-util.c:337
494 msgid "Retrying as an offline update"
495 msgstr "Försöker igen som en frånkopplad uppdatering"
496
497490 #. TRANSLATORS: the first replacement is a display name
498491 #. * e.g. "ColorHugALS" and the second is a version number
499492 #. * e.g. "1.2.3"
500 #: src/fu-util.c:501
493 #: src/fu-util.c:474
501494 #, c-format
502495 msgid "Reinstalling %s with %s... "
503496 msgstr "Återinstallerar %s med %s… "
505498 #. TRANSLATORS: the first replacement is a display name
506499 #. * e.g. "ColorHugALS" and the second and third are
507500 #. * version numbers e.g. "1.2.3"
508 #: src/fu-util.c:508
501 #: src/fu-util.c:481
509502 #, c-format
510503 msgid "Downgrading %s from %s to %s... "
511504 msgstr "Nedgraderar %s från %s till %s… "
513506 #. TRANSLATORS: the first replacement is a display name
514507 #. * e.g. "ColorHugALS" and the second and third are
515508 #. * version numbers e.g. "1.2.3"
516 #: src/fu-util.c:516
509 #: src/fu-util.c:489
517510 #, c-format
518511 msgid "Updating %s from %s to %s... "
519512 msgstr "Uppdaterar %s från %s till %s... "
520513
521 #: src/fu-util.c:543
514 #: src/fu-util.c:516
522515 msgid "Done!"
523516 msgstr "Klar!"
524517
525 #: src/fu-util.c:585 src/fu-util.c:985
518 #: src/fu-util.c:565 src/fu-util.c:978
526519 msgid "OK"
527520 msgstr "OK"
528521
529522 #. TRANSLATORS: downloading new signing file
530 #: src/fu-util.c:719
523 #: src/fu-util.c:699
531524 msgid "Fetching signature"
532525 msgstr ""
533526
534527 #. TRANSLATORS: downloading new metadata file
535 #: src/fu-util.c:722
528 #: src/fu-util.c:702
536529 msgid "Fetching metadata"
537530 msgstr ""
538531
539532 #. TRANSLATORS: downloading new firmware file
540 #: src/fu-util.c:725
533 #: src/fu-util.c:705
541534 msgid "Fetching firmware"
542535 msgstr ""
543536
544537 #. TRANSLATORS: downloading unknown file
545 #: src/fu-util.c:728
538 #: src/fu-util.c:708
546539 msgid "Fetching file"
547540 msgstr ""
548541
549542 #. TRANSLATORS: section header for release version number
550 #: src/fu-util.c:898
543 #: src/fu-util.c:888
551544 msgid "Version"
552545 msgstr "Version"
553546
547 #. TRANSLATORS: section header for the remote the file is coming from
548 #: src/fu-util.c:891
549 msgid "Remote"
550 msgstr ""
551
554552 #. TRANSLATORS: section header for firmware URI
555 #: src/fu-util.c:901
553 #: src/fu-util.c:894
556554 msgid "URI"
557555 msgstr ""
558556
559557 #. TRANSLATORS: section header for firmware description
560 #: src/fu-util.c:907
558 #: src/fu-util.c:900
561559 msgid "Description"
562560 msgstr "Beskrivning"
563561
564562 #. TRANSLATORS: section header for firmware checksum
565 #: src/fu-util.c:915
563 #. TRANSLATORS: remote checksum
564 #: src/fu-util.c:908 src/fu-util.c:1136
566565 msgid "Checksum"
567566 msgstr "Kontrollsumma"
568567
569568 #. TRANSLATORS: get interactive prompt
570 #: src/fu-util.c:947
569 #: src/fu-util.c:940
571570 msgid "Choose a release:"
572571 msgstr ""
573572
574573 #. TRANSLATORS: first replacement is device name
575 #: src/fu-util.c:1036
574 #: src/fu-util.c:1041
576575 #, c-format
577576 msgid "%s has firmware updates:"
578577 msgstr "%s har uppdateringar för fast programvara:"
579578
580 #: src/fu-util.c:1046
579 #: src/fu-util.c:1048
581580 msgid "GUID"
582581 msgstr "GUID"
583582
584583 #. TRANSLATORS: section header for firmware version
585 #: src/fu-util.c:1050
584 #: src/fu-util.c:1060
586585 msgid "Update Version"
587586 msgstr "Uppdateringsversion"
588587
589588 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
590 #: src/fu-util.c:1054
589 #: src/fu-util.c:1064
591590 msgid "Update Remote ID"
592591 msgstr ""
593592
594593 #. TRANSLATORS: section header for firmware checksum
595 #: src/fu-util.c:1063
594 #: src/fu-util.c:1073
596595 msgid "Update Checksum"
597596 msgstr "Uppdateringskontrollsumma"
598597
599598 #. TRANSLATORS: section header for firmware remote http://
600 #: src/fu-util.c:1067
599 #: src/fu-util.c:1077
601600 msgid "Update Location"
602601 msgstr "Uppdateringsplats"
603602
604603 #. TRANSLATORS: section header for long firmware desc
605 #: src/fu-util.c:1078
604 #: src/fu-util.c:1088
606605 msgid "Update Description"
607606 msgstr "Uppdateringsbeskrivning"
608607
609608 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
610 #: src/fu-util.c:1104
609 #: src/fu-util.c:1114
611610 msgid "Remote ID"
612611 msgstr ""
613612
613 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
614 #: src/fu-util.c:1118
615 msgid "Title"
616 msgstr ""
617
614618 #. TRANSLATORS: remote type, e.g. remote or local
615 #: src/fu-util.c:1108
619 #: src/fu-util.c:1122
616620 msgid "Type"
617621 msgstr ""
618622
619 #: src/fu-util.c:1113
623 #: src/fu-util.c:1127
620624 msgid "Keyring"
621625 msgstr ""
622626
623627 #. TRANSLATORS: if the remote is enabled
624 #: src/fu-util.c:1118
628 #: src/fu-util.c:1132
625629 msgid "Enabled"
626630 msgstr ""
627631
628632 #. TRANSLATORS: the age of the metadata
629 #: src/fu-util.c:1145
633 #: src/fu-util.c:1163
630634 msgid "Age"
631635 msgstr ""
632636
633637 #. TRANSLATORS: the numeric priority
634 #: src/fu-util.c:1152
638 #: src/fu-util.c:1170
635639 msgid "Priority"
636640 msgstr ""
637641
638642 #. TRANSLATORS: remote filename base
639 #: src/fu-util.c:1157
643 #: src/fu-util.c:1175
640644 msgid "Username"
641645 msgstr ""
642646
643647 #. TRANSLATORS: remote filename base
644 #: src/fu-util.c:1162
648 #: src/fu-util.c:1180
645649 msgid "Password"
646650 msgstr ""
647651
648 #. TRANSLATORS: remote filename base
649 #: src/fu-util.c:1167
652 #. TRANSLATORS: filename of the local file
653 #: src/fu-util.c:1185
650654 msgid "Filename"
651655 msgstr ""
652656
653 #. TRANSLATORS: remote filename base
654 #: src/fu-util.c:1172
657 #. TRANSLATORS: filename of the local file
658 #: src/fu-util.c:1190
655659 msgid "Filename Signature"
656660 msgstr ""
657661
658 #. TRANSLATORS: locatation of the local file
659 #: src/fu-util.c:1177
660 msgid "Location"
661 msgstr "Plats"
662
663 #. TRANSLATORS: locatation of the local file
664 #: src/fu-util.c:1182
665 msgid "Location Signature"
666 msgstr ""
667
668662 #. TRANSLATORS: remote URI
669 #: src/fu-util.c:1187
663 #: src/fu-util.c:1195
670664 msgid "Metadata URI"
671665 msgstr ""
672666
673667 #. TRANSLATORS: remote URI
674 #: src/fu-util.c:1192
668 #: src/fu-util.c:1200
675669 msgid "Metadata URI Signature"
676670 msgstr ""
677671
678672 #. TRANSLATORS: remote URI
679 #: src/fu-util.c:1197
673 #: src/fu-util.c:1205
680674 msgid "Firmware Base URI"
681675 msgstr ""
682676
683677 #. TRANSLATORS: this is when a device is hotplugged
684 #: src/fu-util.c:1224
678 #: src/fu-util.c:1232
685679 msgid "Device added:"
686680 msgstr "Enhet tillagd:"
687681
688682 #. TRANSLATORS: this is when a device is hotplugged
689 #: src/fu-util.c:1234
683 #: src/fu-util.c:1242
690684 msgid "Device removed:"
691685 msgstr "Enhet borttagen:"
692686
693687 #. TRANSLATORS: this is when a device has been updated
694 #: src/fu-util.c:1244
688 #: src/fu-util.c:1252
695689 msgid "Device changed:"
696690 msgstr "Enhet ändrad:"
697691
698692 #. TRANSLATORS: command line option
699 #: src/fu-util.c:1568
693 #: src/fu-util.c:1595
700694 msgid "Show extra debugging information"
701695 msgstr "Visa extra felsökningsinformation"
702696
703697 #. TRANSLATORS: command line option
704 #: src/fu-util.c:1571
698 #: src/fu-util.c:1598
705699 msgid "Show client and daemon versions"
706700 msgstr ""
707701
708702 #. TRANSLATORS: command line option
709 #: src/fu-util.c:1574
703 #: src/fu-util.c:1601
710704 msgid "Schedule installation for next reboot when possible"
711705 msgstr "Schemalägg om möjligt installationen till nästa uppstart"
712706
713707 #. TRANSLATORS: command line option
714 #: src/fu-util.c:1577
708 #: src/fu-util.c:1604
715709 msgid "Allow re-installing existing firmware versions"
716710 msgstr "Tillåt att installera om befintliga versioner av fast programvara"
717711
718712 #. TRANSLATORS: command line option
719 #: src/fu-util.c:1580
713 #: src/fu-util.c:1607
720714 msgid "Allow downgrading firmware versions"
721715 msgstr "Tillåt att nedgradera versioner av fast programvara"
722716
723717 #. TRANSLATORS: command line option
724 #: src/fu-util.c:1583
718 #: src/fu-util.c:1610
725719 msgid "Override plugin warning"
726720 msgstr "Åsidosätt tilläggsvarning"
727721
728722 #. TRANSLATORS: command description
729 #: src/fu-util.c:1607
723 #: src/fu-util.c:1634
730724 msgid "Get all devices that support firmware updates"
731725 msgstr "Hämta alla enheter som stödjer uppdateringar av fast programvara"
732726
733727 #. TRANSLATORS: command description
734 #: src/fu-util.c:1613
728 #: src/fu-util.c:1640
735729 msgid "Return all the hardware IDs for the machine"
736730 msgstr ""
737731
738732 #. TRANSLATORS: command description
739 #: src/fu-util.c:1619
733 #: src/fu-util.c:1646
740734 msgid "Install prepared updates now"
741735 msgstr "Installera förberedda uppdateringar nu"
742736
743737 #. TRANSLATORS: command description
744 #: src/fu-util.c:1625
738 #: src/fu-util.c:1652
745739 msgid "Install a firmware file on this hardware"
746740 msgstr "Installera en fast programvarufil på denna hårdvara"
747741
748742 #. TRANSLATORS: command description
749 #: src/fu-util.c:1631
743 #: src/fu-util.c:1658
750744 msgid "Gets details about a firmware file"
751745 msgstr "Hämtar detaljer om en fast programvarufil"
752746
753747 #. TRANSLATORS: command description
754 #: src/fu-util.c:1637
748 #: src/fu-util.c:1664
755749 msgid "Gets the list of updates for connected hardware"
756750 msgstr "Hämtar listan över uppdateringar för ansluten hårdvara"
757751
758752 #. TRANSLATORS: command description
759 #: src/fu-util.c:1643
753 #: src/fu-util.c:1670
760754 msgid "Updates all firmware to latest versions available"
761755 msgstr "Uppdaterar all fast programvara till de senast tillgängliga versionerna"
762756
763757 #. TRANSLATORS: command description
764 #: src/fu-util.c:1649
758 #: src/fu-util.c:1676
765759 msgid "Gets the cryptographic hash of the dumped firmware"
766760 msgstr "Hämtar den kryptografiska hashen för den utskrivna versionen av den fasta programvaran"
767761
768762 #. TRANSLATORS: command description
769 #: src/fu-util.c:1655
763 #: src/fu-util.c:1682
770764 msgid "Unlocks the device for firmware access"
771765 msgstr "Låser upp enheten för fast programvaruåtkomst"
772766
773767 #. TRANSLATORS: command description
774 #: src/fu-util.c:1661
768 #: src/fu-util.c:1688
775769 msgid "Clears the results from the last update"
776770 msgstr "Rensar resultaten från senaste uppdateringen"
777771
778772 #. TRANSLATORS: command description
779 #: src/fu-util.c:1667
773 #: src/fu-util.c:1694
774 msgid "Clears any updates scheduled to be updated offline"
775 msgstr ""
776
777 #. TRANSLATORS: command description
778 #: src/fu-util.c:1700
780779 msgid "Gets the results from the last update"
781780 msgstr "Hämtar resultaten från senaste uppdateringen"
782781
783782 #. TRANSLATORS: command description
784 #: src/fu-util.c:1673
783 #: src/fu-util.c:1706
785784 msgid "Gets the releases for a device"
786785 msgstr ""
787786
788787 #. TRANSLATORS: command description
789 #: src/fu-util.c:1679
788 #: src/fu-util.c:1712
790789 msgid "Gets the configured remotes"
791790 msgstr ""
792791
793792 #. TRANSLATORS: command description
794 #: src/fu-util.c:1685
793 #: src/fu-util.c:1718
795794 msgid "Downgrades the firmware on a device"
796795 msgstr ""
797796
798797 #. TRANSLATORS: command description
799 #: src/fu-util.c:1691
798 #: src/fu-util.c:1724
800799 msgid "Refresh metadata from remote server"
801800 msgstr "Uppdatera metadata från fjärrserver"
802801
803802 #. TRANSLATORS: command description
804 #: src/fu-util.c:1697
803 #: src/fu-util.c:1730
805804 msgid "Update the stored metadata with current ROM contents"
806805 msgstr "Uppdatera den lagrade metadatan med aktuellt ROM-innehåll"
807806
808807 #. TRANSLATORS: command description
809 #: src/fu-util.c:1703
808 #: src/fu-util.c:1736
810809 msgid "Monitor the daemon for events"
811810 msgstr "Övervaka demonen för händelser"
812811
813812 #. TRANSLATORS: command description
814 #: src/fu-util.c:1709
813 #: src/fu-util.c:1742
815814 msgid "Build firmware using a sandbox"
816815 msgstr ""
817816
817 #. TRANSLATORS: command description
818 #: src/fu-util.c:1748
819 msgid "Dump SMBIOS data from a file"
820 msgstr ""
821
822 #. TRANSLATORS: command description
823 #: src/fu-util.c:1754
824 msgid "Modifies a given remote"
825 msgstr ""
826
818827 #. TRANSLATORS: program name
819 #: src/fu-util.c:1728
828 #: src/fu-util.c:1773
820829 msgid "Firmware Utility"
821830 msgstr "Fast programvaruverktyg"
1919 """
2020
2121 import sys
22 import os
2223 err = 0
2324
2425 try:
5859 print("Error: missing dependency python cairo (python3-cairo)")
5960 err = 1
6061
62 # check that LINUGAS lists every language with a .po file
63 with open('po/LINGUAS') as f:
64 langs = f.read().splitlines()
65 for root, dirs, files in os.walk('po'):
66 for file in files:
67 if not file.endswith('.po'):
68 continue
69 l = file.split('.po')
70 if len(l) > 1 and not l[0] in langs:
71 err = 1
72 print("Error: missing translations for %s" % l[0])
73
6174 sys.exit(err)
62
+184
-175
po/tr.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Turkish (http://www.transifex.com/freedesktop/fwupd/language/tr/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr ""
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr ""
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Komut bulunamadı"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr ""
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr ""
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr ""
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr ""
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Ayrılıyor"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "Bağlanıyor"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Eklendi"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Kaldırıldı"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Değişti"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "İptal Edildi"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "Kimlik (ID)"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "İsim"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Şifreleme"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Bölge"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Bulundu"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "İletişim kuralı"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Durum"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Bilinmiyor: izin verilmedi"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Seri"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Kip"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Evre"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr ""
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr ""
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Ürün yazılımını DFU biçimine dönüştür"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Birden çok ürün yazılımı dosyasını tek dosyada birleştir"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Ürün yazılımı dosyası üzerindeki üretici kimliğini ayarlayın"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Ürün yazılımı dosyası üzerindeki ürün kimliğini ayarlayın"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr ""
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr ""
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr ""
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr ""
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr ""
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr ""
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr ""
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr ""
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr ""
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr ""
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr ""
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr ""
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr ""
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr ""
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Ürün yazılımı verisini şifreleyin"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Ürün yazılımı verisinin şifresini açın"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Ürün yazılımı dosyası üzerindeki üst veriyi ayarlar"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr ""
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr ""
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr ""
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr ""
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr ""
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr ""
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr ""
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr ""
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr ""
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr ""
393376
407390 msgstr ""
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr ""
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr ""
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr ""
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr ""
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Boşta…"
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "Açılıyor…"
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "Yükleniyor…"
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "Cihaz yeniden başlatılıyor…"
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "Yazılıyor…"
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "Doğrulanıyor…"
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Zamanlanıyor…"
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr ""
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Bilinmiyor"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Ürün yazılımı güncelleme yeteneğine sahip donanım saptanamadı"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Çevrimdışı güncelleme olarak yeniden deneniyor"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr ""
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr ""
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr ""
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Bitti!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "Tamam"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr ""
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr ""
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr ""
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr ""
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr ""
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr ""
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr ""
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr ""
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr ""
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr ""
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Güncelleme Sürümü"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr ""
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Güncelleme Sağlaması"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Güncelleme Konumu"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Güncelleme Açıklaması"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr ""
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr ""
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr ""
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr ""
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr ""
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr ""
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr ""
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr ""
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr ""
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr ""
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Aygıt eklendi:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Aygıt çıkarıldı:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "Aygıt değişti:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr ""
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr ""
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr ""
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr ""
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr ""
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr ""
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr ""
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr ""
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr ""
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr ""
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr ""
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr ""
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr ""
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr ""
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr ""
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr ""
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr ""
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr ""
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr ""
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr ""
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr ""
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr ""
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr ""
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Ürün Yazılımı Yardımcı Programı"
+188
-179
po/uk.po less more
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Ukrainian (http://www.transifex.com/freedesktop/fwupd/language/uk/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr "Щоб отримати доступ до оновлення збережених контрольних сум для пристрою, вам слід пройти розпізнавання"
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "Інша назва %s"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "Такої команди не знайдено"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "Читання"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "Запис"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "Перевірка"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "Витирання"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "Від’єднуємо"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "З’єднуємо"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "Додано"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "Вилучено"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "Змінено"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "Скасовано"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "Ід."
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "Назва"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "Шифр"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "Регіон"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "Знайдено"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "Протокол"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "Стан"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "Невідомий: доступ заборонено"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "Порядкове"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "Режим"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "Стан"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "Об’єм перенесеного"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "Негаразди"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "Перетворити мікропрограму у формат DFU"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "Об’єднати декілька файлів мікропрограм у один"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "Встановити ідентифікатор виробника для файла мікропрограми"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "Встановити ідентифікатор продукту для файла мікропрограми"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr "Встановити адресу елемента для файла мікропрограми"
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr "Встановити розмір мікропрограми для призначення"
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "Встановити версію випуску для файла мікропрограми"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "Встановити альтернативний номер для файла мікропрограми"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "Встановити альтернативну назву для файла мікропрограми"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "Повернути пристрій із можливостями DFU до використання"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "Прочитати мікропрограму з пристрою до файла"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "Прочитати мікропрограму з одного розділу до файла"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "Записати мікропрограму з файла на пристрій"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "Записати мікропрограму з файла на один розділ"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "Вивести поточний список долучених пристроїв із можливостями DFU"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "Від’єднати поточний з’єднаний пристрій із можливостями DFU"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "Створити дамп даних щодо файла мікропрограми"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "Спостерігати за пристроями DFU, які з’єднують із комп’ютером"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "Зашифрувати дані мікропрограми"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "Розшифрувати дані мікропрограми"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "Встановлює метадані щодо файла мікпропрограми"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr "Замінити дані у наявному файлі мікропрограми"
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr "Створити бінарну латку на основі двох файлів"
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr "Застосувати бінарну латку"
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr "Вивести дамп інформації щодо бінарної латки на екран"
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "Засіб роботи з DFU"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "Не вдалося обробити аргументи"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr "Нумерувати усі пристрої MST Synaptics"
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr "Записати файл мікропрограми на пристрій MST"
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr "Засіб багатопотокового передавання Synaptics"
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr "Встановлюємо оновлення мікропрограми…"
393376
407390 msgstr "Показувати параметри діагностики"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "Завершити роботу з невеличкою затримкою"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "Завершити роботу після завантаження рушія"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "Служба оновлення мікропрограми"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "Служба D-Bus оновлення мікропрограми"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "Бездіяльність…"
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "Розпаковування…"
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "Завантаження…"
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "Перезапускаємо пристрій…"
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "Записуємо…"
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "Перевіряємо…"
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "Плануємо…"
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr "Отримуємо дані…"
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "Невідомий"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "Не виявлено обладнання із передбаченою можливістю оновлення мікропрограми"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "Повторна спроба у режимі автономного оновлення"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "Повторно встановлюємо %s з номером версії %s... "
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "Знижуємо версію %s з %s до %s... "
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "Оновлюємо %s з %s до %s... "
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "Виконано!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "Гаразд"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr "Отримуємо підпис"
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr "Отримуємо метадані"
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr "Отримуємо мікропрограму"
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr "Отримуємо файл"
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "Версія"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr "Адреса"
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "Опис"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "Контрольна сума"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr "Виберіть випуск:"
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "%s має такі оновлення мікропрограми:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "Версія оновлення"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr "Оновити віддалений ідентифікатор"
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "Контрольна сума оновлення"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "Місце оновлення"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "Опис оновлення"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr "Віддалений ідентифікатор"
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr "Тип"
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619 msgstr ""
623 msgstr "Сховище ключів"
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr "Увімкнено"
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr "Вік"
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr "Пріоритетність"
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr "Користувач"
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr "Пароль"
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr "Назва файла"
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr "Підпис назви файла"
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "Місце"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669 msgstr ""
663 msgstr "Адреса метаданих"
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674 msgstr ""
668 msgstr "Підпис адреси метаданих"
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679 msgstr ""
673 msgstr "Основна адреса мікропрограми"
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "Додано пристрій:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "Вилучено пристрій:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "Змінено пристрій:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "Показати додаткові діагностичні дані"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr "Вивести дані щодо версій клієнат і фонової служби"
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr "Якщо можливо, запланувати встановлення на наступне перезавантаження"
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "Дозволити повторне встановлення наявних версій мікропрограми"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "Дозволити зниження версій мікропрограми"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr "Перевизначити попередження для додатка"
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "Отримати список усіх пристроїв, у яких передбачено оновлення мікропрограми"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr "Повернути усі ідентифікатори апаратного забезпечення комп’ютера"
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "Встановити приготовані оновлення зараз"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "Встановити файл мікропрограми на це обладнання"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "Отримати параметри файла мікропрограми"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "Отримує список оновлень для з’єднаного обладнання"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "Оновлює усі мікропрограми до найновіших доступних версій"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "Отримує криптографічні хеш-суми для дампів мікропрограм"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "Розблоковує пристрій для доступу до мікропрограми"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "Вилучає результати останнього оновлення"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "Отримує результати з останнього оновлення"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr "Отримує випуски для пристрою"
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr "Отримує налаштовані віддалені пристрої"
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr "Знижує версію мікропрограми на пристрої"
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "Оновити метадані з віддаленого сервера"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "Оновити збережені метадані на основі поточного вмісту ROM"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "Стежити за подіями у фоновій службі"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
813 msgstr "Зібрати мікропрограму за допомогою пісочниці"
814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
814823 msgstr ""
815824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "Засіб роботи з мікропрограмами"
1111 msgstr ""
1212 "Project-Id-Version: fwupd\n"
1313 "Report-Msgid-Bugs-To: \n"
14 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
15 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
14 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
15 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1616 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1717 "Language-Team: Chinese (China) (http://www.transifex.com/freedesktop/fwupd/language/zh_CN/)\n"
1818 "MIME-Version: 1.0\n"
108108 "Authentication is required to update the stored checksums for the device"
109109 msgstr "需要认证:为设备更新存储的校验和"
110110
111 #: policy/org.freedesktop.fwupd.policy.in:105
112 msgid "Modify a configured remote"
113 msgstr ""
114
115 #. TRANSLATORS: this is the PolicyKit modal dialog
116 #: policy/org.freedesktop.fwupd.policy.in:107
117 msgid ""
118 "Authentication is required to modify a configured remote used for firmware "
119 "updates"
120 msgstr ""
121
111122 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
112 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
123 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
113124 #: src/fu-util.c:112
114125 #, c-format
115126 msgid "Alias to %s"
116127 msgstr "%s 的别名"
117128
118129 #. TRANSLATORS: error message
119 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
130 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
120131 #: src/fu-util.c:176
121132 msgid "Command not found"
122133 msgstr "未找到命令"
123134
124 #. TRANSLATORS: read from device to host
125 #: libdfu/dfu-tool.c:1236
126 msgid "Reading"
127 msgstr "读取中"
128
129 #. TRANSLATORS: write from host to device
130 #: libdfu/dfu-tool.c:1242
131 msgid "Writing"
132 msgstr "写入中"
133
134 #. TRANSLATORS: read from device to host
135 #: libdfu/dfu-tool.c:1248
136 msgid "Verifying"
137 msgstr "验证中"
138
139 #. TRANSLATORS: read from device to host
140 #: libdfu/dfu-tool.c:1254
141 msgid "Erasing"
142 msgstr "擦除中"
143
144 #. TRANSLATORS: waiting for device
145 #: libdfu/dfu-tool.c:1260
146 msgid "Detaching"
147 msgstr "断开中"
148
149 #. TRANSLATORS: waiting for device
150 #: libdfu/dfu-tool.c:1266
151 msgid "Attaching"
152 msgstr "连接中"
153
154135 #. TRANSLATORS: this is when a device is hotplugged
155 #: libdfu/dfu-tool.c:1487
136 #: plugins/dfu/dfu-tool.c:1440
156137 msgid "Added"
157138 msgstr "已添加"
158139
159140 #. TRANSLATORS: this is when a device is hotplugged
160 #: libdfu/dfu-tool.c:1498
141 #: plugins/dfu/dfu-tool.c:1451
161142 msgid "Removed"
162143 msgstr "已移除"
163144
164145 #. TRANSLATORS: this is when a device is hotplugged
165146 #. TRANSLATORS: this is when the daemon state changes
166 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
147 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
167148 msgid "Changed"
168149 msgstr "已变更"
169150
170151 #. TRANSLATORS: this is when a device ctrl+c's a watch
171 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
152 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
172153 msgid "Cancelled"
173154 msgstr "已取消"
174155
175156 #. TRANSLATORS: Appstream ID for the hardware type
176 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
157 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
177158 msgid "ID"
178159 msgstr "ID"
179160
180161 #. TRANSLATORS: interface name, e.g. "Flash"
181162 #. TRANSLATORS: device name, e.g. 'ColorHug2'
182 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
163 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
164 #: plugins/dfu/dfu-tool.c:2065
183165 msgid "Name"
184166 msgstr "名称"
185167
186168 #. TRANSLATORS: this is the encryption method used when writing
187 #: libdfu/dfu-tool.c:2043
169 #: plugins/dfu/dfu-tool.c:1985
188170 msgid "Cipher"
189171 msgstr "加密"
190172
191173 #. TRANSLATORS: these are areas of memory on the chip
192 #: libdfu/dfu-tool.c:2057
174 #: plugins/dfu/dfu-tool.c:1999
193175 msgid "Region"
194176 msgstr "区域"
195177
196178 #. TRANSLATORS: detected a DFU device
197 #: libdfu/dfu-tool.c:2092
179 #: plugins/dfu/dfu-tool.c:2033
198180 msgid "Found"
199181 msgstr "找到"
200182
201183 #. TRANSLATORS: DFU protocol version, e.g. 1.1
202 #: libdfu/dfu-tool.c:2100
184 #: plugins/dfu/dfu-tool.c:2041
203185 msgid "Protocol"
204186 msgstr "协议"
205187
206188 #. TRANSLATORS: probably not run as root...
207189 #. TRANSLATORS: device has failed to report status
208190 #. TRANSLATORS: device status, e.g. "OK"
209 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
191 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
192 #: plugins/dfu/dfu-tool.c:2080
210193 msgid "Status"
211194 msgstr "状况"
212195
213 #: libdfu/dfu-tool.c:2112
196 #: plugins/dfu/dfu-tool.c:2054
214197 msgid "Unknown: permission denied"
215198 msgstr "未知:访问被拒绝"
216199
217200 #. TRANSLATORS: serial number, e.g. '00012345'
218 #: libdfu/dfu-tool.c:2129
201 #: plugins/dfu/dfu-tool.c:2071
219202 msgid "Serial"
220203 msgstr "串口"
221204
222205 #. TRANSLATORS: device mode, e.g. runtime or DFU
223 #: libdfu/dfu-tool.c:2134
206 #: plugins/dfu/dfu-tool.c:2076
224207 msgid "Mode"
225208 msgstr "模式"
226209
227210 #. TRANSLATORS: device state, i.e. appIDLE
228 #: libdfu/dfu-tool.c:2142
211 #: plugins/dfu/dfu-tool.c:2084
229212 msgid "State"
230213 msgstr "状态"
231214
232215 #. TRANSLATORS: transfer size in bytes
233 #: libdfu/dfu-tool.c:2150
216 #: plugins/dfu/dfu-tool.c:2092
234217 msgid "Transfer Size"
235218 msgstr "传输大小"
236219
237220 #. TRANSLATORS: device quirks, i.e. things that
238221 #. * it does that we have to work around
239 #: libdfu/dfu-tool.c:2158
222 #: plugins/dfu/dfu-tool.c:2100
240223 msgid "Quirks"
241224 msgstr "特异情况"
242225
243226 #. TRANSLATORS: command description
244 #: libdfu/dfu-tool.c:2237
227 #: plugins/dfu/dfu-tool.c:2181
245228 msgid "Convert firmware to DFU format"
246229 msgstr "将固件转换为固件升级(DFU)格式"
247230
248231 #. TRANSLATORS: command description
249 #: libdfu/dfu-tool.c:2243
232 #: plugins/dfu/dfu-tool.c:2187
250233 msgid "Merge multiple firmware files into one"
251234 msgstr "将多个固件文件合并为一个"
252235
253236 #. TRANSLATORS: command description
254 #: libdfu/dfu-tool.c:2249
237 #: plugins/dfu/dfu-tool.c:2193
255238 msgid "Set vendor ID on firmware file"
256239 msgstr "设置固件文件上的供应商 ID"
257240
258241 #. TRANSLATORS: command description
259 #: libdfu/dfu-tool.c:2255
242 #: plugins/dfu/dfu-tool.c:2199
260243 msgid "Set product ID on firmware file"
261244 msgstr "设置固件文件上的产品 ID"
262245
263246 #. TRANSLATORS: command description
264 #: libdfu/dfu-tool.c:2261
247 #: plugins/dfu/dfu-tool.c:2205
265248 msgid "Set element address on firmware file"
266249 msgstr "设置固件文件上的元件地址"
267250
268251 #. TRANSLATORS: command description
269 #: libdfu/dfu-tool.c:2267
252 #: plugins/dfu/dfu-tool.c:2211
270253 msgid "Set the firmware size for the target"
271254 msgstr "为目标固件设置大小"
272255
273256 #. TRANSLATORS: command description
274 #: libdfu/dfu-tool.c:2273
257 #: plugins/dfu/dfu-tool.c:2217
275258 msgid "Set release version on firmware file"
276259 msgstr "设置固件文件上的发布版本"
277260
278261 #. TRANSLATORS: command description
279 #: libdfu/dfu-tool.c:2279
262 #: plugins/dfu/dfu-tool.c:2223
280263 msgid "Set alternative number on firmware file"
281264 msgstr "设置固件文件上的替代数字"
282265
283266 #. TRANSLATORS: command description
284 #: libdfu/dfu-tool.c:2285
267 #: plugins/dfu/dfu-tool.c:2229
285268 msgid "Set alternative name on firmware file"
286269 msgstr "设置固件文件上的替代名称"
287270
288271 #. TRANSLATORS: command description
289 #: libdfu/dfu-tool.c:2291
272 #: plugins/dfu/dfu-tool.c:2235
290273 msgid "Attach DFU capable device back to runtime"
291274 msgstr "将可固件升级 (DFU) 的设备重新附到运行时上"
292275
293276 #. TRANSLATORS: command description
294 #: libdfu/dfu-tool.c:2297
277 #: plugins/dfu/dfu-tool.c:2241
295278 msgid "Read firmware from device into a file"
296279 msgstr "将来自设备的固件读入文件"
297280
298281 #. TRANSLATORS: command description
299 #: libdfu/dfu-tool.c:2303
282 #: plugins/dfu/dfu-tool.c:2247
300283 msgid "Read firmware from one partition into a file"
301284 msgstr "将来自分区的固件读入文件"
302285
303286 #. TRANSLATORS: command description
304 #: libdfu/dfu-tool.c:2309
287 #: plugins/dfu/dfu-tool.c:2253
305288 msgid "Write firmware from file into device"
306289 msgstr "将来自文件的固件写入设备"
307290
308291 #. TRANSLATORS: command description
309 #: libdfu/dfu-tool.c:2315
292 #: plugins/dfu/dfu-tool.c:2259
310293 msgid "Write firmware from file into one partition"
311294 msgstr "将来自文件的固件写入分区"
312295
313296 #. TRANSLATORS: command description
314 #: libdfu/dfu-tool.c:2321
297 #: plugins/dfu/dfu-tool.c:2265
315298 msgid "List currently attached DFU capable devices"
316299 msgstr "列出当前连接的可固件升级的设备"
317300
318301 #. TRANSLATORS: command description
319 #: libdfu/dfu-tool.c:2327
302 #: plugins/dfu/dfu-tool.c:2271
320303 msgid "Detach currently attached DFU capable device"
321304 msgstr "断开当前连接的可固件升级的设备"
322305
323306 #. TRANSLATORS: command description
324 #: libdfu/dfu-tool.c:2333
307 #: plugins/dfu/dfu-tool.c:2277
325308 msgid "Dump details about a firmware file"
326309 msgstr "转储有关某固件文件的详细信息"
327310
328311 #. TRANSLATORS: command description
329 #: libdfu/dfu-tool.c:2339
312 #: plugins/dfu/dfu-tool.c:2283
330313 msgid "Watch DFU devices being hotplugged"
331314 msgstr "注意被热插入的固件升级 (DFU) 设备"
332315
333316 #. TRANSLATORS: command description
334 #: libdfu/dfu-tool.c:2345
317 #: plugins/dfu/dfu-tool.c:2289
335318 msgid "Encrypt firmware data"
336319 msgstr "加密固件数据"
337320
338321 #. TRANSLATORS: command description
339 #: libdfu/dfu-tool.c:2351
322 #: plugins/dfu/dfu-tool.c:2295
340323 msgid "Decrypt firmware data"
341324 msgstr "解密固件数据"
342325
343326 #. TRANSLATORS: command description
344 #: libdfu/dfu-tool.c:2357
327 #: plugins/dfu/dfu-tool.c:2301
345328 msgid "Sets metadata on a firmware file"
346329 msgstr "设置固件文件上的元数据"
347330
348331 #. TRANSLATORS: command description
349 #: libdfu/dfu-tool.c:2363
332 #: plugins/dfu/dfu-tool.c:2307
350333 msgid "Replace data in an existing firmware file"
351334 msgstr "用已有的固件文件替换数据"
352335
353336 #. TRANSLATORS: command description
354 #: libdfu/dfu-tool.c:2369
337 #: plugins/dfu/dfu-tool.c:2313
355338 msgid "Create a binary patch using two files"
356339 msgstr "使用两个文件创建二进制补丁"
357340
358341 #. TRANSLATORS: command description
359 #: libdfu/dfu-tool.c:2375
342 #: plugins/dfu/dfu-tool.c:2319
360343 msgid "Apply a binary patch"
361344 msgstr "应用二进制补丁"
362345
363346 #. TRANSLATORS: command description
364 #: libdfu/dfu-tool.c:2381
347 #: plugins/dfu/dfu-tool.c:2325
365348 msgid "Dump information about a binary patch to the screen"
366349 msgstr "将二进制补丁信息输出到屏幕"
367350
368351 #. TRANSLATORS: DFU stands for device firmware update
369 #: libdfu/dfu-tool.c:2407
352 #: plugins/dfu/dfu-tool.c:2351
370353 msgid "DFU Utility"
371354 msgstr "固件更新实用程序"
372355
373356 #. TRANSLATORS: the user didn't read the man page
374 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
375 #: src/fu-util.c:1733
357 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
358 #: src/fu-util.c:1778
376359 msgid "Failed to parse arguments"
377360 msgstr "未能解析参数"
378361
379362 #. TRANSLATORS: command description
380 #: plugins/synapticsmst/synapticsmst-tool.c:408
363 #: plugins/synapticsmst/synapticsmst-tool.c:400
381364 msgid "Enumerate all Synaptics MST devices"
382365 msgstr "枚举所有 Synaptics MST 设备"
383366
384367 #. TRANSLATORS: command description
385 #: plugins/synapticsmst/synapticsmst-tool.c:414
368 #: plugins/synapticsmst/synapticsmst-tool.c:406
386369 msgid "Flash firmware file to MST device"
387370 msgstr "刷写固件文件到 MST 设备"
388371
389 #: plugins/synapticsmst/synapticsmst-tool.c:434
372 #: plugins/synapticsmst/synapticsmst-tool.c:426
390373 msgid "Synaptics Multistream Transport Utility"
391374 msgstr "Synaptics 多流传输工具"
392375
393376 #. TRANSLATORS: this is shown when updating the firmware after the reboot
394 #: plugins/uefi/fu-plugin-uefi.c:194
377 #: plugins/uefi/fu-plugin-uefi.c:396
395378 msgid "Installing firmware update…"
396379 msgstr "正在安装固件更新..."
397380
411394 msgstr "显示调试选项"
412395
413396 #. TRANSLATORS: exit after we've started up, used for user profiling
414 #: src/fu-main.c:863
397 #: src/fu-main.c:960
415398 msgid "Exit after a small delay"
416399 msgstr "在短暂的延迟后退出"
417400
418401 #. TRANSLATORS: exit straight away, used for automatic profiling
419 #: src/fu-main.c:866
402 #: src/fu-main.c:963
420403 msgid "Exit after the engine has loaded"
421404 msgstr "在引擎加载后退出"
422405
423406 #. TRANSLATORS: program name
424 #: src/fu-main.c:880
407 #: src/fu-main.c:977
425408 msgid "Firmware Update Daemon"
426409 msgstr "固件更新守护程序"
427410
428411 #. TRANSLATORS: program summary
429 #: src/fu-main.c:885
412 #: src/fu-main.c:982
430413 msgid "Firmware Update D-Bus Service"
431414 msgstr "固件更新 D-Bus 服务"
432415
433416 #. TRANSLATORS: daemon is inactive
434 #: src/fu-progressbar.c:51
417 #: src/fu-progressbar.c:52
435418 msgid "Idle…"
436419 msgstr "空闲…"
437420
438421 #. TRANSLATORS: decompressing the firmware file
439 #: src/fu-progressbar.c:55
422 #: src/fu-progressbar.c:56
440423 msgid "Decompressing…"
441424 msgstr "正在解压缩…"
442425
443426 #. TRANSLATORS: parsing the firmware information
444 #: src/fu-progressbar.c:59
427 #: src/fu-progressbar.c:60
445428 msgid "Loading…"
446429 msgstr "正在加载…"
447430
448431 #. TRANSLATORS: restarting the device to pick up new F/W
449 #: src/fu-progressbar.c:63
432 #: src/fu-progressbar.c:64
450433 msgid "Restarting device…"
451434 msgstr "正在重启设备…"
452435
436 #. TRANSLATORS: reading from the flash chips
437 #: src/fu-progressbar.c:68
438 msgid "Reading…"
439 msgstr ""
440
453441 #. TRANSLATORS: writing to the flash chips
454 #: src/fu-progressbar.c:67
442 #: src/fu-progressbar.c:72
455443 msgid "Writing…"
456444 msgstr "正在写入…"
457445
446 #. TRANSLATORS: erasing contents of the flash chips
447 #: src/fu-progressbar.c:76
448 msgid "Erasing…"
449 msgstr ""
450
458451 #. TRANSLATORS: verifying we wrote the firmware correctly
459 #: src/fu-progressbar.c:71
452 #: src/fu-progressbar.c:80
460453 msgid "Verifying…"
461454 msgstr "正在验证…"
462455
463456 #. TRANSLATORS: scheduing an update to be done on the next boot
464 #: src/fu-progressbar.c:75
457 #: src/fu-progressbar.c:84
465458 msgid "Scheduling…"
466459 msgstr "正在计划…"
467460
468461 #. TRANSLATORS: downloading from a remote server
469 #: src/fu-progressbar.c:79
462 #: src/fu-progressbar.c:88
470463 msgid "Downloading…"
471464 msgstr "正在下载..."
472465
466 #. TRANSLATORS: waiting for user to authenticate
467 #: src/fu-progressbar.c:92
468 msgid "Authenticating…"
469 msgstr ""
470
473471 #. TRANSLATORS: currect daemon status is unknown
474 #: src/fu-progressbar.c:86
472 #: src/fu-progressbar.c:99
475473 msgid "Unknown"
476474 msgstr "未知"
477475
491489 msgid "No hardware detected with firmware update capability"
492490 msgstr "没有检测到支持更新固件的硬件"
493491
494 #. TRANSLATOR: the plugin only supports offline
495 #: src/fu-util.c:337
496 msgid "Retrying as an offline update"
497 msgstr "作为脱机更新重试"
498
499492 #. TRANSLATORS: the first replacement is a display name
500493 #. * e.g. "ColorHugALS" and the second is a version number
501494 #. * e.g. "1.2.3"
502 #: src/fu-util.c:501
495 #: src/fu-util.c:474
503496 #, c-format
504497 msgid "Reinstalling %s with %s... "
505498 msgstr "正在重新安装 %s,使用 %s…"
507500 #. TRANSLATORS: the first replacement is a display name
508501 #. * e.g. "ColorHugALS" and the second and third are
509502 #. * version numbers e.g. "1.2.3"
510 #: src/fu-util.c:508
503 #: src/fu-util.c:481
511504 #, c-format
512505 msgid "Downgrading %s from %s to %s... "
513506 msgstr "正在降级 %s,从 %s 到 %s…"
515508 #. TRANSLATORS: the first replacement is a display name
516509 #. * e.g. "ColorHugALS" and the second and third are
517510 #. * version numbers e.g. "1.2.3"
518 #: src/fu-util.c:516
511 #: src/fu-util.c:489
519512 #, c-format
520513 msgid "Updating %s from %s to %s... "
521514 msgstr "正在更新 %s,从 %s 到 %s…"
522515
523 #: src/fu-util.c:543
516 #: src/fu-util.c:516
524517 msgid "Done!"
525518 msgstr "完成!"
526519
527 #: src/fu-util.c:585 src/fu-util.c:985
520 #: src/fu-util.c:565 src/fu-util.c:978
528521 msgid "OK"
529522 msgstr "确定"
530523
531524 #. TRANSLATORS: downloading new signing file
532 #: src/fu-util.c:719
525 #: src/fu-util.c:699
533526 msgid "Fetching signature"
534527 msgstr "正在获取签名"
535528
536529 #. TRANSLATORS: downloading new metadata file
537 #: src/fu-util.c:722
530 #: src/fu-util.c:702
538531 msgid "Fetching metadata"
539532 msgstr "正在获取元信息"
540533
541534 #. TRANSLATORS: downloading new firmware file
542 #: src/fu-util.c:725
535 #: src/fu-util.c:705
543536 msgid "Fetching firmware"
544537 msgstr "正在获取固件"
545538
546539 #. TRANSLATORS: downloading unknown file
547 #: src/fu-util.c:728
540 #: src/fu-util.c:708
548541 msgid "Fetching file"
549542 msgstr "正在获取文件"
550543
551544 #. TRANSLATORS: section header for release version number
552 #: src/fu-util.c:898
545 #: src/fu-util.c:888
553546 msgid "Version"
554547 msgstr "版本"
555548
549 #. TRANSLATORS: section header for the remote the file is coming from
550 #: src/fu-util.c:891
551 msgid "Remote"
552 msgstr ""
553
556554 #. TRANSLATORS: section header for firmware URI
557 #: src/fu-util.c:901
555 #: src/fu-util.c:894
558556 msgid "URI"
559557 msgstr "URI"
560558
561559 #. TRANSLATORS: section header for firmware description
562 #: src/fu-util.c:907
560 #: src/fu-util.c:900
563561 msgid "Description"
564562 msgstr "描述"
565563
566564 #. TRANSLATORS: section header for firmware checksum
567 #: src/fu-util.c:915
565 #. TRANSLATORS: remote checksum
566 #: src/fu-util.c:908 src/fu-util.c:1136
568567 msgid "Checksum"
569568 msgstr "校验和"
570569
571570 #. TRANSLATORS: get interactive prompt
572 #: src/fu-util.c:947
571 #: src/fu-util.c:940
573572 msgid "Choose a release:"
574573 msgstr "选择发行版本:"
575574
576575 #. TRANSLATORS: first replacement is device name
577 #: src/fu-util.c:1036
576 #: src/fu-util.c:1041
578577 #, c-format
579578 msgid "%s has firmware updates:"
580579 msgstr "%s 有固件更新:"
581580
582 #: src/fu-util.c:1046
581 #: src/fu-util.c:1048
583582 msgid "GUID"
584583 msgstr "GUID"
585584
586585 #. TRANSLATORS: section header for firmware version
587 #: src/fu-util.c:1050
586 #: src/fu-util.c:1060
588587 msgid "Update Version"
589588 msgstr "更新版本"
590589
591590 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
592 #: src/fu-util.c:1054
591 #: src/fu-util.c:1064
593592 msgid "Update Remote ID"
594593 msgstr "更新远程 ID"
595594
596595 #. TRANSLATORS: section header for firmware checksum
597 #: src/fu-util.c:1063
596 #: src/fu-util.c:1073
598597 msgid "Update Checksum"
599598 msgstr "更新校验和"
600599
601600 #. TRANSLATORS: section header for firmware remote http://
602 #: src/fu-util.c:1067
601 #: src/fu-util.c:1077
603602 msgid "Update Location"
604603 msgstr "更新位置"
605604
606605 #. TRANSLATORS: section header for long firmware desc
607 #: src/fu-util.c:1078
606 #: src/fu-util.c:1088
608607 msgid "Update Description"
609608 msgstr "更新说明"
610609
611610 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
612 #: src/fu-util.c:1104
611 #: src/fu-util.c:1114
613612 msgid "Remote ID"
614613 msgstr "远程 ID"
615614
615 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
616 #: src/fu-util.c:1118
617 msgid "Title"
618 msgstr ""
619
616620 #. TRANSLATORS: remote type, e.g. remote or local
617 #: src/fu-util.c:1108
621 #: src/fu-util.c:1122
618622 msgid "Type"
619623 msgstr "类型"
620624
621 #: src/fu-util.c:1113
625 #: src/fu-util.c:1127
622626 msgid "Keyring"
623627 msgstr ""
624628
625629 #. TRANSLATORS: if the remote is enabled
626 #: src/fu-util.c:1118
630 #: src/fu-util.c:1132
627631 msgid "Enabled"
628632 msgstr "已启用"
629633
630634 #. TRANSLATORS: the age of the metadata
631 #: src/fu-util.c:1145
635 #: src/fu-util.c:1163
632636 msgid "Age"
633637 msgstr "已发布时间"
634638
635639 #. TRANSLATORS: the numeric priority
636 #: src/fu-util.c:1152
640 #: src/fu-util.c:1170
637641 msgid "Priority"
638642 msgstr "优先级"
639643
640644 #. TRANSLATORS: remote filename base
641 #: src/fu-util.c:1157
645 #: src/fu-util.c:1175
642646 msgid "Username"
643647 msgstr "用户名"
644648
645649 #. TRANSLATORS: remote filename base
646 #: src/fu-util.c:1162
650 #: src/fu-util.c:1180
647651 msgid "Password"
648652 msgstr "密码"
649653
650 #. TRANSLATORS: remote filename base
651 #: src/fu-util.c:1167
654 #. TRANSLATORS: filename of the local file
655 #: src/fu-util.c:1185
652656 msgid "Filename"
653657 msgstr "文件名"
654658
655 #. TRANSLATORS: remote filename base
656 #: src/fu-util.c:1172
659 #. TRANSLATORS: filename of the local file
660 #: src/fu-util.c:1190
657661 msgid "Filename Signature"
658662 msgstr "文件名签名"
659663
660 #. TRANSLATORS: locatation of the local file
661 #: src/fu-util.c:1177
662 msgid "Location"
663 msgstr "位置"
664
665 #. TRANSLATORS: locatation of the local file
666 #: src/fu-util.c:1182
667 msgid "Location Signature"
668 msgstr ""
669
670664 #. TRANSLATORS: remote URI
671 #: src/fu-util.c:1187
665 #: src/fu-util.c:1195
672666 msgid "Metadata URI"
673667 msgstr ""
674668
675669 #. TRANSLATORS: remote URI
676 #: src/fu-util.c:1192
670 #: src/fu-util.c:1200
677671 msgid "Metadata URI Signature"
678672 msgstr ""
679673
680674 #. TRANSLATORS: remote URI
681 #: src/fu-util.c:1197
675 #: src/fu-util.c:1205
682676 msgid "Firmware Base URI"
683677 msgstr ""
684678
685679 #. TRANSLATORS: this is when a device is hotplugged
686 #: src/fu-util.c:1224
680 #: src/fu-util.c:1232
687681 msgid "Device added:"
688682 msgstr "已添加设备:"
689683
690684 #. TRANSLATORS: this is when a device is hotplugged
691 #: src/fu-util.c:1234
685 #: src/fu-util.c:1242
692686 msgid "Device removed:"
693687 msgstr "已移除设备:"
694688
695689 #. TRANSLATORS: this is when a device has been updated
696 #: src/fu-util.c:1244
690 #: src/fu-util.c:1252
697691 msgid "Device changed:"
698692 msgstr "已更改设备:"
699693
700694 #. TRANSLATORS: command line option
701 #: src/fu-util.c:1568
695 #: src/fu-util.c:1595
702696 msgid "Show extra debugging information"
703697 msgstr "显示额外调试信息"
704698
705699 #. TRANSLATORS: command line option
706 #: src/fu-util.c:1571
700 #: src/fu-util.c:1598
707701 msgid "Show client and daemon versions"
708702 msgstr "显示客户端及守护程序版本"
709703
710704 #. TRANSLATORS: command line option
711 #: src/fu-util.c:1574
705 #: src/fu-util.c:1601
712706 msgid "Schedule installation for next reboot when possible"
713707 msgstr "如有可能,安排安装到下次重启"
714708
715709 #. TRANSLATORS: command line option
716 #: src/fu-util.c:1577
710 #: src/fu-util.c:1604
717711 msgid "Allow re-installing existing firmware versions"
718712 msgstr "允许重新安装现有的固件版本"
719713
720714 #. TRANSLATORS: command line option
721 #: src/fu-util.c:1580
715 #: src/fu-util.c:1607
722716 msgid "Allow downgrading firmware versions"
723717 msgstr "允许降级固件版本"
724718
725719 #. TRANSLATORS: command line option
726 #: src/fu-util.c:1583
720 #: src/fu-util.c:1610
727721 msgid "Override plugin warning"
728722 msgstr "忽略插件警告"
729723
730724 #. TRANSLATORS: command description
731 #: src/fu-util.c:1607
725 #: src/fu-util.c:1634
732726 msgid "Get all devices that support firmware updates"
733727 msgstr "获得所有支持更新固件的硬件列表"
734728
735729 #. TRANSLATORS: command description
736 #: src/fu-util.c:1613
730 #: src/fu-util.c:1640
737731 msgid "Return all the hardware IDs for the machine"
738732 msgstr "返回机器的所有硬件 ID"
739733
740734 #. TRANSLATORS: command description
741 #: src/fu-util.c:1619
735 #: src/fu-util.c:1646
742736 msgid "Install prepared updates now"
743737 msgstr "现在安装准备好的更新"
744738
745739 #. TRANSLATORS: command description
746 #: src/fu-util.c:1625
740 #: src/fu-util.c:1652
747741 msgid "Install a firmware file on this hardware"
748742 msgstr "安装此硬件上的固件文件"
749743
750744 #. TRANSLATORS: command description
751 #: src/fu-util.c:1631
745 #: src/fu-util.c:1658
752746 msgid "Gets details about a firmware file"
753747 msgstr "获取有关某固件文件的详细信息"
754748
755749 #. TRANSLATORS: command description
756 #: src/fu-util.c:1637
750 #: src/fu-util.c:1664
757751 msgid "Gets the list of updates for connected hardware"
758752 msgstr "获取已连接硬件的可用更新列表"
759753
760754 #. TRANSLATORS: command description
761 #: src/fu-util.c:1643
755 #: src/fu-util.c:1670
762756 msgid "Updates all firmware to latest versions available"
763757 msgstr "将所有固件都更新为最新版本"
764758
765759 #. TRANSLATORS: command description
766 #: src/fu-util.c:1649
760 #: src/fu-util.c:1676
767761 msgid "Gets the cryptographic hash of the dumped firmware"
768762 msgstr "获取转储出的固件的校验和"
769763
770764 #. TRANSLATORS: command description
771 #: src/fu-util.c:1655
765 #: src/fu-util.c:1682
772766 msgid "Unlocks the device for firmware access"
773767 msgstr "为固件访问解锁设备"
774768
775769 #. TRANSLATORS: command description
776 #: src/fu-util.c:1661
770 #: src/fu-util.c:1688
777771 msgid "Clears the results from the last update"
778772 msgstr "清除从最后一次更新获取的结果"
779773
780774 #. TRANSLATORS: command description
781 #: src/fu-util.c:1667
775 #: src/fu-util.c:1694
776 msgid "Clears any updates scheduled to be updated offline"
777 msgstr ""
778
779 #. TRANSLATORS: command description
780 #: src/fu-util.c:1700
782781 msgid "Gets the results from the last update"
783782 msgstr "从最后一次更新中获取结果"
784783
785784 #. TRANSLATORS: command description
786 #: src/fu-util.c:1673
785 #: src/fu-util.c:1706
787786 msgid "Gets the releases for a device"
788787 msgstr "获取用于设备的发行版本"
789788
790789 #. TRANSLATORS: command description
791 #: src/fu-util.c:1679
790 #: src/fu-util.c:1712
792791 msgid "Gets the configured remotes"
793792 msgstr "获取已配置的远程位置"
794793
795794 #. TRANSLATORS: command description
796 #: src/fu-util.c:1685
795 #: src/fu-util.c:1718
797796 msgid "Downgrades the firmware on a device"
798797 msgstr "降级设备上的固件"
799798
800799 #. TRANSLATORS: command description
801 #: src/fu-util.c:1691
800 #: src/fu-util.c:1724
802801 msgid "Refresh metadata from remote server"
803802 msgstr "刷新来自远程服务器的元数据"
804803
805804 #. TRANSLATORS: command description
806 #: src/fu-util.c:1697
805 #: src/fu-util.c:1730
807806 msgid "Update the stored metadata with current ROM contents"
808807 msgstr "使用目前的 ROM 内容更新存储的元数据"
809808
810809 #. TRANSLATORS: command description
811 #: src/fu-util.c:1703
810 #: src/fu-util.c:1736
812811 msgid "Monitor the daemon for events"
813812 msgstr "监视守护程序里的事件"
814813
815814 #. TRANSLATORS: command description
816 #: src/fu-util.c:1709
815 #: src/fu-util.c:1742
817816 msgid "Build firmware using a sandbox"
818817 msgstr ""
819818
819 #. TRANSLATORS: command description
820 #: src/fu-util.c:1748
821 msgid "Dump SMBIOS data from a file"
822 msgstr ""
823
824 #. TRANSLATORS: command description
825 #: src/fu-util.c:1754
826 msgid "Modifies a given remote"
827 msgstr ""
828
820829 #. TRANSLATORS: program name
821 #: src/fu-util.c:1728
830 #: src/fu-util.c:1773
822831 msgid "Firmware Utility"
823832 msgstr "固件实用程序"
77 msgstr ""
88 "Project-Id-Version: fwupd\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2017-09-01 14:26+0100\n"
11 "PO-Revision-Date: 2017-09-01 13:27+0000\n"
10 "POT-Creation-Date: 2017-10-09 10:22+0100\n"
11 "PO-Revision-Date: 2017-10-09 09:22+0000\n"
1212 "Last-Translator: Richard Hughes <richard@hughsie.com>\n"
1313 "Language-Team: Chinese (Taiwan) (http://www.transifex.com/freedesktop/fwupd/language/zh_TW/)\n"
1414 "MIME-Version: 1.0\n"
104104 "Authentication is required to update the stored checksums for the device"
105105 msgstr "必須先通過身份核對才能更新裝置的儲存校驗計算碼"
106106
107 #: policy/org.freedesktop.fwupd.policy.in:105
108 msgid "Modify a configured remote"
109 msgstr ""
110
111 #. TRANSLATORS: this is the PolicyKit modal dialog
112 #: policy/org.freedesktop.fwupd.policy.in:107
113 msgid ""
114 "Authentication is required to modify a configured remote used for firmware "
115 "updates"
116 msgstr ""
117
107118 #. TRANSLATORS: this is a command alias, e.g. 'get-devices'
108 #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115
119 #: plugins/dfu/dfu-tool.c:123 plugins/synapticsmst/synapticsmst-tool.c:113
109120 #: src/fu-util.c:112
110121 #, c-format
111122 msgid "Alias to %s"
112123 msgstr "%s 的別名"
113124
114125 #. TRANSLATORS: error message
115 #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362
126 #: plugins/dfu/dfu-tool.c:191 plugins/synapticsmst/synapticsmst-tool.c:354
116127 #: src/fu-util.c:176
117128 msgid "Command not found"
118129 msgstr "找不到指令"
119130
120 #. TRANSLATORS: read from device to host
121 #: libdfu/dfu-tool.c:1236
122 msgid "Reading"
123 msgstr "讀取中"
124
125 #. TRANSLATORS: write from host to device
126 #: libdfu/dfu-tool.c:1242
127 msgid "Writing"
128 msgstr "寫入中"
129
130 #. TRANSLATORS: read from device to host
131 #: libdfu/dfu-tool.c:1248
132 msgid "Verifying"
133 msgstr "核驗中"
134
135 #. TRANSLATORS: read from device to host
136 #: libdfu/dfu-tool.c:1254
137 msgid "Erasing"
138 msgstr "抹除中"
139
140 #. TRANSLATORS: waiting for device
141 #: libdfu/dfu-tool.c:1260
142 msgid "Detaching"
143 msgstr "解開連接中"
144
145 #. TRANSLATORS: waiting for device
146 #: libdfu/dfu-tool.c:1266
147 msgid "Attaching"
148 msgstr "連接中"
149
150131 #. TRANSLATORS: this is when a device is hotplugged
151 #: libdfu/dfu-tool.c:1487
132 #: plugins/dfu/dfu-tool.c:1440
152133 msgid "Added"
153134 msgstr "已加入"
154135
155136 #. TRANSLATORS: this is when a device is hotplugged
156 #: libdfu/dfu-tool.c:1498
137 #: plugins/dfu/dfu-tool.c:1451
157138 msgid "Removed"
158139 msgstr "已移除"
159140
160141 #. TRANSLATORS: this is when a device is hotplugged
161142 #. TRANSLATORS: this is when the daemon state changes
162 #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251
143 #: plugins/dfu/dfu-tool.c:1460 src/fu-util.c:1259
163144 msgid "Changed"
164145 msgstr "已變更"
165146
166147 #. TRANSLATORS: this is when a device ctrl+c's a watch
167 #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213
148 #: plugins/dfu/dfu-tool.c:1468 src/fu-util.c:1221
168149 msgid "Cancelled"
169150 msgstr "已取消"
170151
171152 #. TRANSLATORS: Appstream ID for the hardware type
172 #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040
153 #: plugins/dfu/dfu-tool.c:1966 src/fu-util.c:1057
173154 msgid "ID"
174155 msgstr "ID"
175156
176157 #. TRANSLATORS: interface name, e.g. "Flash"
177158 #. TRANSLATORS: device name, e.g. 'ColorHug2'
178 #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123
159 #: plugins/dfu/dfu-tool.c:1972 plugins/dfu/dfu-tool.c:1978
160 #: plugins/dfu/dfu-tool.c:2065
179161 msgid "Name"
180162 msgstr "名稱"
181163
182164 #. TRANSLATORS: this is the encryption method used when writing
183 #: libdfu/dfu-tool.c:2043
165 #: plugins/dfu/dfu-tool.c:1985
184166 msgid "Cipher"
185167 msgstr "加密法"
186168
187169 #. TRANSLATORS: these are areas of memory on the chip
188 #: libdfu/dfu-tool.c:2057
170 #: plugins/dfu/dfu-tool.c:1999
189171 msgid "Region"
190172 msgstr "地區"
191173
192174 #. TRANSLATORS: detected a DFU device
193 #: libdfu/dfu-tool.c:2092
175 #: plugins/dfu/dfu-tool.c:2033
194176 msgid "Found"
195177 msgstr "找到"
196178
197179 #. TRANSLATORS: DFU protocol version, e.g. 1.1
198 #: libdfu/dfu-tool.c:2100
180 #: plugins/dfu/dfu-tool.c:2041
199181 msgid "Protocol"
200182 msgstr "協定"
201183
202184 #. TRANSLATORS: probably not run as root...
203185 #. TRANSLATORS: device has failed to report status
204186 #. TRANSLATORS: device status, e.g. "OK"
205 #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138
187 #: plugins/dfu/dfu-tool.c:2054 plugins/dfu/dfu-tool.c:2057
188 #: plugins/dfu/dfu-tool.c:2080
206189 msgid "Status"
207190 msgstr "狀態"
208191
209 #: libdfu/dfu-tool.c:2112
192 #: plugins/dfu/dfu-tool.c:2054
210193 msgid "Unknown: permission denied"
211194 msgstr "未知:權限不足"
212195
213196 #. TRANSLATORS: serial number, e.g. '00012345'
214 #: libdfu/dfu-tool.c:2129
197 #: plugins/dfu/dfu-tool.c:2071
215198 msgid "Serial"
216199 msgstr "序號"
217200
218201 #. TRANSLATORS: device mode, e.g. runtime or DFU
219 #: libdfu/dfu-tool.c:2134
202 #: plugins/dfu/dfu-tool.c:2076
220203 msgid "Mode"
221204 msgstr "模式"
222205
223206 #. TRANSLATORS: device state, i.e. appIDLE
224 #: libdfu/dfu-tool.c:2142
207 #: plugins/dfu/dfu-tool.c:2084
225208 msgid "State"
226209 msgstr "狀態"
227210
228211 #. TRANSLATORS: transfer size in bytes
229 #: libdfu/dfu-tool.c:2150
212 #: plugins/dfu/dfu-tool.c:2092
230213 msgid "Transfer Size"
231214 msgstr "傳輸大小"
232215
233216 #. TRANSLATORS: device quirks, i.e. things that
234217 #. * it does that we have to work around
235 #: libdfu/dfu-tool.c:2158
218 #: plugins/dfu/dfu-tool.c:2100
236219 msgid "Quirks"
237220 msgstr "奇技淫巧"
238221
239222 #. TRANSLATORS: command description
240 #: libdfu/dfu-tool.c:2237
223 #: plugins/dfu/dfu-tool.c:2181
241224 msgid "Convert firmware to DFU format"
242225 msgstr "將韌體轉換為 DFU 格式"
243226
244227 #. TRANSLATORS: command description
245 #: libdfu/dfu-tool.c:2243
228 #: plugins/dfu/dfu-tool.c:2187
246229 msgid "Merge multiple firmware files into one"
247230 msgstr "合併多份韌體檔案為一份"
248231
249232 #. TRANSLATORS: command description
250 #: libdfu/dfu-tool.c:2249
233 #: plugins/dfu/dfu-tool.c:2193
251234 msgid "Set vendor ID on firmware file"
252235 msgstr "設定韌體檔案廠商 ID"
253236
254237 #. TRANSLATORS: command description
255 #: libdfu/dfu-tool.c:2255
238 #: plugins/dfu/dfu-tool.c:2199
256239 msgid "Set product ID on firmware file"
257240 msgstr "設定韌體檔案產品 ID"
258241
259242 #. TRANSLATORS: command description
260 #: libdfu/dfu-tool.c:2261
243 #: plugins/dfu/dfu-tool.c:2205
261244 msgid "Set element address on firmware file"
262245 msgstr "設定韌體檔案元素位址"
263246
264247 #. TRANSLATORS: command description
265 #: libdfu/dfu-tool.c:2267
248 #: plugins/dfu/dfu-tool.c:2211
266249 msgid "Set the firmware size for the target"
267250 msgstr "設定目標的韌體檔案大小"
268251
269252 #. TRANSLATORS: command description
270 #: libdfu/dfu-tool.c:2273
253 #: plugins/dfu/dfu-tool.c:2217
271254 msgid "Set release version on firmware file"
272255 msgstr "設定韌體檔案發行版本"
273256
274257 #. TRANSLATORS: command description
275 #: libdfu/dfu-tool.c:2279
258 #: plugins/dfu/dfu-tool.c:2223
276259 msgid "Set alternative number on firmware file"
277260 msgstr "設定韌體檔案替代編號"
278261
279262 #. TRANSLATORS: command description
280 #: libdfu/dfu-tool.c:2285
263 #: plugins/dfu/dfu-tool.c:2229
281264 msgid "Set alternative name on firmware file"
282265 msgstr "設定韌體檔案替代名稱"
283266
284267 #. TRANSLATORS: command description
285 #: libdfu/dfu-tool.c:2291
268 #: plugins/dfu/dfu-tool.c:2235
286269 msgid "Attach DFU capable device back to runtime"
287270 msgstr "將 DFU 能力裝置接回執行時期"
288271
289272 #. TRANSLATORS: command description
290 #: libdfu/dfu-tool.c:2297
273 #: plugins/dfu/dfu-tool.c:2241
291274 msgid "Read firmware from device into a file"
292275 msgstr "將裝置的韌體讀取為檔案"
293276
294277 #. TRANSLATORS: command description
295 #: libdfu/dfu-tool.c:2303
278 #: plugins/dfu/dfu-tool.c:2247
296279 msgid "Read firmware from one partition into a file"
297280 msgstr "從一分割區將韌體讀取為檔案"
298281
299282 #. TRANSLATORS: command description
300 #: libdfu/dfu-tool.c:2309
283 #: plugins/dfu/dfu-tool.c:2253
301284 msgid "Write firmware from file into device"
302285 msgstr "從檔案將韌體寫入裝置"
303286
304287 #. TRANSLATORS: command description
305 #: libdfu/dfu-tool.c:2315
288 #: plugins/dfu/dfu-tool.c:2259
306289 msgid "Write firmware from file into one partition"
307290 msgstr "從檔案將韌體寫入一分割區"
308291
309292 #. TRANSLATORS: command description
310 #: libdfu/dfu-tool.c:2321
293 #: plugins/dfu/dfu-tool.c:2265
311294 msgid "List currently attached DFU capable devices"
312295 msgstr "列出目前接上的 DFU 能力裝置"
313296
314297 #. TRANSLATORS: command description
315 #: libdfu/dfu-tool.c:2327
298 #: plugins/dfu/dfu-tool.c:2271
316299 msgid "Detach currently attached DFU capable device"
317300 msgstr "解開目前接上的 DFU 能力裝置"
318301
319302 #. TRANSLATORS: command description
320 #: libdfu/dfu-tool.c:2333
303 #: plugins/dfu/dfu-tool.c:2277
321304 msgid "Dump details about a firmware file"
322305 msgstr "傾印韌體檔案的相關細節"
323306
324307 #. TRANSLATORS: command description
325 #: libdfu/dfu-tool.c:2339
308 #: plugins/dfu/dfu-tool.c:2283
326309 msgid "Watch DFU devices being hotplugged"
327310 msgstr "監看 DFU 裝置熱插拔的過程"
328311
329312 #. TRANSLATORS: command description
330 #: libdfu/dfu-tool.c:2345
313 #: plugins/dfu/dfu-tool.c:2289
331314 msgid "Encrypt firmware data"
332315 msgstr "加密韌體資料"
333316
334317 #. TRANSLATORS: command description
335 #: libdfu/dfu-tool.c:2351
318 #: plugins/dfu/dfu-tool.c:2295
336319 msgid "Decrypt firmware data"
337320 msgstr "解密韌體資料"
338321
339322 #. TRANSLATORS: command description
340 #: libdfu/dfu-tool.c:2357
323 #: plugins/dfu/dfu-tool.c:2301
341324 msgid "Sets metadata on a firmware file"
342325 msgstr "設定韌體檔案的中介資料"
343326
344327 #. TRANSLATORS: command description
345 #: libdfu/dfu-tool.c:2363
328 #: plugins/dfu/dfu-tool.c:2307
346329 msgid "Replace data in an existing firmware file"
347330 msgstr "取代既有韌體檔案中的資料"
348331
349332 #. TRANSLATORS: command description
350 #: libdfu/dfu-tool.c:2369
333 #: plugins/dfu/dfu-tool.c:2313
351334 msgid "Create a binary patch using two files"
352335 msgstr "根據兩份檔案製作二進位補丁"
353336
354337 #. TRANSLATORS: command description
355 #: libdfu/dfu-tool.c:2375
338 #: plugins/dfu/dfu-tool.c:2319
356339 msgid "Apply a binary patch"
357340 msgstr "套用二進位補丁"
358341
359342 #. TRANSLATORS: command description
360 #: libdfu/dfu-tool.c:2381
343 #: plugins/dfu/dfu-tool.c:2325
361344 msgid "Dump information about a binary patch to the screen"
362345 msgstr "傾印二進位補丁相關資訊至螢幕上"
363346
364347 #. TRANSLATORS: DFU stands for device firmware update
365 #: libdfu/dfu-tool.c:2407
348 #: plugins/dfu/dfu-tool.c:2351
366349 msgid "DFU Utility"
367350 msgstr "DFU 公用程式"
368351
369352 #. TRANSLATORS: the user didn't read the man page
370 #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439
371 #: src/fu-util.c:1733
353 #: plugins/dfu/dfu-tool.c:2356 plugins/synapticsmst/synapticsmst-tool.c:431
354 #: src/fu-util.c:1778
372355 msgid "Failed to parse arguments"
373356 msgstr "無法解析引數"
374357
375358 #. TRANSLATORS: command description
376 #: plugins/synapticsmst/synapticsmst-tool.c:408
359 #: plugins/synapticsmst/synapticsmst-tool.c:400
377360 msgid "Enumerate all Synaptics MST devices"
378361 msgstr "枚舉所有 Synaptics MST 裝置"
379362
380363 #. TRANSLATORS: command description
381 #: plugins/synapticsmst/synapticsmst-tool.c:414
364 #: plugins/synapticsmst/synapticsmst-tool.c:406
382365 msgid "Flash firmware file to MST device"
383366 msgstr "刷寫韌體檔案至 MST 裝置"
384367
385 #: plugins/synapticsmst/synapticsmst-tool.c:434
368 #: plugins/synapticsmst/synapticsmst-tool.c:426
386369 msgid "Synaptics Multistream Transport Utility"
387370 msgstr "Synaptics 多串流傳輸公用程式"
388371
389372 #. TRANSLATORS: this is shown when updating the firmware after the reboot
390 #: plugins/uefi/fu-plugin-uefi.c:194
373 #: plugins/uefi/fu-plugin-uefi.c:396
391374 msgid "Installing firmware update…"
392375 msgstr "安裝韌體更新中…"
393376
407390 msgstr "顯示除錯選項"
408391
409392 #. TRANSLATORS: exit after we've started up, used for user profiling
410 #: src/fu-main.c:863
393 #: src/fu-main.c:960
411394 msgid "Exit after a small delay"
412395 msgstr "經過一段短暫延遲後便離開"
413396
414397 #. TRANSLATORS: exit straight away, used for automatic profiling
415 #: src/fu-main.c:866
398 #: src/fu-main.c:963
416399 msgid "Exit after the engine has loaded"
417400 msgstr "引擎載入後離開"
418401
419402 #. TRANSLATORS: program name
420 #: src/fu-main.c:880
403 #: src/fu-main.c:977
421404 msgid "Firmware Update Daemon"
422405 msgstr "韌體更新幕後程式"
423406
424407 #. TRANSLATORS: program summary
425 #: src/fu-main.c:885
408 #: src/fu-main.c:982
426409 msgid "Firmware Update D-Bus Service"
427410 msgstr "韌體更新 D-Bus 服務"
428411
429412 #. TRANSLATORS: daemon is inactive
430 #: src/fu-progressbar.c:51
413 #: src/fu-progressbar.c:52
431414 msgid "Idle…"
432415 msgstr "閒置…"
433416
434417 #. TRANSLATORS: decompressing the firmware file
435 #: src/fu-progressbar.c:55
418 #: src/fu-progressbar.c:56
436419 msgid "Decompressing…"
437420 msgstr "解壓縮中…"
438421
439422 #. TRANSLATORS: parsing the firmware information
440 #: src/fu-progressbar.c:59
423 #: src/fu-progressbar.c:60
441424 msgid "Loading…"
442425 msgstr "載入中…"
443426
444427 #. TRANSLATORS: restarting the device to pick up new F/W
445 #: src/fu-progressbar.c:63
428 #: src/fu-progressbar.c:64
446429 msgid "Restarting device…"
447430 msgstr "重新啓動裝置中…"
448431
432 #. TRANSLATORS: reading from the flash chips
433 #: src/fu-progressbar.c:68
434 msgid "Reading…"
435 msgstr ""
436
449437 #. TRANSLATORS: writing to the flash chips
450 #: src/fu-progressbar.c:67
438 #: src/fu-progressbar.c:72
451439 msgid "Writing…"
452440 msgstr "寫入中…"
453441
442 #. TRANSLATORS: erasing contents of the flash chips
443 #: src/fu-progressbar.c:76
444 msgid "Erasing…"
445 msgstr ""
446
454447 #. TRANSLATORS: verifying we wrote the firmware correctly
455 #: src/fu-progressbar.c:71
448 #: src/fu-progressbar.c:80
456449 msgid "Verifying…"
457450 msgstr "核驗中…"
458451
459452 #. TRANSLATORS: scheduing an update to be done on the next boot
460 #: src/fu-progressbar.c:75
453 #: src/fu-progressbar.c:84
461454 msgid "Scheduling…"
462455 msgstr "排程中…"
463456
464457 #. TRANSLATORS: downloading from a remote server
465 #: src/fu-progressbar.c:79
458 #: src/fu-progressbar.c:88
466459 msgid "Downloading…"
467460 msgstr "下載中…"
468461
462 #. TRANSLATORS: waiting for user to authenticate
463 #: src/fu-progressbar.c:92
464 msgid "Authenticating…"
465 msgstr ""
466
469467 #. TRANSLATORS: currect daemon status is unknown
470 #: src/fu-progressbar.c:86
468 #: src/fu-progressbar.c:99
471469 msgid "Unknown"
472470 msgstr "未知"
473471
487485 msgid "No hardware detected with firmware update capability"
488486 msgstr "未偵測到具備韌體更新能力的硬體"
489487
490 #. TRANSLATOR: the plugin only supports offline
491 #: src/fu-util.c:337
492 msgid "Retrying as an offline update"
493 msgstr "以離線更新方式重試"
494
495488 #. TRANSLATORS: the first replacement is a display name
496489 #. * e.g. "ColorHugALS" and the second is a version number
497490 #. * e.g. "1.2.3"
498 #: src/fu-util.c:501
491 #: src/fu-util.c:474
499492 #, c-format
500493 msgid "Reinstalling %s with %s... "
501494 msgstr "正重新安裝 %s %s 版…"
503496 #. TRANSLATORS: the first replacement is a display name
504497 #. * e.g. "ColorHugALS" and the second and third are
505498 #. * version numbers e.g. "1.2.3"
506 #: src/fu-util.c:508
499 #: src/fu-util.c:481
507500 #, c-format
508501 msgid "Downgrading %s from %s to %s... "
509502 msgstr "正降級 %s 從 %s 版至 %s 版…"
511504 #. TRANSLATORS: the first replacement is a display name
512505 #. * e.g. "ColorHugALS" and the second and third are
513506 #. * version numbers e.g. "1.2.3"
514 #: src/fu-util.c:516
507 #: src/fu-util.c:489
515508 #, c-format
516509 msgid "Updating %s from %s to %s... "
517510 msgstr "正更新 %s 從 %s 版至 %s 版…"
518511
519 #: src/fu-util.c:543
512 #: src/fu-util.c:516
520513 msgid "Done!"
521514 msgstr "完成!"
522515
523 #: src/fu-util.c:585 src/fu-util.c:985
516 #: src/fu-util.c:565 src/fu-util.c:978
524517 msgid "OK"
525518 msgstr "確定"
526519
527520 #. TRANSLATORS: downloading new signing file
528 #: src/fu-util.c:719
521 #: src/fu-util.c:699
529522 msgid "Fetching signature"
530523 msgstr "擷取簽章中"
531524
532525 #. TRANSLATORS: downloading new metadata file
533 #: src/fu-util.c:722
526 #: src/fu-util.c:702
534527 msgid "Fetching metadata"
535528 msgstr "擷取中介資料中"
536529
537530 #. TRANSLATORS: downloading new firmware file
538 #: src/fu-util.c:725
531 #: src/fu-util.c:705
539532 msgid "Fetching firmware"
540533 msgstr "擷取韌體中"
541534
542535 #. TRANSLATORS: downloading unknown file
543 #: src/fu-util.c:728
536 #: src/fu-util.c:708
544537 msgid "Fetching file"
545538 msgstr "擷取檔案中"
546539
547540 #. TRANSLATORS: section header for release version number
548 #: src/fu-util.c:898
541 #: src/fu-util.c:888
549542 msgid "Version"
550543 msgstr "版本"
551544
545 #. TRANSLATORS: section header for the remote the file is coming from
546 #: src/fu-util.c:891
547 msgid "Remote"
548 msgstr ""
549
552550 #. TRANSLATORS: section header for firmware URI
553 #: src/fu-util.c:901
551 #: src/fu-util.c:894
554552 msgid "URI"
555553 msgstr "URI"
556554
557555 #. TRANSLATORS: section header for firmware description
558 #: src/fu-util.c:907
556 #: src/fu-util.c:900
559557 msgid "Description"
560558 msgstr "描述說明"
561559
562560 #. TRANSLATORS: section header for firmware checksum
563 #: src/fu-util.c:915
561 #. TRANSLATORS: remote checksum
562 #: src/fu-util.c:908 src/fu-util.c:1136
564563 msgid "Checksum"
565564 msgstr "校驗計算碼"
566565
567566 #. TRANSLATORS: get interactive prompt
568 #: src/fu-util.c:947
567 #: src/fu-util.c:940
569568 msgid "Choose a release:"
570569 msgstr "選擇發行版:"
571570
572571 #. TRANSLATORS: first replacement is device name
573 #: src/fu-util.c:1036
572 #: src/fu-util.c:1041
574573 #, c-format
575574 msgid "%s has firmware updates:"
576575 msgstr "%s 有韌體更新:"
577576
578 #: src/fu-util.c:1046
577 #: src/fu-util.c:1048
579578 msgid "GUID"
580579 msgstr "GUID"
581580
582581 #. TRANSLATORS: section header for firmware version
583 #: src/fu-util.c:1050
582 #: src/fu-util.c:1060
584583 msgid "Update Version"
585584 msgstr "更新版本"
586585
587586 #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing
588 #: src/fu-util.c:1054
587 #: src/fu-util.c:1064
589588 msgid "Update Remote ID"
590589 msgstr "更新遠端 ID"
591590
592591 #. TRANSLATORS: section header for firmware checksum
593 #: src/fu-util.c:1063
592 #: src/fu-util.c:1073
594593 msgid "Update Checksum"
595594 msgstr "更新校驗計算碼"
596595
597596 #. TRANSLATORS: section header for firmware remote http://
598 #: src/fu-util.c:1067
597 #: src/fu-util.c:1077
599598 msgid "Update Location"
600599 msgstr "更新位置"
601600
602601 #. TRANSLATORS: section header for long firmware desc
603 #: src/fu-util.c:1078
602 #: src/fu-util.c:1088
604603 msgid "Update Description"
605604 msgstr "更新描述說明"
606605
607606 #. TRANSLATORS: remote identifier, e.g. lvfs-testing
608 #: src/fu-util.c:1104
607 #: src/fu-util.c:1114
609608 msgid "Remote ID"
610609 msgstr "遠端 ID"
611610
611 #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service"
612 #: src/fu-util.c:1118
613 msgid "Title"
614 msgstr ""
615
612616 #. TRANSLATORS: remote type, e.g. remote or local
613 #: src/fu-util.c:1108
617 #: src/fu-util.c:1122
614618 msgid "Type"
615619 msgstr "類型"
616620
617 #: src/fu-util.c:1113
621 #: src/fu-util.c:1127
618622 msgid "Keyring"
619623 msgstr ""
620624
621625 #. TRANSLATORS: if the remote is enabled
622 #: src/fu-util.c:1118
626 #: src/fu-util.c:1132
623627 msgid "Enabled"
624628 msgstr "啟用"
625629
626630 #. TRANSLATORS: the age of the metadata
627 #: src/fu-util.c:1145
631 #: src/fu-util.c:1163
628632 msgid "Age"
629633 msgstr "年紀"
630634
631635 #. TRANSLATORS: the numeric priority
632 #: src/fu-util.c:1152
636 #: src/fu-util.c:1170
633637 msgid "Priority"
634638 msgstr "優先等級"
635639
636640 #. TRANSLATORS: remote filename base
637 #: src/fu-util.c:1157
641 #: src/fu-util.c:1175
638642 msgid "Username"
639643 msgstr "使用者名稱"
640644
641645 #. TRANSLATORS: remote filename base
642 #: src/fu-util.c:1162
646 #: src/fu-util.c:1180
643647 msgid "Password"
644648 msgstr "密碼"
645649
646 #. TRANSLATORS: remote filename base
647 #: src/fu-util.c:1167
650 #. TRANSLATORS: filename of the local file
651 #: src/fu-util.c:1185
648652 msgid "Filename"
649653 msgstr "檔名"
650654
651 #. TRANSLATORS: remote filename base
652 #: src/fu-util.c:1172
655 #. TRANSLATORS: filename of the local file
656 #: src/fu-util.c:1190
653657 msgid "Filename Signature"
654658 msgstr "檔名簽章"
655659
656 #. TRANSLATORS: locatation of the local file
657 #: src/fu-util.c:1177
658 msgid "Location"
659 msgstr "位置"
660
661 #. TRANSLATORS: locatation of the local file
662 #: src/fu-util.c:1182
663 msgid "Location Signature"
664 msgstr ""
665
666660 #. TRANSLATORS: remote URI
667 #: src/fu-util.c:1187
661 #: src/fu-util.c:1195
668662 msgid "Metadata URI"
669663 msgstr ""
670664
671665 #. TRANSLATORS: remote URI
672 #: src/fu-util.c:1192
666 #: src/fu-util.c:1200
673667 msgid "Metadata URI Signature"
674668 msgstr ""
675669
676670 #. TRANSLATORS: remote URI
677 #: src/fu-util.c:1197
671 #: src/fu-util.c:1205
678672 msgid "Firmware Base URI"
679673 msgstr ""
680674
681675 #. TRANSLATORS: this is when a device is hotplugged
682 #: src/fu-util.c:1224
676 #: src/fu-util.c:1232
683677 msgid "Device added:"
684678 msgstr "裝置已加入:"
685679
686680 #. TRANSLATORS: this is when a device is hotplugged
687 #: src/fu-util.c:1234
681 #: src/fu-util.c:1242
688682 msgid "Device removed:"
689683 msgstr "裝置已移除:"
690684
691685 #. TRANSLATORS: this is when a device has been updated
692 #: src/fu-util.c:1244
686 #: src/fu-util.c:1252
693687 msgid "Device changed:"
694688 msgstr "裝置已變更:"
695689
696690 #. TRANSLATORS: command line option
697 #: src/fu-util.c:1568
691 #: src/fu-util.c:1595
698692 msgid "Show extra debugging information"
699693 msgstr "顯示額外除錯資訊"
700694
701695 #. TRANSLATORS: command line option
702 #: src/fu-util.c:1571
696 #: src/fu-util.c:1598
703697 msgid "Show client and daemon versions"
704698 msgstr "顯示客戶端與幕後程式版本"
705699
706700 #. TRANSLATORS: command line option
707 #: src/fu-util.c:1574
701 #: src/fu-util.c:1601
708702 msgid "Schedule installation for next reboot when possible"
709703 msgstr "安排下次重新開機時若可行便安裝"
710704
711705 #. TRANSLATORS: command line option
712 #: src/fu-util.c:1577
706 #: src/fu-util.c:1604
713707 msgid "Allow re-installing existing firmware versions"
714708 msgstr "允許重新安裝既有的韌體版本"
715709
716710 #. TRANSLATORS: command line option
717 #: src/fu-util.c:1580
711 #: src/fu-util.c:1607
718712 msgid "Allow downgrading firmware versions"
719713 msgstr "允許降級韌體版本"
720714
721715 #. TRANSLATORS: command line option
722 #: src/fu-util.c:1583
716 #: src/fu-util.c:1610
723717 msgid "Override plugin warning"
724718 msgstr "凌駕插件警告"
725719
726720 #. TRANSLATORS: command description
727 #: src/fu-util.c:1607
721 #: src/fu-util.c:1634
728722 msgid "Get all devices that support firmware updates"
729723 msgstr "取得所有支援韌體更新的裝置"
730724
731725 #. TRANSLATORS: command description
732 #: src/fu-util.c:1613
726 #: src/fu-util.c:1640
733727 msgid "Return all the hardware IDs for the machine"
734728 msgstr "回傳所有機器的硬體 ID"
735729
736730 #. TRANSLATORS: command description
737 #: src/fu-util.c:1619
731 #: src/fu-util.c:1646
738732 msgid "Install prepared updates now"
739733 msgstr "立刻安裝準備的更新"
740734
741735 #. TRANSLATORS: command description
742 #: src/fu-util.c:1625
736 #: src/fu-util.c:1652
743737 msgid "Install a firmware file on this hardware"
744738 msgstr "在此硬體安裝韌體檔案"
745739
746740 #. TRANSLATORS: command description
747 #: src/fu-util.c:1631
741 #: src/fu-util.c:1658
748742 msgid "Gets details about a firmware file"
749743 msgstr "取得韌體檔案的相關細節"
750744
751745 #. TRANSLATORS: command description
752 #: src/fu-util.c:1637
746 #: src/fu-util.c:1664
753747 msgid "Gets the list of updates for connected hardware"
754748 msgstr "取得連接硬體的更新清單"
755749
756750 #. TRANSLATORS: command description
757 #: src/fu-util.c:1643
751 #: src/fu-util.c:1670
758752 msgid "Updates all firmware to latest versions available"
759753 msgstr "將所有韌體更新至可用的最新版本"
760754
761755 #. TRANSLATORS: command description
762 #: src/fu-util.c:1649
756 #: src/fu-util.c:1676
763757 msgid "Gets the cryptographic hash of the dumped firmware"
764758 msgstr "取得傾印韌體檔案的加密雜湊"
765759
766760 #. TRANSLATORS: command description
767 #: src/fu-util.c:1655
761 #: src/fu-util.c:1682
768762 msgid "Unlocks the device for firmware access"
769763 msgstr "解鎖裝置以供韌體存取"
770764
771765 #. TRANSLATORS: command description
772 #: src/fu-util.c:1661
766 #: src/fu-util.c:1688
773767 msgid "Clears the results from the last update"
774768 msgstr "清除上次更新的結果"
775769
776770 #. TRANSLATORS: command description
777 #: src/fu-util.c:1667
771 #: src/fu-util.c:1694
772 msgid "Clears any updates scheduled to be updated offline"
773 msgstr ""
774
775 #. TRANSLATORS: command description
776 #: src/fu-util.c:1700
778777 msgid "Gets the results from the last update"
779778 msgstr "取得上次更新的結果"
780779
781780 #. TRANSLATORS: command description
782 #: src/fu-util.c:1673
781 #: src/fu-util.c:1706
783782 msgid "Gets the releases for a device"
784783 msgstr "取得裝置的發行版本"
785784
786785 #. TRANSLATORS: command description
787 #: src/fu-util.c:1679
786 #: src/fu-util.c:1712
788787 msgid "Gets the configured remotes"
789788 msgstr "取得設定的遠端"
790789
791790 #. TRANSLATORS: command description
792 #: src/fu-util.c:1685
791 #: src/fu-util.c:1718
793792 msgid "Downgrades the firmware on a device"
794793 msgstr "降級裝置的韌體"
795794
796795 #. TRANSLATORS: command description
797 #: src/fu-util.c:1691
796 #: src/fu-util.c:1724
798797 msgid "Refresh metadata from remote server"
799798 msgstr "重整遠端伺服器的中介資料"
800799
801800 #. TRANSLATORS: command description
802 #: src/fu-util.c:1697
801 #: src/fu-util.c:1730
803802 msgid "Update the stored metadata with current ROM contents"
804803 msgstr "以目前 ROM 內容更新儲存的中介資料"
805804
806805 #. TRANSLATORS: command description
807 #: src/fu-util.c:1703
806 #: src/fu-util.c:1736
808807 msgid "Monitor the daemon for events"
809808 msgstr "監控幕後程式是否有活動"
810809
811810 #. TRANSLATORS: command description
812 #: src/fu-util.c:1709
811 #: src/fu-util.c:1742
813812 msgid "Build firmware using a sandbox"
814813 msgstr ""
815814
815 #. TRANSLATORS: command description
816 #: src/fu-util.c:1748
817 msgid "Dump SMBIOS data from a file"
818 msgstr ""
819
820 #. TRANSLATORS: command description
821 #: src/fu-util.c:1754
822 msgid "Modifies a given remote"
823 msgstr ""
824
816825 #. TRANSLATORS: program name
817 #: src/fu-util.c:1728
826 #: src/fu-util.c:1773
818827 msgid "Firmware Utility"
819828 msgstr "韌體公用程式"
100100 </defaults>
101101 </action>
102102
103 <action id="org.freedesktop.fwupd.modify-remote">
104 <description>Modify a configured remote</description>
105 <!-- TRANSLATORS: this is the PolicyKit modal dialog -->
106 <message>Authentication is required to modify a configured remote used for firmware updates</message>
107 <defaults>
108 <allow_any>auth_admin</allow_any>
109 <allow_inactive>no</allow_inactive>
110 <allow_active>auth_admin_keep</allow_active>
111 </defaults>
112 </action>
113
103114 </policyconfig>
3030 #include "fwupd-error.h"
3131
3232 #include "fu-common.h"
33
34 /**
35 * SECTION:fu-common
36 * @short_description: common functionality for plugins to use
37 *
38 * Helper functions that can be used by the daemon and plugins.
39 *
40 * See also: #FuPlugin
41 */
3342
3443 /**
3544 * fu_common_rmtree:
166175 *
167176 * Note: this will close the fd when done
168177 *
169 * Returns: (transfer container): a #GBytes, or %NULL
178 * Returns: (transfer full): a #GBytes, or %NULL
170179 **/
171180 GBytes *
172181 fu_common_get_contents_fd (gint fd, gsize count, GError **error)
212221 /**
213222 * fu_common_extract_archive:
214223 * @blob: a #GBytes archive as a blob
215 * @directory: a directory name to extract to
224 * @dir: a directory name to extract to
216225 * @error: A #GError, or %NULL
217226 *
218227 * Extracts an achive to a directory.
304313 /**
305314 * fu_common_firmware_builder:
306315 * @bytes: The data to use
307 * @script_fn: Name of the script to run in the tarball, e.g. "startup.sh"
308 * @output_fn: Name of the generated firmware, e.g. "firmware.bin"
316 * @script_fn: Name of the script to run in the tarball, e.g. `startup.sh`
317 * @output_fn: Name of the generated firmware, e.g. `firmware.bin`
309318 * @error: A #GError, or %NULL
310319 *
311320 * Builds a firmware file using tools from the host session in a bubblewrap
489498 /**
490499 * fu_common_spawn_sync:
491500 * @argv: The argument list to run
492 * @handler_cb: A #FuOutputHandler or %NULL
493 * @handler_user_data: the user data to pass to @handler
501 * @handler_cb: (scope call): A #FuOutputHandler or %NULL
502 * @handler_user_data: the user data to pass to @handler_cb
494503 * @cancellable: a #GCancellable, or %NULL
495504 * @error: A #GError or %NULL
496505 *
2121 #ifndef __FU_COMMON_H__
2222 #define __FU_COMMON_H__
2323
24 #include <glib.h>
24 #include <gio/gio.h>
2525
2626 typedef void (*FuOutputHandler) (const gchar *line,
2727 gpointer user_data);
2828
2929 gboolean fu_common_spawn_sync (const gchar * const *argv,
30 FuOutputHandler handler,
30 FuOutputHandler handler_cb,
3131 gpointer handler_user_data,
3232 GCancellable *cancellable,
3333 GError **error);
3737 gboolean fu_common_mkdir_parent (const gchar *filename,
3838 GError **error);
3939 gboolean fu_common_set_contents_bytes (const gchar *filename,
40 GBytes *blob,
40 GBytes *bytes,
4141 GError **error);
4242 GBytes *fu_common_get_contents_bytes (const gchar *filename,
4343 GError **error);
3838 GPtrArray *monitors;
3939 GPtrArray *blacklist_devices;
4040 GPtrArray *blacklist_plugins;
41 gboolean enable_option_rom;
4241 };
4342
4443 G_DEFINE_TYPE (FuConfig, fu_config, G_TYPE_OBJECT)
45
46 static const gchar *
47 fu_config_get_sysconfig_dir (void)
48 {
49 if (g_file_test (SYSCONFDIR, G_FILE_TEST_EXISTS))
50 return SYSCONFDIR;
51 return "/etc";
52 }
5344
5445 static GPtrArray *
5546 fu_config_get_config_paths (void)
5748 GPtrArray *paths = g_ptr_array_new_with_free_func (g_free);
5849 const gchar *remotes_dir;
5950 const gchar *system_prefixlibdir = "/usr/lib/fwupd";
60 const gchar *system_sysconfdir = "/etc/fwupd";
6151 g_autofree gchar *sysconfdir = NULL;
6252
6353 /* only set by the self test program */
6858 }
6959
7060 /* use sysconfig, and then fall back to /etc */
71 sysconfdir = g_build_filename (SYSCONFDIR, "fwupd", NULL);
72 if (g_file_test (sysconfdir, G_FILE_TEST_EXISTS)) {
61 sysconfdir = g_build_filename (FWUPDCONFIGDIR, NULL);
62 if (g_file_test (sysconfdir, G_FILE_TEST_EXISTS))
7363 g_ptr_array_add (paths, g_steal_pointer (&sysconfdir));
74 } else {
75 g_debug ("falling back to system path");
76 if (g_file_test (system_sysconfdir, G_FILE_TEST_EXISTS))
77 g_ptr_array_add (paths, g_strdup (system_sysconfdir));
78 }
7964
8065 /* add in system-wide locations */
8166 if (g_file_test (system_prefixlibdir, G_FILE_TEST_EXISTS))
150135 g_autofree gchar *filename = g_build_filename (path_remotes, tmp, NULL);
151136 g_autoptr(FwupdRemote) remote = fwupd_remote_new ();
152137
138 /* skip invalid files */
139 if (!g_str_has_suffix (tmp, ".conf")) {
140 g_debug ("skipping invalid file %s", filename);
141 continue;
142 }
143
153144 /* load from keyfile */
154 g_debug ("loading from %s", filename);
145 g_debug ("loading config from %s", filename);
155146 if (!fwupd_remote_load_from_filename (remote, filename,
156 NULL, error))
147 NULL, error)) {
148 g_prefix_error (error, "failed to load %s: ", filename);
157149 return FALSE;
150 }
158151
159152 /* watch the config file and the XML file itself */
160153 if (!fu_config_add_inotify (self, filename, error))
298291 g_ptr_array_set_size (self->remotes, 0);
299292
300293 /* load the main daemon config file */
301 config_file = g_build_filename (fu_config_get_sysconfig_dir (),
302 "fwupd.conf", NULL);
294 config_file = g_build_filename (FWUPDCONFIGDIR, "daemon.conf", NULL);
303295 g_debug ("loading config values from %s", config_file);
304296 if (!g_key_file_load_from_file (self->keyfile, config_file,
305297 G_KEY_FILE_NONE, error))
313305 g_signal_connect (monitor, "changed",
314306 G_CALLBACK (fu_config_monitor_changed_cb), self);
315307 g_ptr_array_add (self->monitors, monitor);
316
317 /* optional, at the moment */
318 self->enable_option_rom =
319 g_key_file_get_boolean (self->keyfile,
320 "fwupd",
321 "EnableOptionROM",
322 NULL);
323308
324309 /* get blacklisted devices */
325310 devices = g_key_file_get_string_list (self->keyfile,
351336 if (!fu_config_load_remotes (self, error))
352337 return FALSE;
353338
354 /* enable the test suite */
355 if (g_key_file_get_boolean (self->keyfile,
356 "fwupd",
357 "EnableTestSuite",
358 NULL))
359 g_setenv ("FWUPD_TESTS", "true", TRUE);
360
361339 /* success */
362340 return TRUE;
363341 }
388366 {
389367 g_return_val_if_fail (FU_IS_CONFIG (self), NULL);
390368 return self->blacklist_plugins;
391 }
392
393 gboolean
394 fu_config_get_enable_option_rom (FuConfig *self)
395 {
396 g_return_val_if_fail (FU_IS_CONFIG (self), FALSE);
397 return self->enable_option_rom;
398369 }
399370
400371 static void
3636
3737 GPtrArray *fu_config_get_blacklist_devices (FuConfig *self);
3838 GPtrArray *fu_config_get_blacklist_plugins (FuConfig *self);
39 gboolean fu_config_get_enable_option_rom (FuConfig *self);
4039 GPtrArray *fu_config_get_remotes (FuConfig *self);
4140 FwupdRemote *fu_config_get_remote_by_id (FuConfig *self,
4241 const gchar *remote_id);
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <gio/gio.h>
24 #include <gusb.h>
25
26 #include "fu-device-locker.h"
27
28 /**
29 * SECTION:fu-device-locker
30 * @title: FuDeviceLocker
31 * @short_description: a device helper object
32 *
33 * An object that makes it easy to close a device when an object goes out of
34 * scope.
35 *
36 * See also: #FuDevice
37 */
38
39 struct _FuDeviceLocker {
40 GObject parent_instance;
41 GObject *device;
42 gboolean device_open;
43 FuDeviceLockerFunc open_func;
44 FuDeviceLockerFunc close_func;
45 };
46
47 G_DEFINE_TYPE (FuDeviceLocker, fu_device_locker, G_TYPE_OBJECT)
48
49 static void
50 fu_device_locker_finalize (GObject *obj)
51 {
52 FuDeviceLocker *self = FU_DEVICE_LOCKER (obj);
53
54 /* close device */
55 if (self->device_open) {
56 g_autoptr(GError) error = NULL;
57 if (!self->close_func (self->device, &error))
58 g_warning ("failed to close device: %s", error->message);
59 }
60
61 g_object_unref (self->device);
62 G_OBJECT_CLASS (fu_device_locker_parent_class)->finalize (obj);
63 }
64
65 static void
66 fu_device_locker_class_init (FuDeviceLockerClass *klass)
67 {
68 GObjectClass *object_class = G_OBJECT_CLASS (klass);
69 object_class->finalize = fu_device_locker_finalize;
70 }
71
72 static void
73 fu_device_locker_init (FuDeviceLocker *self)
74 {
75 }
76
77 /**
78 * fu_device_locker_new:
79 * @device: A #GObject
80 * @error: A #GError, or %NULL
81 *
82 * Opens the device for use. When the #FuDeviceLocker is deallocated the device
83 * will be closed and any error will just be directed to the console.
84 * This object is typically called using g_autoptr() but the device can also be
85 * manually closed using g_clear_object().
86 *
87 * The functions used for opening and closing the device are set automatically.
88 * If the @device is not a type or supertype of @GUsbDevice then this function
89 * will not work. For custom objects please use fu_device_locker_new_full().
90 *
91 * NOTE: If the @open_func failed then the @close_func will not be called.
92 *
93 * Think of this object as the device ownership.
94 *
95 * Returns: a #FuDeviceLocker, or %NULL if the @open_func failed.
96 **/
97 FuDeviceLocker *
98 fu_device_locker_new (gpointer device, GError **error)
99 {
100 g_return_val_if_fail (device != NULL, NULL);
101 g_return_val_if_fail (error != NULL, NULL);
102
103 /* GUsbDevice */
104 if (G_USB_IS_DEVICE (device)) {
105 return fu_device_locker_new_full (device,
106 (FuDeviceLockerFunc) g_usb_device_open,
107 (FuDeviceLockerFunc) g_usb_device_close,
108 error);
109 }
110 g_set_error_literal (error,
111 G_IO_ERROR,
112 G_IO_ERROR_NOT_SUPPORTED,
113 "device object type not supported");
114 return NULL;
115 }
116
117 /**
118 * fu_device_locker_new_full:
119 * @device: A #GObject
120 * @open_func: (scope async): A function to open the device
121 * @close_func: (scope async): A function to close the device
122 * @error: A #GError, or %NULL
123 *
124 * Opens the device for use. When the #FuDeviceLocker is deallocated the device
125 * will be closed and any error will just be directed to the console.
126 * This object is typically called using g_autoptr() but the device can also be
127 * manually closed using g_clear_object().
128 *
129 * NOTE: If the @open_func failed then the @close_func will not be called.
130 *
131 * Think of this object as the device ownership.
132 *
133 * Returns: a #FuDeviceLocker, or %NULL if the @open_func failed.
134 **/
135 FuDeviceLocker *
136 fu_device_locker_new_full (gpointer device,
137 FuDeviceLockerFunc open_func,
138 FuDeviceLockerFunc close_func,
139 GError **error)
140 {
141 g_autoptr(FuDeviceLocker) self = NULL;
142
143 g_return_val_if_fail (device != NULL, NULL);
144 g_return_val_if_fail (open_func != NULL, NULL);
145 g_return_val_if_fail (close_func != NULL, NULL);
146 g_return_val_if_fail (error != NULL, NULL);
147
148 /* create object */
149 self = g_object_new (FU_TYPE_DEVICE_LOCKER, NULL);
150 self->device = g_object_ref (device);
151 self->open_func = open_func;
152 self->close_func = close_func;
153
154 /* open device */
155 if (!self->open_func (device, error))
156 return NULL;
157
158 /* success */
159 self->device_open = TRUE;
160 return g_steal_pointer (&self);
161 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __FU_DEVICE_LOCKER_H
22 #define __FU_DEVICE_LOCKER_H
23
24 #include <glib-object.h>
25
26 G_BEGIN_DECLS
27
28 #define FU_TYPE_DEVICE_LOCKER (fu_device_locker_get_type ())
29
30 G_DECLARE_FINAL_TYPE (FuDeviceLocker, fu_device_locker, FU, DEVICE_LOCKER, GObject)
31
32 typedef gboolean (*FuDeviceLockerFunc) (GObject *device,
33 GError **error);
34
35 FuDeviceLocker *fu_device_locker_new (gpointer device,
36 GError **error);
37 FuDeviceLocker *fu_device_locker_new_full (gpointer device,
38 FuDeviceLockerFunc open_func,
39 FuDeviceLockerFunc close_func,
40 GError **error);
41
42 G_END_DECLS
43
44 #endif /* __FU_DEVICE_LOCKER_H */
2121 #ifndef __FU_DEVICE_METADATA_H__
2222 #define __FU_DEVICE_METADATA_H__
2323
24 /* thunderbolt plugin */
24 /**
25 * SECTION:fu-device-metadata
26 * @short_description: a device helper object
27 *
28 * An object that makes it easy to close a device when an object goes out of
29 * scope.
30 *
31 * See also: #FuDevice
32 */
33
34 /**
35 * FU_DEVICE_METADATA_TBT_CAN_FORCE_POWER:
36 *
37 * If the system can force-enable the Thunderbolt controller.
38 * Consumed by the thunderbolt plugin.
39 */
2540 #define FU_DEVICE_METADATA_TBT_CAN_FORCE_POWER "Thunderbolt::CanForcePower"
41
42 /**
43 * FU_DEVICE_METADATA_TBT_IS_SAFE_MODE:
44 *
45 * If the Thunderbolt hardware is stuck in safe mode.
46 * Consumed by the thunderbolt plugin.
47 */
2648 #define FU_DEVICE_METADATA_TBT_IS_SAFE_MODE "Thunderbolt::IsSafeMode"
2749
2850 #endif /* __FU_DEVICE_METADATA_H__ */
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU General Public License Version 2
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #ifndef __FU_DEVICE_PRIVATE_H
22 #define __FU_DEVICE_PRIVATE_H
23
24 #include <fu-device.h>
25
26 G_BEGIN_DECLS
27
28 gchar *fu_device_to_string (FuDevice *device);
29 const gchar *fu_device_get_version_new (FuDevice *device);
30 void fu_device_set_version_new (FuDevice *device,
31 const gchar *version_new);
32 const gchar *fu_device_get_filename_pending (FuDevice *device);
33 void fu_device_set_filename_pending (FuDevice *device,
34 const gchar *filename_pending);
35
36 G_END_DECLS
37
38 #endif /* __FU_DEVICE_PRIVATE_H */
39
2020
2121 #include "config.h"
2222
23 #include <string.h>
2324 #include <appstream-glib.h>
2425 #include <glib-object.h>
2526 #include <gio/gio.h>
2627
27 #include "fu-device.h"
28 #include "fu-device-private.h"
29
30 /**
31 * SECTION:fu-device
32 * @short_description: a physical or logical device
33 *
34 * An object that represents a physical or logical device.
35 *
36 * See also: #FuDeviceLocker
37 */
2838
2939 static void fu_device_finalize (GObject *object);
3040
3141 typedef struct {
3242 gchar *equivalent_id;
43 gchar *version_new;
44 gchar *filename_pending;
3345 FuDevice *alternate;
3446 GHashTable *metadata;
3547 } FuDevicePrivate;
3648
37 G_DEFINE_TYPE_WITH_PRIVATE (FuDevice, fu_device, FWUPD_TYPE_RESULT)
49 G_DEFINE_TYPE_WITH_PRIVATE (FuDevice, fu_device, FWUPD_TYPE_DEVICE)
3850 #define GET_PRIVATE(o) (fu_device_get_instance_private (o))
3951
4052 const gchar *
5466 priv->equivalent_id = g_strdup (equivalent_id);
5567 }
5668
69 const gchar *
70 fu_device_get_version_new (FuDevice *device)
71 {
72 FuDevicePrivate *priv = GET_PRIVATE (device);
73 g_return_val_if_fail (FU_IS_DEVICE (device), NULL);
74 return priv->version_new;
75 }
76
77 void
78 fu_device_set_version_new (FuDevice *device, const gchar *version_new)
79 {
80 FuDevicePrivate *priv = GET_PRIVATE (device);
81 g_return_if_fail (FU_IS_DEVICE (device));
82 g_free (priv->version_new);
83 priv->version_new = g_strdup (version_new);
84 }
85
86 const gchar *
87 fu_device_get_filename_pending (FuDevice *device)
88 {
89 FuDevicePrivate *priv = GET_PRIVATE (device);
90 g_return_val_if_fail (FU_IS_DEVICE (device), NULL);
91 return priv->filename_pending;
92 }
93
94 void
95 fu_device_set_filename_pending (FuDevice *device, const gchar *filename_pending)
96 {
97 FuDevicePrivate *priv = GET_PRIVATE (device);
98 g_return_if_fail (FU_IS_DEVICE (device));
99 g_free (priv->filename_pending);
100 priv->filename_pending = g_strdup (filename_pending);
101 }
102
103 /**
104 * fu_device_get_alternate:
105 * @device: A #FuDevice
106 *
107 * Gets any alternate device. An alternate device may be linked to the primary
108 * device in some way.
109 *
110 * Returns: (transfer none): a #FuDevice or %NULL
111 *
112 * Since: 0.7.2
113 **/
57114 FuDevice *
58115 fu_device_get_alternate (FuDevice *device)
59116 {
62119 return priv->alternate;
63120 }
64121
122 /**
123 * fu_device_set_alternate:
124 * @device: A #FuDevice
125 * @alternate: Another #FuDevice
126 *
127 * Sets any alternate device. An alternate device may be linked to the primary
128 * device in some way.
129 *
130 * Since: 0.7.2
131 **/
65132 void
66133 fu_device_set_alternate (FuDevice *device, FuDevice *alternate)
67134 {
70137 g_set_object (&priv->alternate, alternate);
71138 }
72139
140 /**
141 * fu_device_add_guid:
142 * @device: A #FuDevice
143 * @guid: A GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad`
144 *
145 * Adds a GUID to the device. If the @guid argument is not a valid GUID then it
146 * is converted to a GUID using as_utils_guid_from_string().
147 *
148 * Since: 0.7.2
149 **/
73150 void
74151 fu_device_add_guid (FuDevice *device, const gchar *guid)
75152 {
77154 if (!as_utils_guid_is_valid (guid)) {
78155 g_autofree gchar *tmp = as_utils_guid_from_string (guid);
79156 g_debug ("using %s for %s", tmp, guid);
80 fwupd_device_add_guid (fwupd_result_get_device (FWUPD_RESULT (device)), tmp);
157 fwupd_device_add_guid (FWUPD_DEVICE (device), tmp);
81158 return;
82159 }
83160
84161 /* already valid */
85 fwupd_device_add_guid (fwupd_result_get_device (FWUPD_RESULT (device)), guid);
162 fwupd_device_add_guid (FWUPD_DEVICE (device), guid);
86163 }
87164
88165 /**
217294 fu_device_set_metadata (device, key, tmp);
218295 }
219296
297 /**
298 * fu_device_set_name:
299 * @device: A #FuDevice
300 * @value: a device name
301 *
302 * Sets the name on the device. Any invalid parts will be converted or removed.
303 *
304 * Since: 0.7.1
305 **/
220306 void
221307 fu_device_set_name (FuDevice *device, const gchar *value)
222308 {
223309 g_autoptr(GString) new = g_string_new (value);
224310 g_strdelimit (new->str, "_", ' ');
225311 as_utils_string_replace (new, "(TM)", "™");
226 fwupd_device_set_name (fwupd_result_get_device (FWUPD_RESULT (device)), new->str);
312 fwupd_device_set_name (FWUPD_DEVICE (device), new->str);
313 }
314
315 static void
316 fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value)
317 {
318 /* ignore */
319 if (key == NULL || value == NULL)
320 return;
321 g_string_append_printf (str, " %s: ", key);
322 for (gsize i = strlen (key); i < 20; i++)
323 g_string_append (str, " ");
324 g_string_append_printf (str, "%s\n", value);
325 }
326
327 /**
328 * fu_device_to_string:
329 * @device: A #FuDevice
330 *
331 * This allows us to easily print the FwupdDevice, the FwupdRelease and the
332 * daemon-specific metadata.
333 *
334 * Returns: a string value, or %NULL for invalid.
335 *
336 * Since: 0.9.8
337 **/
338 gchar *
339 fu_device_to_string (FuDevice *device)
340 {
341 FuDevicePrivate *priv = GET_PRIVATE (device);
342 GString *str = g_string_new ("");
343 g_autofree gchar *tmp = NULL;
344 g_autoptr(GList) keys = NULL;
345
346 g_return_val_if_fail (FU_IS_DEVICE (device), NULL);
347
348 tmp = fwupd_device_to_string (FWUPD_DEVICE (device));
349 if (tmp != NULL && tmp[0] != '\0')
350 g_string_append (str, tmp);
351 if (priv->equivalent_id != NULL)
352 fwupd_pad_kv_str (str, "EquivalentId", priv->equivalent_id);
353 if (priv->filename_pending != NULL)
354 fwupd_pad_kv_str (str, "FilenamePending", priv->filename_pending);
355 if (priv->version_new != NULL)
356 fwupd_pad_kv_str (str, "VersionNew", priv->version_new);
357 keys = g_hash_table_get_keys (priv->metadata);
358 for (GList *l = keys; l != NULL; l = l->next) {
359 const gchar *key = l->data;
360 const gchar *value = g_hash_table_lookup (priv->metadata, key);
361 fwupd_pad_kv_str (str, key, value);
362 }
363 return g_string_free (str, FALSE);
227364 }
228365
229366 static void
250387 if (priv->alternate != NULL)
251388 g_object_unref (priv->alternate);
252389 g_hash_table_unref (priv->metadata);
390 g_free (priv->equivalent_id);
391 g_free (priv->version_new);
392 g_free (priv->filename_pending);
253393
254394 G_OBJECT_CLASS (fu_device_parent_class)->finalize (object);
255395 }
2727 G_BEGIN_DECLS
2828
2929 #define FU_TYPE_DEVICE (fu_device_get_type ())
30 G_DECLARE_DERIVABLE_TYPE (FuDevice, fu_device, FU, DEVICE, FwupdResult)
30 G_DECLARE_DERIVABLE_TYPE (FuDevice, fu_device, FU, DEVICE, FwupdDevice)
3131
3232 struct _FuDeviceClass
3333 {
34 FwupdResultClass parent_class;
34 FwupdDeviceClass parent_class;
3535 };
3636
3737 FuDevice *fu_device_new (void);
3838
39 /* compat setters */
40 #define fu_device_add_flag(d,v) fwupd_device_add_flag(fwupd_result_get_device(FWUPD_RESULT(d)),v)
41 #define fu_device_remove_flag(d,v) fwupd_device_remove_flag(fwupd_result_get_device(FWUPD_RESULT(d)),v)
42 #define fu_device_has_flag(d,v) fwupd_device_has_flag(fwupd_result_get_device(FWUPD_RESULT(d)),v)
43 #define fu_device_add_checksum(d,v) fwupd_device_add_checksum(fwupd_result_get_device(FWUPD_RESULT(d)),v)
44 #define fu_device_set_created(d,v) fwupd_device_set_created(fwupd_result_get_device(FWUPD_RESULT(d)),v)
45 #define fu_device_set_description(d,v) fwupd_device_set_description(fwupd_result_get_device(FWUPD_RESULT(d)),v)
46 #define fu_device_set_flags(d,v) fwupd_device_set_flags(fwupd_result_get_device(FWUPD_RESULT(d)),v)
47 #define fu_device_has_guid(d,v) fwupd_device_has_guid(fwupd_result_get_device(FWUPD_RESULT(d)),v)
48 #define fu_device_set_id(d,v) fwupd_device_set_id(fwupd_result_get_device(FWUPD_RESULT(d)),v)
49 #define fu_device_set_modified(d,v) fwupd_device_set_modified(fwupd_result_get_device(FWUPD_RESULT(d)),v)
50 #define fu_device_set_plugin(d,v) fwupd_device_set_provider(fwupd_result_get_device(FWUPD_RESULT(d)),v)
51 #define fu_device_set_unique_id(d,v) fwupd_result_set_unique_id(FWUPD_RESULT(d),v)
52 #define fu_device_set_update_description(d,v) fwupd_release_set_description(fwupd_result_get_release(FWUPD_RESULT(d)),v)
53 #define fu_device_set_update_error(d,v) fwupd_result_set_update_error(FWUPD_RESULT(d),v)
54 #define fu_device_set_update_filename(d,v) fwupd_release_set_filename(fwupd_result_get_release(FWUPD_RESULT(d)),v)
55 #define fu_device_set_update_homepage(d,v) fwupd_release_set_homepage(fwupd_result_get_release(FWUPD_RESULT(d)),v)
56 #define fu_device_set_update_id(d,v) fwupd_release_set_appstream_id(fwupd_result_get_release(FWUPD_RESULT(d)),v)
57 #define fu_device_set_update_license(d,v) fwupd_release_set_license(fwupd_result_get_release(FWUPD_RESULT(d)),v)
58 #define fu_device_set_update_name(d,v) fwupd_release_set_name(fwupd_result_get_release(FWUPD_RESULT(d)),v)
59 #define fu_device_set_update_state(d,v) fwupd_result_set_update_state(FWUPD_RESULT(d),v)
60 #define fu_device_set_update_summary(d,v) fwupd_release_set_summary(fwupd_result_get_release(FWUPD_RESULT(d)),v)
61 #define fu_device_set_update_uri(d,v) fwupd_release_set_uri(fwupd_result_get_release(FWUPD_RESULT(d)),v)
62 #define fu_device_set_update_vendor(d,v) fwupd_release_set_vendor(fwupd_result_get_release(FWUPD_RESULT(d)),v)
63 #define fu_device_set_update_version(d,v) fwupd_release_set_version(fwupd_result_get_release(FWUPD_RESULT(d)),v)
64 #define fu_device_set_update_remote_id(d,v) fwupd_release_set_remote_id(fwupd_result_get_release(FWUPD_RESULT(d)),v)
65 #define fu_device_set_vendor(d,v) fwupd_device_set_vendor(fwupd_result_get_device(FWUPD_RESULT(d)),v)
66 #define fu_device_set_vendor_id(d,v) fwupd_device_set_vendor_id(fwupd_result_get_device(FWUPD_RESULT(d)),v)
67 #define fu_device_set_version(d,v) fwupd_device_set_version(fwupd_result_get_device(FWUPD_RESULT(d)),v)
68 #define fu_device_set_version_lowest(d,v) fwupd_device_set_version_lowest(fwupd_result_get_device(FWUPD_RESULT(d)),v)
69 #define fu_device_set_version_bootloader(d,v) fwupd_device_set_version_bootloader(fwupd_result_get_device(FWUPD_RESULT(d)),v)
70 #define fu_device_set_flashes_left(d,v) fwupd_device_set_flashes_left(fwupd_result_get_device(FWUPD_RESULT(d)),v)
71
72 /* compat getters */
73 #define fu_device_get_checksums(d) fwupd_device_get_checksums(fwupd_result_get_device(FWUPD_RESULT(d)))
74 #define fu_device_get_flags(d) fwupd_device_get_flags(fwupd_result_get_device(FWUPD_RESULT(d)))
75 #define fu_device_get_guids(d) fwupd_device_get_guids(fwupd_result_get_device(FWUPD_RESULT(d)))
76 #define fu_device_get_guid_default(d) fwupd_device_get_guid_default(fwupd_result_get_device(FWUPD_RESULT(d)))
77 #define fu_device_get_name(d) fwupd_device_get_name(fwupd_result_get_device(FWUPD_RESULT(d)))
78 #define fu_device_get_id(d) fwupd_device_get_id(fwupd_result_get_device(FWUPD_RESULT(d)))
79 #define fu_device_get_plugin(d) fwupd_device_get_provider(fwupd_result_get_device(FWUPD_RESULT(d)))
80 #define fu_device_get_update_error(d) fwupd_result_get_update_error(FWUPD_RESULT(d))
81 #define fu_device_get_update_filename(d) fwupd_release_get_filename(fwupd_result_get_release(FWUPD_RESULT(d)))
82 #define fu_device_get_update_state(d) fwupd_result_get_update_state(FWUPD_RESULT(d))
83 #define fu_device_get_update_version(d) fwupd_release_get_version(fwupd_result_get_release(FWUPD_RESULT(d)))
84 #define fu_device_get_update_remote_id(d) fwupd_release_get_remote_id(fwupd_result_get_release(FWUPD_RESULT(d)))
85 #define fu_device_get_version(d) fwupd_device_get_version(fwupd_result_get_device(FWUPD_RESULT(d)))
86 #define fu_device_get_version_lowest(d) fwupd_device_get_version_lowest(fwupd_result_get_device(FWUPD_RESULT(d)))
87 #define fu_device_get_version_bootloader(d) fwupd_device_get_version_bootloader(fwupd_result_get_device(FWUPD_RESULT(d)))
88 #define fu_device_get_vendor_id(d) fwupd_device_get_vendor_id(fwupd_result_get_device(FWUPD_RESULT(d)))
89 #define fu_device_get_flashes_left(d) fwupd_device_get_flashes_left(fwupd_result_get_device(FWUPD_RESULT(d)))
39 /* helpful casting macros */
40 #define fu_device_add_flag(d,v) fwupd_device_add_flag(FWUPD_DEVICE(d),v)
41 #define fu_device_remove_flag(d,v) fwupd_device_remove_flag(FWUPD_DEVICE(d),v)
42 #define fu_device_has_flag(d,v) fwupd_device_has_flag(FWUPD_DEVICE(d),v)
43 #define fu_device_add_checksum(d,v) fwupd_device_add_checksum(FWUPD_DEVICE(d),v)
44 #define fu_device_add_icon(d,v) fwupd_device_add_icon(FWUPD_DEVICE(d),v)
45 #define fu_device_set_created(d,v) fwupd_device_set_created(FWUPD_DEVICE(d),v)
46 #define fu_device_set_description(d,v) fwupd_device_set_description(FWUPD_DEVICE(d),v)
47 #define fu_device_set_flags(d,v) fwupd_device_set_flags(FWUPD_DEVICE(d),v)
48 #define fu_device_has_guid(d,v) fwupd_device_has_guid(FWUPD_DEVICE(d),v)
49 #define fu_device_set_id(d,v) fwupd_device_set_id(FWUPD_DEVICE(d),v)
50 #define fu_device_set_modified(d,v) fwupd_device_set_modified(FWUPD_DEVICE(d),v)
51 #define fu_device_set_plugin(d,v) fwupd_device_set_plugin(FWUPD_DEVICE(d),v)
52 #define fu_device_set_summary(d,v) fwupd_device_set_summary(FWUPD_DEVICE(d),v)
53 #define fu_device_set_update_error(d,v) fwupd_device_set_update_error(FWUPD_DEVICE(d),v)
54 #define fu_device_set_update_state(d,v) fwupd_device_set_update_state(FWUPD_DEVICE(d),v)
55 #define fu_device_set_vendor(d,v) fwupd_device_set_vendor(FWUPD_DEVICE(d),v)
56 #define fu_device_set_vendor_id(d,v) fwupd_device_set_vendor_id(FWUPD_DEVICE(d),v)
57 #define fu_device_set_version(d,v) fwupd_device_set_version(FWUPD_DEVICE(d),v)
58 #define fu_device_set_version_lowest(d,v) fwupd_device_set_version_lowest(FWUPD_DEVICE(d),v)
59 #define fu_device_set_version_bootloader(d,v) fwupd_device_set_version_bootloader(FWUPD_DEVICE(d),v)
60 #define fu_device_set_flashes_left(d,v) fwupd_device_set_flashes_left(FWUPD_DEVICE(d),v)
61 #define fu_device_get_checksums(d) fwupd_device_get_checksums(FWUPD_DEVICE(d))
62 #define fu_device_get_flags(d) fwupd_device_get_flags(FWUPD_DEVICE(d))
63 #define fu_device_get_guids(d) fwupd_device_get_guids(FWUPD_DEVICE(d))
64 #define fu_device_get_guid_default(d) fwupd_device_get_guid_default(FWUPD_DEVICE(d))
65 #define fu_device_get_icons(d) fwupd_device_get_icons(FWUPD_DEVICE(d))
66 #define fu_device_get_name(d) fwupd_device_get_name(FWUPD_DEVICE(d))
67 #define fu_device_get_id(d) fwupd_device_get_id(FWUPD_DEVICE(d))
68 #define fu_device_get_plugin(d) fwupd_device_get_plugin(FWUPD_DEVICE(d))
69 #define fu_device_get_update_error(d) fwupd_device_get_update_error(FWUPD_DEVICE(d))
70 #define fu_device_get_update_state(d) fwupd_device_get_update_state(FWUPD_DEVICE(d))
71 #define fu_device_get_version(d) fwupd_device_get_version(FWUPD_DEVICE(d))
72 #define fu_device_get_version_lowest(d) fwupd_device_get_version_lowest(FWUPD_DEVICE(d))
73 #define fu_device_get_version_bootloader(d) fwupd_device_get_version_bootloader(FWUPD_DEVICE(d))
74 #define fu_device_get_vendor_id(d) fwupd_device_get_vendor_id(FWUPD_DEVICE(d))
75 #define fu_device_get_flashes_left(d) fwupd_device_get_flashes_left(FWUPD_DEVICE(d))
9076
9177 /* accessors */
9278 const gchar *fu_device_get_equivalent_id (FuDevice *device);
2424 #include <gio/gio.h>
2525 #include <gio/gunixinputstream.h>
2626 #include <glib-object.h>
27 #include <string.h>
2728
2829 #include "fwupd-common-private.h"
2930 #include "fwupd-enums-private.h"
3536 #include "fu-common.h"
3637 #include "fu-config.h"
3738 #include "fu-debug.h"
38 #include "fu-device.h"
39 #include "fu-device-private.h"
3940 #include "fu-engine.h"
4041 #include "fu-hwids.h"
4142 #include "fu-keyring.h"
4344 #include "fu-plugin.h"
4445 #include "fu-plugin-private.h"
4546 #include "fu-quirks.h"
47 #include "fu-smbios.h"
4648
4749 #ifdef ENABLE_GPG
4850 #include "fu-keyring-gpg.h"
6971 guint coldplug_delay;
7072 GPtrArray *plugins; /* of FuPlugin */
7173 GHashTable *plugins_hash; /* of name : FuPlugin */
74 GPtrArray *supported_guids;
75 FuSmbios *smbios;
7276 FuHwids *hwids;
7377 };
7478
9195 FuPlugin *plugin;
9296 } FuDeviceItem;
9397
94 static gboolean fu_engine_get_updates_item_update (FuEngine *self, FuDeviceItem *item);
95
9698 static void
9799 fu_engine_emit_changed (FuEngine *self)
98100 {
120122 /**
121123 * fu_engine_get_status:
122124 * @self: A #FuEngine
123 * @device_id: A device ID
124 * @error: A #GError, or %NULL
125125 *
126126 * Gets the current engine status.
127127 *
219219 return NULL;
220220 }
221221
222 static const gchar *
223 fu_engine_get_sysconfig_dir (void)
224 {
225 if (g_file_test (SYSCONFDIR, G_FILE_TEST_EXISTS))
226 return SYSCONFDIR;
227 return "/etc";
228 }
229
230222 static void
231 fu_engine_set_release_from_appstream (FuEngine *self, FwupdRelease *rel,
232 AsApp *app, AsRelease *release)
223 fu_engine_set_release_from_appstream (FuEngine *self,
224 FwupdRelease *rel,
225 AsRelease *release)
233226 {
234227 AsChecksum *csum;
235228 FwupdRemote *remote = NULL;
236 const gchar *remote_id;
237229 const gchar *tmp;
230 GBytes *remote_blob;
238231
239232 /* find the remote */
240 remote_id = as_app_get_metadata_item (app, "fwupd::RemoteID");
241 if (remote_id != NULL) {
242 remote = fu_config_get_remote_by_id (self->config, remote_id);
243 if (remote == NULL)
244 g_warning ("failed to find remote %s", remote_id);
245 } else {
246 g_warning ("no fwupd::RemoteID set on %s",
247 as_app_get_unique_id (app));
233 remote_blob = as_release_get_blob (release, "fwupd::RemoteId");
234 if (remote_blob != NULL) {
235 const gchar *remote_id = g_bytes_get_data (remote_blob, NULL);
236 if (remote_id != NULL) {
237 fwupd_release_set_remote_id (rel, remote_id);
238 remote = fu_config_get_remote_by_id (self->config, remote_id);
239 if (remote == NULL) {
240 g_warning ("no remote found for release %s",
241 as_release_get_version (release));
242 }
243 }
248244 }
249245
250246 tmp = as_release_get_version (release);
370366 }
371367
372368 /* check we were installed correctly */
373 pki_dir = g_build_filename (fu_engine_get_sysconfig_dir (), "pki", "fwupd", NULL);
369 pki_dir = g_build_filename (SYSCONFDIR, "pki", "fwupd", NULL);
374370 if (!g_file_test (pki_dir, G_FILE_TEST_EXISTS)) {
375371 g_set_error (error,
376372 FWUPD_ERROR,
383379 kr = fu_engine_get_keyring_for_kind (keyring_kind, error);
384380 if (kr == NULL)
385381 return FALSE;
386 if (!fu_keyring_setup (kr, error))
387 return FALSE;
388 if (!fu_keyring_add_public_keys (kr, pki_dir, error))
389 return FALSE;
382 if (!fu_keyring_setup (kr, error)) {
383 g_prefix_error (error, "failed to set up %s keyring: ",
384 fu_keyring_get_name (kr));
385 return FALSE;
386 }
387 if (!fu_keyring_add_public_keys (kr, pki_dir, error)) {
388 g_prefix_error (error, "failed to add public keys to %s keyring: ",
389 fu_keyring_get_name (kr));
390 return FALSE;
391 }
390392 kr_result = fu_keyring_verify_data (kr, blob_payload, blob_signature, &error_local);
391393 if (kr_result == NULL) {
392 g_warning ("untrusted as failed to verify: %s",
394 g_warning ("untrusted as failed to verify from %s keyring: %s",
395 fu_keyring_get_name (kr),
393396 error_local->message);
394397 return TRUE;
395398 }
491494 return NULL;
492495 }
493496 return g_steal_pointer (&store);
497 }
498
499 /**
500 * fu_engine_modify_remote:
501 * @self: A #FuEngine
502 * @remote_id: A remote ID
503 * @key: the key, e.g. `Enabled`
504 * @value: the key, e.g. `true`
505 * @error: A #GError, or %NULL
506 *
507 * Updates the verification store entry for a specific device.
508 *
509 * Returns: %TRUE for success
510 **/
511 gboolean
512 fu_engine_modify_remote (FuEngine *self,
513 const gchar *remote_id,
514 const gchar *key,
515 const gchar *value,
516 GError **error)
517 {
518 FwupdRemote *remote;
519 const gchar *filename;
520 const gchar *keys[] = { "Enabled", "MetadataURI", "FirmwareBaseURI", NULL };
521 g_autoptr(GKeyFile) keyfile = g_key_file_new ();
522
523 /* check remote is valid */
524 remote = fu_config_get_remote_by_id (self->config, remote_id);
525 if (remote == NULL) {
526 g_set_error (error,
527 FWUPD_ERROR,
528 FWUPD_ERROR_NOT_FOUND,
529 "remote %s not found", remote_id);
530 return FALSE;
531 }
532
533 /* check keys are valid */
534 if (!g_strv_contains (keys, key)) {
535 g_set_error (error,
536 FWUPD_ERROR,
537 FWUPD_ERROR_NOT_FOUND,
538 "key %s not supported", key);
539 return FALSE;
540 }
541
542 /* modify the remote filename */
543 filename = fwupd_remote_get_filename_source (remote);
544 if (!g_key_file_load_from_file (keyfile, filename,
545 G_KEY_FILE_KEEP_COMMENTS,
546 error)) {
547 g_prefix_error (error, "failed to load %s: ", filename);
548 return FALSE;
549 }
550 g_key_file_set_string (keyfile, "fwupd Remote", key, value);
551 return g_key_file_save_to_file (keyfile, filename, error);
494552 }
495553
496554 /**
10791137 }
10801138
10811139 version = as_release_get_version (rel);
1082 fu_device_set_update_version (item->device, version);
1140 fu_device_set_version_new (item->device, version);
10831141
10841142 /* compare to the lowest supported version, if it exists */
10851143 tmp = fu_device_get_version_lowest (item->device);
12361294 *
12371295 * Gets the PolicyKit action ID to use for the install operation.
12381296 *
1239 * Returns: string, e.g. "org.freedesktop.fwupd.update-internal-trusted"
1297 * Returns: string, e.g. `org.freedesktop.fwupd.update-internal-trusted`
12401298 **/
12411299 const gchar *
12421300 fu_engine_get_action_id_for_device (FuEngine *self,
13641422 return "org.freedesktop.fwupd.update-internal";
13651423 }
13661424
1425 static AsRelease *
1426 _as_app_get_release_by_version (AsApp *app, const gchar *version)
1427 {
1428 GPtrArray *releases = as_app_get_releases (app);
1429 for (guint i = 0; i < releases->len; i++) {
1430 AsRelease *release = g_ptr_array_index (releases, i);
1431 if (g_strcmp0 (version, as_release_get_version (release)) == 0)
1432 return release;
1433 }
1434 return NULL;
1435 }
1436
1437 static void
1438 fu_engine_add_component_to_store (FuEngine *self, AsApp *app)
1439 {
1440 AsApp *app_old = as_store_get_app_by_id (self->store, as_app_get_id (app));
1441 GPtrArray *releases = as_app_get_releases (app);
1442
1443 /* possibly convert the version from 0x to dotted */
1444 fu_engine_vendor_quirk_release_version (app);
1445
1446 /* possibly convert the flashed provide to a GUID */
1447 fu_engine_vendor_fixup_provide_value (app);
1448
1449 /* the app does not already exist */
1450 if (app_old == NULL) {
1451 as_store_add_app (self->store, app);
1452 return;
1453 }
1454
1455 /* add releases that do not exist from a higher priority remote */
1456 for (guint j = 0; j < releases->len; j++) {
1457 AsRelease *release = g_ptr_array_index (releases, j);
1458 AsRelease *release_old;
1459 const gchar *version = as_release_get_version (release);
1460 release_old = _as_app_get_release_by_version (app_old, version);
1461 if (release_old != NULL) {
1462 g_debug ("skipping release %s that already exists for %s",
1463 version, as_app_get_id (app_old));
1464 continue;
1465 }
1466 g_debug ("adding release %s to existing %s",
1467 version, as_app_get_id (app_old));
1468 as_app_add_release (app_old, release);
1469 }
1470 }
1471
13671472 static gboolean
13681473 fu_engine_load_metadata_from_file (FuEngine *self,
13691474 const gchar *path,
13731478 GPtrArray *apps;
13741479 g_autoptr(AsStore) store = NULL;
13751480 g_autoptr(GFile) file = NULL;
1481 g_autoptr(GBytes) remote_blob = NULL;
13761482
13771483 /* load the store locally until we know it is valid */
13781484 store = as_store_new ();
13801486 if (!as_store_from_file (store, file, NULL, NULL, error))
13811487 return FALSE;
13821488
1489 /* save the remote to the release */
1490 if (remote_id != NULL && remote_id[0] != '\0')
1491 remote_blob = g_bytes_new (remote_id, strlen (remote_id) + 1);
1492
13831493 /* add the new application from the store */
13841494 apps = as_store_get_apps (store);
13851495 for (guint i = 0; i < apps->len; i++) {
13861496 AsApp *app = g_ptr_array_index (apps, i);
13871497
1388 /* does this app already exist */
1389 if (as_store_get_app_by_id (self->store, as_app_get_id (app)) != NULL) {
1390 g_debug ("%s exists in remote %s, skipping",
1391 as_app_get_unique_id (app),
1392 as_app_get_metadata_item (app, "fwupd::RemoteID"));
1393 continue;
1394 }
1395 if (remote_id != NULL && remote_id[0] != '\0')
1396 as_app_add_metadata (app, "fwupd::RemoteID", remote_id);
1397 as_store_add_app (self->store, app);
1498 /* save the remote-id to all the releases for this component */
1499 if (remote_blob != NULL) {
1500 GPtrArray *releases = as_app_get_releases (app);
1501 for (guint j = 0; j < releases->len; j++) {
1502 AsRelease *release = g_ptr_array_index (releases, j);
1503 as_release_set_blob (release,
1504 "fwupd::RemoteId",
1505 remote_blob);
1506 }
1507 }
1508
1509 /* either add component, or merge in new releases */
1510 fu_engine_add_component_to_store (self, app);
13981511 }
13991512 return TRUE;
14001513 }
14041517 {
14051518 GPtrArray *apps;
14061519 GPtrArray *remotes;
1520 g_autofree gchar *guids_str = NULL;
1521 g_autoptr(GError) error_local = NULL;
14071522
14081523 /* clear existing store */
14091524 as_store_remove_all (self->store);
14241539 continue;
14251540 }
14261541 if (!fu_engine_load_metadata_from_file (self, path,
1427 fwupd_remote_get_id (remote),
1428 error))
1429 return FALSE;
1542 fwupd_remote_get_id (remote),
1543 &error_local)) {
1544 g_warning ("failed to load remote %s: %s",
1545 fwupd_remote_get_id (remote),
1546 error_local->message);
1547 continue;
1548 }
14301549 }
14311550
14321551 /* print what we've got */
14371556 g_debug ("devices now in store:");
14381557 for (guint i = 0; i < apps->len; i++) {
14391558 AsApp *app = g_ptr_array_index (apps, i);
1440 g_debug ("%u\t%s\t%s", i + 1,
1559 GPtrArray *releases = as_app_get_releases (app);
1560 g_autoptr(GString) releases_str = g_string_new (NULL);
1561
1562 for (guint j = 0; j < releases->len; j++) {
1563 AsRelease *release = g_ptr_array_index (releases, j);
1564 g_string_append_printf (releases_str, "%s,",
1565 as_release_get_version (release));
1566 if (j >= 2) {
1567 g_string_append (releases_str, "…,");
1568 break;
1569 }
1570 }
1571 if (releases_str->len > 1)
1572 g_string_truncate (releases_str, releases_str->len - 1);
1573 g_debug ("%u\t%s\t%s [%s]", i + 1,
14411574 as_app_get_id (app),
1442 as_app_get_name (app, NULL));
1575 as_app_get_name (app, NULL),
1576 releases_str->str);
1577 }
1578 }
1579
1580 /* update the list of supported GUIDs */
1581 g_ptr_array_set_size (self->supported_guids, 0);
1582 guids_str = fu_engine_get_guids_from_store (self->store);
1583 if (guids_str != NULL) {
1584 g_auto(GStrv) guids = g_strsplit (guids_str, ",", -1);
1585 for (guint i = 0; guids[i] != NULL; i++) {
1586 g_ptr_array_add (self->supported_guids,
1587 g_steal_pointer (&guids[i]));
14431588 }
14441589 }
14451590
14461591 /* are any devices now supported? */
14471592 for (guint i = 0; i < self->devices->len; i++) {
14481593 FuDeviceItem *item = g_ptr_array_index (self->devices, i);
1449 if (fu_engine_get_updates_item_update (self, item))
1594 if (fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_SUPPORTED))
14501595 fu_engine_emit_device_changed (self, item->device);
14511596 }
14521597
14731618 /**
14741619 * fu_engine_update_metadata:
14751620 * @self: A #FuEngine
1476 * @remote_id: A remote ID, e.g. "lvfs"
1621 * @remote_id: A remote ID, e.g. `lvfs`
14771622 * @fd: file descriptor of the metadata
14781623 * @fd_sig: file descriptor of the metadata signature
14791624 * @error: A #GError, or %NULL
15991744 }
16001745
16011746 static gboolean
1602 fu_engine_get_updates_item_update (FuEngine *self, FuDeviceItem *item)
1747 fu_engine_is_device_supported (FuEngine *self, FuDevice *device)
16031748 {
16041749 AsApp *app;
1605 AsRelease *release;
1606 GPtrArray *releases;
1607 const gchar *tmp;
1608 const gchar *version;
1609 g_autoptr(GError) error = NULL;
1610 g_autoptr(GPtrArray) updates_list = NULL;
1611
1612 /* get device version */
1613 version = fu_device_get_version (item->device);
1614 if (version == NULL)
1750
1751 /* no device version */
1752 if (fu_device_get_version (device) == NULL)
16151753 return FALSE;
16161754
16171755 /* match the GUIDs in the XML */
1618 app = fu_engine_store_get_app_by_guids (self->store, item->device);
1756 app = fu_engine_store_get_app_by_guids (self->store, device);
16191757 if (app == NULL)
16201758 return FALSE;
1621
1622 /* possibly convert the version from 0x to dotted */
1623 fu_engine_vendor_quirk_release_version (app);
1624
1625 /* possibly convert the flashed provide to a GUID */
1626 fu_engine_vendor_fixup_provide_value (app);
1627
1628 /* get latest release */
1629 release = as_app_get_release_default (app);
1630 if (release == NULL) {
1631 g_debug ("%s [%s] has no firmware update metadata",
1632 fu_device_get_id (item->device),
1633 fu_device_get_name (item->device));
1634 return FALSE;
1635 }
1636
1637 /* supported in metadata */
1638 fwupd_device_add_flag (fwupd_result_get_device (FWUPD_RESULT (item->device)),
1639 FWUPD_DEVICE_FLAG_SUPPORTED);
1640
1641 /* check if actually newer than what we have installed */
1642 if (as_utils_vercmp (as_release_get_version (release), version) <= 0) {
1643 g_debug ("%s has no firmware updates",
1644 fu_device_get_id (item->device));
1645 return FALSE;
1646 }
1647
1648 /* check we can install it */
1649 if (!fu_engine_check_requirements (app, item->device, &error)) {
1650 g_debug ("can not be installed: %s", error->message);
1651 return FALSE;
1652 }
1653
1654 /* only show devices that can be updated */
1655 if (!fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_UPDATABLE)) {
1656 g_debug ("ignoring %s [%s] as not updatable",
1657 fu_device_get_id (item->device),
1658 fu_device_get_name (item->device));
1659 return FALSE;
1660 }
1661
1662 /* add application metadata */
1663 fu_device_set_update_id (item->device, as_app_get_id (app));
1664 tmp = as_app_get_developer_name (app, NULL);
1665 if (tmp != NULL)
1666 fu_device_set_update_vendor (item->device, tmp);
1667 tmp = as_app_get_name (app, NULL);
1668 if (tmp != NULL)
1669 fu_device_set_update_name (item->device, tmp);
1670 tmp = as_app_get_comment (app, NULL);
1671 if (tmp != NULL)
1672 fu_device_set_update_summary (item->device, tmp);
1673 tmp = as_app_get_description (app, NULL);
1674 if (tmp != NULL)
1675 fu_device_set_description (item->device, tmp);
1676 tmp = as_app_get_url_item (app, AS_URL_KIND_HOMEPAGE);
1677 if (tmp != NULL)
1678 fu_device_set_update_homepage (item->device, tmp);
1679 tmp = as_app_get_project_license (app);
1680 if (tmp != NULL)
1681 fu_device_set_update_license (item->device, tmp);
1682 tmp = as_app_get_metadata_item (app, "fwupd::RemoteID");
1683 if (tmp != NULL)
1684 fu_device_set_update_remote_id (item->device, tmp);
1685 tmp = as_app_get_unique_id (app);
1686 if (tmp != NULL)
1687 fu_device_set_unique_id (item->device, tmp);
1688
1689 /* add release information */
1690 fu_engine_set_release_from_appstream (self,
1691 fwupd_result_get_release (FWUPD_RESULT (item->device)),
1692 app, release);
1693
1694 /* get the list of releases newer than the one installed */
1695 updates_list = g_ptr_array_new ();
1696 releases = as_app_get_releases (app);
1697 for (guint i = 0; i < releases->len; i++) {
1698 release = g_ptr_array_index (releases, i);
1699 if (as_utils_vercmp (as_release_get_version (release), version) <= 0)
1700 continue;
1701 tmp = as_release_get_description (release, NULL);
1702 if (tmp == NULL)
1703 continue;
1704 g_ptr_array_add (updates_list, release);
1705 }
1706
1707 /* no prefix on each release */
1708 if (updates_list->len == 1) {
1709 release = g_ptr_array_index (updates_list, 0);
1710 fu_device_set_update_description (item->device,
1711 as_release_get_description (release, NULL));
1712 } else {
1713 g_autoptr(GString) update_desc = NULL;
1714 update_desc = g_string_new ("");
1715
1716 /* get the descriptions with a version prefix */
1717 for (guint i = 0; i < updates_list->len; i++) {
1718 release = g_ptr_array_index (updates_list, i);
1719 g_string_append_printf (update_desc,
1720 "<p>%s:</p>%s",
1721 as_release_get_version (release),
1722 as_release_get_description (release, NULL));
1723 }
1724 if (update_desc->len > 0)
1725 fu_device_set_update_description (item->device, update_desc->str);
1726 }
17271759
17281760 /* success */
17291761 return TRUE;
17711803 return g_steal_pointer (&store);
17721804 }
17731805
1774 static FwupdResult *
1806 static FwupdDevice *
17751807 fu_engine_get_result_from_app (FuEngine *self, AsApp *app, GError **error)
17761808 {
17771809 FwupdTrustFlags trust_flags = FWUPD_TRUST_FLAG_NONE;
17781810 AsRelease *release;
1779 FwupdDevice *dev;
1780 FwupdRelease *rel;
17811811 GPtrArray *provides;
1782 g_autoptr(FwupdResult) res = NULL;
1783
1784 res = fwupd_result_new ();
1785 dev = fwupd_result_get_device (res);
1812 g_autoptr(FwupdDevice) dev = NULL;
1813 g_autoptr(FwupdRelease) rel = NULL;
1814
1815 dev = fwupd_device_new ();
17861816 provides = as_app_get_provides (app);
17871817 for (guint i = 0; i < provides->len; i++) {
17881818 AsProvide *prov = AS_PROVIDE (g_ptr_array_index (provides, i));
18231853 release = as_app_get_release_default (app);
18241854 if (!fu_engine_get_release_trust_flags (release, &trust_flags, error))
18251855 return NULL;
1826 fwupd_result_set_update_trust_flags (res, trust_flags);
18271856
18281857 /* possibly convert the version from 0x to dotted */
18291858 fu_engine_vendor_quirk_release_version (app);
18331862
18341863 /* create a result with all the metadata in */
18351864 fwupd_device_set_description (dev, as_app_get_description (app, NULL));
1836 rel = fwupd_result_get_release (res);
1865 rel = fwupd_release_new ();
1866 fwupd_release_set_trust_flags (rel, trust_flags);
18371867 fwupd_release_set_homepage (rel, as_app_get_url_item (app, AS_URL_KIND_HOMEPAGE));
18381868 fwupd_release_set_license (rel, as_app_get_project_license (app));
18391869 fwupd_release_set_name (rel, as_app_get_name (app, NULL));
18401870 fwupd_release_set_summary (rel, as_app_get_comment (app, NULL));
18411871 fwupd_release_set_vendor (rel, as_app_get_developer_name (app, NULL));
1842 fwupd_result_set_unique_id (res, as_app_get_unique_id (app));
18431872 fwupd_release_set_appstream_id (rel, as_app_get_id (app));
1844 fu_engine_set_release_from_appstream (self, rel, app, release);
1845 return g_steal_pointer (&res);
1873 fu_engine_set_release_from_appstream (self, rel, release);
1874 fwupd_device_add_release (dev, rel);
1875 return g_steal_pointer (&dev);
18461876 }
18471877
18481878 /**
1849 * fu_engine_get_details_local:
1879 * fu_engine_get_details:
18501880 * @self: A #FuEngine
18511881 * @fd: A file descriptor
18521882 * @error: A #GError, or %NULL
18551885 *
18561886 * Note: this will close the fd when done
18571887 *
1858 * Returns: (transfer container) (element-type FwupdResult): results
1888 * Returns: (transfer container) (element-type FwupdDevice): results
18591889 **/
18601890 GPtrArray *
1861 fu_engine_get_details_local (FuEngine *self, gint fd, GError **error)
1891 fu_engine_get_details (FuEngine *self, gint fd, GError **error)
18621892 {
18631893 GPtrArray *apps;
18641894 g_autoptr(AsStore) store = NULL;
18891919 details = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
18901920 for (guint i = 0; i < apps->len; i++) {
18911921 AsApp *app = g_ptr_array_index (apps, i);
1892 FwupdResult *res = NULL;
1922 FwupdDevice *res = NULL;
18931923
18941924 /* check we can install it */
18951925 if (!fu_engine_check_requirements (app, NULL, error))
19161946 GPtrArray *
19171947 fu_engine_get_devices (FuEngine *self, GError **error)
19181948 {
1919 GPtrArray *devices;
1949 g_autoptr(GPtrArray) devices = NULL;
19201950
19211951 g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
19221952 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
19341964 "No detected devices");
19351965 return NULL;
19361966 }
1937 return devices;
1938 }
1939
1940 /**
1941 * fu_engine_get_updates:
1942 * @self: A #FuEngine
1943 * @error: A #GError, or %NULL
1944 *
1945 * Gets the list of updates.
1946 *
1947 * Returns: (transfer container) (element-type FwupdDevice): results
1948 **/
1949 GPtrArray *
1950 fu_engine_get_updates (FuEngine *self, GError **error)
1951 {
1952 GPtrArray *updates;
1953
1954 g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
1955 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1956
1957 updates = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
1958 for (guint i = 0; i < self->devices->len; i++) {
1959 FuDeviceItem *item = g_ptr_array_index (self->devices, i);
1960 if (fu_engine_get_updates_item_update (self, item))
1961 g_ptr_array_add (updates, g_object_ref (item->device));
1962 }
1963 if (updates->len == 0) {
1964 g_set_error_literal (error,
1965 FWUPD_ERROR,
1966 FWUPD_ERROR_NOTHING_TO_DO,
1967 "No devices can be updated");
1968 return NULL;
1969 }
1970 return updates;
1967 return g_steal_pointer (&devices);
19711968 }
19721969
19731970 /**
19741971 * fu_engine_get_remotes:
19751972 * @self: A #FuEngine
1976 * @device_id: A device ID
19771973 * @error: A #GError, or %NULL
19781974 *
19791975 * Gets the list of remotes in use by the engine.
19991995 return g_ptr_array_ref (remotes);
20001996 }
20011997
2002 /**
2003 * fu_engine_get_releases:
2004 * @self: A #FuEngine
2005 * @device_id: A device ID
2006 * @error: A #GError, or %NULL
2007 *
2008 * Gets the releases available for a specific device.
2009 *
2010 * Returns: (transfer container) (element-type FwupdResult): results
2011 **/
2012 GPtrArray *
2013 fu_engine_get_releases (FuEngine *self, const gchar *device_id, GError **error)
2014 {
2015 FuDeviceItem *item;
1998 static gint
1999 fu_engine_sort_releases_cb (gconstpointer a, gconstpointer b)
2000 {
2001 FwupdRelease *rel_a = FWUPD_RELEASE (*((FwupdRelease **) a));
2002 FwupdRelease *rel_b = FWUPD_RELEASE (*((FwupdRelease **) b));
2003 return as_utils_vercmp (fwupd_release_get_version (rel_a),
2004 fwupd_release_get_version (rel_b));
2005 }
2006
2007 static GPtrArray *
2008 fu_engine_get_releases_for_device (FuEngine *self, FuDevice *device, GError **error)
2009 {
20162010 GPtrArray *device_guids;
2017 g_autoptr(GPtrArray) releases = NULL;
2018
2019 g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
2020 g_return_val_if_fail (device_id != NULL, NULL);
2021 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2022
2023 /* find the device */
2024 item = fu_engine_get_item_by_id (self, device_id, error);
2025 if (item == NULL)
2026 return NULL;
2027
2028 /* get all the releases for the device */
2011 GPtrArray *releases;
2012 const gchar *version;
2013
2014 /* get device version */
2015 version = fu_device_get_version (device);
2016 if (version == NULL) {
2017 g_set_error (error,
2018 FWUPD_ERROR,
2019 FWUPD_ERROR_NOT_SUPPORTED,
2020 "no version set");
2021 return NULL;
2022 }
2023
2024 /* only show devices that can be updated */
2025 if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)) {
2026 g_set_error (error,
2027 FWUPD_ERROR,
2028 FWUPD_ERROR_NOT_SUPPORTED,
2029 "ignoring %s [%s] as not updatable",
2030 fu_device_get_id (device),
2031 fu_device_get_name (device));
2032 return NULL;
2033 }
2034
20292035 releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
2030 device_guids = fu_device_get_guids (item->device);
2036 device_guids = fu_device_get_guids (device);
20312037 for (guint i = 0; i < device_guids->len; i++) {
20322038 GPtrArray *releases_tmp;
20332039 const gchar *guid = g_ptr_array_index (device_guids, i);
20362042 guid);
20372043 if (app == NULL)
20382044 continue;
2045
2046 /* check we can install it */
2047 if (!fu_engine_check_requirements (app, device, error))
2048 return NULL;
20392049 releases_tmp = as_app_get_releases (app);
20402050 for (guint j = 0; j < releases_tmp->len; j++) {
20412051 AsRelease *release = g_ptr_array_index (releases_tmp, j);
2042 FwupdRelease *rel = fwupd_release_new ();
2043 fu_engine_set_release_from_appstream (self, rel, app, release);
2044 g_ptr_array_add (releases, g_object_ref (rel));
2045 }
2046 }
2047
2048 /* no devices */
2052 GPtrArray *checksums;
2053 g_autoptr(FwupdRelease) rel = fwupd_release_new ();
2054
2055 /* create new FwupdRelease for the AsRelease */
2056 fwupd_release_set_appstream_id (rel, as_app_get_id (app));
2057 fu_engine_set_release_from_appstream (self, rel, release);
2058
2059 /* invalid */
2060 if (fwupd_release_get_uri (rel) == NULL)
2061 continue;
2062 checksums = fwupd_release_get_checksums (rel);
2063 if (checksums->len == 0)
2064 continue;
2065
2066 /* success */
2067 g_ptr_array_add (releases, g_steal_pointer (&rel));
2068 }
2069 }
2070 return releases;
2071 }
2072
2073 /**
2074 * fu_engine_get_releases:
2075 * @self: A #FuEngine
2076 * @device_id: A device ID
2077 * @error: A #GError, or %NULL
2078 *
2079 * Gets the releases available for a specific device.
2080 *
2081 * Returns: (transfer container) (element-type FwupdDevice): results
2082 **/
2083 GPtrArray *
2084 fu_engine_get_releases (FuEngine *self, const gchar *device_id, GError **error)
2085 {
2086 FuDeviceItem *item;
2087 g_autoptr(GPtrArray) releases = NULL;
2088
2089 g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
2090 g_return_val_if_fail (device_id != NULL, NULL);
2091 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2092
2093 /* find the device */
2094 item = fu_engine_get_item_by_id (self, device_id, error);
2095 if (item == NULL)
2096 return NULL;
2097
2098 /* get all the releases for the device */
2099 releases = fu_engine_get_releases_for_device (self, item->device, error);
2100 if (releases == NULL)
2101 return NULL;
20492102 if (releases->len == 0) {
20502103 g_set_error_literal (error,
20512104 FWUPD_ERROR,
20532106 "No releases for device");
20542107 return NULL;
20552108 }
2109 g_ptr_array_sort (releases, fu_engine_sort_releases_cb);
2110 return g_steal_pointer (&releases);
2111 }
2112
2113 /**
2114 * fu_engine_get_downgrades:
2115 * @self: A #FuEngine
2116 * @device_id: A device ID
2117 * @error: A #GError, or %NULL
2118 *
2119 * Gets the downgrades available for a specific device.
2120 *
2121 * Returns: (transfer container) (element-type FwupdDevice): results
2122 **/
2123 GPtrArray *
2124 fu_engine_get_downgrades (FuEngine *self, const gchar *device_id, GError **error)
2125 {
2126 FuDeviceItem *item;
2127 g_autoptr(GPtrArray) releases = NULL;
2128 g_autoptr(GPtrArray) releases_tmp = NULL;
2129 g_autoptr(GString) error_str = g_string_new (NULL);
2130
2131 g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
2132 g_return_val_if_fail (device_id != NULL, NULL);
2133 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2134
2135 /* find the device */
2136 item = fu_engine_get_item_by_id (self, device_id, error);
2137 if (item == NULL)
2138 return NULL;
2139
2140 /* get all the releases for the device */
2141 releases_tmp = fu_engine_get_releases_for_device (self, item->device, error);
2142 if (releases_tmp == NULL)
2143 return NULL;
2144 releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
2145 for (guint i = 0; i < releases_tmp->len; i++) {
2146 FwupdRelease *rel_tmp = g_ptr_array_index (releases_tmp, i);
2147 gint vercmp;
2148
2149 /* only include older firmware */
2150 vercmp = as_utils_vercmp (fwupd_release_get_version (rel_tmp),
2151 fu_device_get_version (item->device));
2152 if (vercmp == 0) {
2153 g_string_append_printf (error_str, "%s=same, ",
2154 fwupd_release_get_version (rel_tmp));
2155 g_debug ("ignoring %s as the same as %s",
2156 fwupd_release_get_version (rel_tmp),
2157 fu_device_get_version (item->device));
2158 continue;
2159 }
2160 if (vercmp > 0) {
2161 g_string_append_printf (error_str, "%s=newer, ",
2162 fwupd_release_get_version (rel_tmp));
2163 g_debug ("ignoring %s as newer than %s",
2164 fwupd_release_get_version (rel_tmp),
2165 fu_device_get_version (item->device));
2166 continue;
2167 }
2168
2169 /* don't show releases we are not allowed to dowgrade to */
2170 if (fu_device_get_version_lowest (item->device) != NULL) {
2171 if (as_utils_vercmp (fwupd_release_get_version (rel_tmp),
2172 fu_device_get_version_lowest (item->device)) <= 0) {
2173 g_string_append_printf (error_str, "%s=lowest, ",
2174 fwupd_release_get_version (rel_tmp));
2175 g_debug ("ignoring %s as older than lowest %s",
2176 fwupd_release_get_version (rel_tmp),
2177 fu_device_get_version_lowest (item->device));
2178 continue;
2179 }
2180 }
2181 g_ptr_array_add (releases, g_object_ref (rel_tmp));
2182 }
2183 if (error_str->len > 2)
2184 g_string_truncate (error_str, error_str->len - 2);
2185 if (releases->len == 0) {
2186 if (error_str->len > 0) {
2187 g_set_error (error,
2188 FWUPD_ERROR,
2189 FWUPD_ERROR_NOTHING_TO_DO,
2190 "No downgrades for device, current is %s: %s",
2191 fu_device_get_version (item->device),
2192 error_str->str);
2193 } else {
2194 g_set_error (error,
2195 FWUPD_ERROR,
2196 FWUPD_ERROR_NOTHING_TO_DO,
2197 "No downgrades for device, current is %s",
2198 fu_device_get_version (item->device));
2199 }
2200 return NULL;
2201 }
2202 g_ptr_array_sort (releases, fu_engine_sort_releases_cb);
2203 return g_steal_pointer (&releases);
2204 }
2205
2206 /**
2207 * fu_engine_get_upgrades:
2208 * @self: A #FuEngine
2209 * @device_id: A device ID
2210 * @error: A #GError, or %NULL
2211 *
2212 * Gets the upgrades available for a specific device.
2213 *
2214 * Returns: (transfer container) (element-type FwupdDevice): results
2215 **/
2216 GPtrArray *
2217 fu_engine_get_upgrades (FuEngine *self, const gchar *device_id, GError **error)
2218 {
2219 FuDeviceItem *item;
2220 g_autoptr(GPtrArray) releases = NULL;
2221 g_autoptr(GPtrArray) releases_tmp = NULL;
2222 g_autoptr(GString) error_str = g_string_new (NULL);
2223
2224 g_return_val_if_fail (FU_IS_ENGINE (self), NULL);
2225 g_return_val_if_fail (device_id != NULL, NULL);
2226 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2227
2228 /* find the device */
2229 item = fu_engine_get_item_by_id (self, device_id, error);
2230 if (item == NULL)
2231 return NULL;
2232
2233 /* get all the releases for the device */
2234 releases_tmp = fu_engine_get_releases_for_device (self, item->device, error);
2235 if (releases_tmp == NULL)
2236 return NULL;
2237 releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
2238 for (guint i = 0; i < releases_tmp->len; i++) {
2239 FwupdRelease *rel_tmp = g_ptr_array_index (releases_tmp, i);
2240 gint vercmp;
2241
2242 /* only include older firmware */
2243 vercmp = as_utils_vercmp (fwupd_release_get_version (rel_tmp),
2244 fu_device_get_version (item->device));
2245 if (vercmp == 0) {
2246 g_string_append_printf (error_str, "%s=same, ",
2247 fwupd_release_get_version (rel_tmp));
2248 g_debug ("ignoring %s as the same as %s",
2249 fwupd_release_get_version (rel_tmp),
2250 fu_device_get_version (item->device));
2251 continue;
2252 }
2253 if (vercmp < 0) {
2254 g_string_append_printf (error_str, "%s=older, ",
2255 fwupd_release_get_version (rel_tmp));
2256 g_debug ("ignoring %s as older than %s",
2257 fwupd_release_get_version (rel_tmp),
2258 fu_device_get_version (item->device));
2259 continue;
2260 }
2261 g_ptr_array_add (releases, g_object_ref (rel_tmp));
2262 }
2263 if (error_str->len > 2)
2264 g_string_truncate (error_str, error_str->len - 2);
2265 if (releases->len == 0) {
2266 if (error_str->len > 0) {
2267 g_set_error (error,
2268 FWUPD_ERROR,
2269 FWUPD_ERROR_NOTHING_TO_DO,
2270 "No upgrades for device, current is %s: %s",
2271 fu_device_get_version (item->device),
2272 error_str->str);
2273 } else {
2274 g_set_error (error,
2275 FWUPD_ERROR,
2276 FWUPD_ERROR_NOTHING_TO_DO,
2277 "No upgrades for device, current is %s",
2278 fu_device_get_version (item->device));
2279 }
2280 return NULL;
2281 }
2282 g_ptr_array_sort (releases, fu_engine_sort_releases_cb);
20562283 return g_steal_pointer (&releases);
20572284 }
20582285
20922319 *
20932320 * Gets the historical state of a specific device operation.
20942321 *
2095 * Returns: (transfer container): a #FwupdResult, or %NULL
2322 * Returns: (transfer container): a #FwupdDevice, or %NULL
20962323 **/
2097 FwupdResult *
2324 FwupdDevice *
20982325 fu_engine_get_results (FuEngine *self, const gchar *device_id, GError **error)
20992326 {
21002327 FuDeviceItem *item;
21122339 if (!fu_plugin_runner_get_results (item->plugin, item->device, error))
21132340 return NULL;
21142341
2115 /* ensure the unique ID is set */
2116 if (fwupd_result_get_unique_id (FWUPD_RESULT (item->device)) == NULL) {
2117 g_autofree gchar *id2 = NULL;
2118 FwupdResult *res = FWUPD_RESULT (item->device);
2119 FwupdDevice *dev = fwupd_result_get_device (res);
2120 id2 = as_utils_unique_id_build (AS_APP_SCOPE_SYSTEM,
2121 AS_BUNDLE_KIND_UNKNOWN,
2122 NULL,
2123 AS_APP_KIND_FIRMWARE,
2124 fwupd_device_get_name (dev),
2125 fwupd_device_get_version (dev));
2126 fwupd_result_set_unique_id (res, id2);
2127 }
21282342 return g_object_ref (item->device);
21292343 }
21302344
22892503 return;
22902504 }
22912505
2506 /* success */
2507 fu_engine_add_device (self, plugin, device);
2508 }
2509
2510 void
2511 fu_engine_add_device (FuEngine *self, FuPlugin *plugin, FuDevice *device)
2512 {
2513 FuDeviceItem *item;
2514
22922515 /* notify all plugins about this new device */
22932516 if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REGISTERED))
22942517 fu_engine_plugin_device_register (self, device);
23012524
23022525 /* match the metadata at this point so clients can tell if the
23032526 * device is worthy */
2304 fu_engine_get_updates_item_update (self, item);
2527 if (fu_engine_is_device_supported (self, item->device))
2528 fu_device_add_flag (item->device, FWUPD_DEVICE_FLAG_SUPPORTED);
23052529
23062530 /* notify clients */
23072531 fu_engine_emit_device_added (self, item->device);
23892613 static gint
23902614 fu_engine_plugin_sort_cb (gconstpointer a, gconstpointer b)
23912615 {
2392 FuPlugin *plugin1 = *((FuPlugin **) a);
2393 FuPlugin *plugin2 = *((FuPlugin **) b);
2394 return g_strcmp0 (fu_plugin_get_name (plugin1),
2395 fu_plugin_get_name (plugin2));
2616 FuPlugin **pa = (FuPlugin **) a;
2617 FuPlugin **pb = (FuPlugin **) b;
2618 if (fu_plugin_get_order (*pa) < fu_plugin_get_order (*pb))
2619 return -1;
2620 if (fu_plugin_get_order (*pa) > fu_plugin_get_order (*pb))
2621 return 1;
2622 return 0;
23962623 }
23972624
23982625 static gboolean
23992626 fu_engine_load_plugins (FuEngine *self, GError **error)
24002627 {
2628 FuPlugin *dep;
2629 GPtrArray *deps;
24012630 const gchar *fn;
2631 gboolean changes;
2632 guint dep_loop_check = 0;
24022633 g_autoptr(GDir) dir = NULL;
24032634
24042635 /* search */
24202651 plugin = fu_plugin_new ();
24212652 fu_plugin_set_usb_context (plugin, self->usb_ctx);
24222653 fu_plugin_set_hwids (plugin, self->hwids);
2654 fu_plugin_set_smbios (plugin, self->smbios);
2655 fu_plugin_set_supported (plugin, self->supported_guids);
24232656 g_debug ("adding plugin %s", filename);
24242657 if (!fu_plugin_open (plugin, filename, &error_local)) {
24252658 g_warning ("failed to open plugin %s: %s",
24712704 g_strdup (fu_plugin_get_name (plugin)),
24722705 g_object_ref (plugin));
24732706 }
2707
2708 /* order by deps */
2709 do {
2710 changes = FALSE;
2711 for (guint i = 0; i < self->plugins->len; i++) {
2712 FuPlugin *plugin = g_ptr_array_index (self->plugins, i);
2713 deps = fu_plugin_get_rules (plugin, FU_PLUGIN_RULE_RUN_AFTER);
2714 for (guint j = 0; j < deps->len && !changes; j++) {
2715 const gchar *plugin_name = g_ptr_array_index (deps, j);
2716 dep = fu_engine_get_plugin_by_name (self, plugin_name);
2717 if (dep == NULL) {
2718 g_debug ("cannot find plugin '%s' "
2719 "requested by '%s'",
2720 plugin_name,
2721 fu_plugin_get_name (plugin));
2722 continue;
2723 }
2724 if (!fu_plugin_get_enabled (dep))
2725 continue;
2726 if (fu_plugin_get_order (plugin) <= fu_plugin_get_order (dep)) {
2727 g_debug ("%s [%u] to be ordered after %s [%u] "
2728 "so promoting to [%u]",
2729 fu_plugin_get_name (plugin),
2730 fu_plugin_get_order (plugin),
2731 fu_plugin_get_name (dep),
2732 fu_plugin_get_order (dep),
2733 fu_plugin_get_order (dep) + 1);
2734 fu_plugin_set_order (plugin, fu_plugin_get_order (dep) + 1);
2735 changes = TRUE;
2736 }
2737 }
2738 }
2739 for (guint i = 0; i < self->plugins->len; i++) {
2740 FuPlugin *plugin = g_ptr_array_index (self->plugins, i);
2741 deps = fu_plugin_get_rules (plugin, FU_PLUGIN_RULE_RUN_BEFORE);
2742 for (guint j = 0; j < deps->len && !changes; j++) {
2743 const gchar *plugin_name = g_ptr_array_index (deps, j);
2744 dep = fu_engine_get_plugin_by_name (self, plugin_name);
2745 if (dep == NULL) {
2746 g_debug ("cannot find plugin '%s' "
2747 "requested by '%s'",
2748 plugin_name,
2749 fu_plugin_get_name (plugin));
2750 continue;
2751 }
2752 if (!fu_plugin_get_enabled (dep))
2753 continue;
2754 if (fu_plugin_get_order (plugin) >= fu_plugin_get_order (dep)) {
2755 g_debug ("%s [%u] to be ordered before %s [%u] "
2756 "so promoting to [%u]",
2757 fu_plugin_get_name (plugin),
2758 fu_plugin_get_order (plugin),
2759 fu_plugin_get_name (dep),
2760 fu_plugin_get_order (dep),
2761 fu_plugin_get_order (dep) + 1);
2762 fu_plugin_set_order (dep, fu_plugin_get_order (plugin) + 1);
2763 changes = TRUE;
2764 }
2765 }
2766 }
2767
2768 /* check we're not stuck */
2769 if (dep_loop_check++ > 100) {
2770 g_set_error (error,
2771 FWUPD_ERROR,
2772 FWUPD_ERROR_INTERNAL,
2773 "got stuck in dep loop");
2774 return FALSE;
2775 }
2776 } while (changes);
2777
2778 /* check for conflicts */
2779 for (guint i = 0; i < self->plugins->len; i++) {
2780 FuPlugin *plugin = g_ptr_array_index (self->plugins, i);
2781 if (!fu_plugin_get_enabled (plugin))
2782 continue;
2783 deps = fu_plugin_get_rules (plugin, FU_PLUGIN_RULE_CONFLICTS);
2784 for (guint j = 0; j < deps->len && !changes; j++) {
2785 const gchar *plugin_name = g_ptr_array_index (deps, j);
2786 dep = fu_engine_get_plugin_by_name (self, plugin_name);
2787 if (dep == NULL)
2788 continue;
2789 if (!fu_plugin_get_enabled (dep))
2790 continue;
2791 g_debug ("disabling %s as conflicts with %s",
2792 fu_plugin_get_name (dep),
2793 fu_plugin_get_name (plugin));
2794 fu_plugin_set_enabled (dep, FALSE);
2795 }
2796 }
2797
2798 /* sort by order */
24742799 g_ptr_array_sort (self->plugins, fu_engine_plugin_sort_cb);
2475
24762800 return TRUE;
24772801 }
24782802
25342858 gboolean
25352859 fu_engine_load (FuEngine *self, GError **error)
25362860 {
2861 g_autoptr(GError) error_hwids = NULL;
2862 g_autoptr(GError) error_smbios = NULL;
2863
25372864 g_return_val_if_fail (FU_IS_ENGINE (self), FALSE);
25382865 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
25392866
25562883 g_prefix_error (error, "Failed to get USB context: ");
25572884 return FALSE;
25582885 }
2559 #if G_USB_CHECK_VERSION(0,2,11)
2560 g_usb_context_set_flags (self->usb_ctx,
2561 G_USB_CONTEXT_FLAGS_AUTO_OPEN_DEVICES);
2562 #endif
2563
2564 /* load the hwids */
2565 if (!fu_hwids_setup (self->hwids, NULL, error)) {
2566 g_prefix_error (error, "Failed to load hwids: ");
2567 return FALSE;
2568 }
2886
2887 /* load SMBIOS and the hwids */
2888 if (!fu_smbios_setup (self->smbios, &error_smbios))
2889 g_warning ("Failed to load SMBIOS: %s", error_smbios->message);
2890 if (!fu_hwids_setup (self->hwids, self->smbios, &error_hwids))
2891 g_warning ("Failed to load HWIDs: %s", error_hwids->message);
25692892
25702893 /* delete old data files */
25712894 if (!fu_engine_cleanup_state (error)) {
25772900 if (!fu_engine_load_plugins (self, error)) {
25782901 g_prefix_error (error, "Failed to load plugins: ");
25792902 return FALSE;
2580 }
2581
2582 /* disable udev? */
2583 if (!fu_config_get_enable_option_rom (self->config)) {
2584 FuPlugin *plugin = g_hash_table_lookup (self->plugins_hash, "udev");
2585 if (plugin != NULL)
2586 fu_plugin_set_enabled (plugin, FALSE);
25872903 }
25882904
25892905 /* add devices */
26402956 self->status = FWUPD_STATUS_IDLE;
26412957 self->config = fu_config_new ();
26422958 self->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_engine_item_free);
2959 self->smbios = fu_smbios_new ();
26432960 self->hwids = fu_hwids_new ();
26442961 self->pending = fu_pending_new ();
26452962 self->profile = as_profile_new ();
26462963 self->store = as_store_new ();
2964 self->supported_guids = g_ptr_array_new_with_free_func (g_free);
26472965 self->plugins = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
26482966 self->plugins_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
26492967 g_free, (GDestroyNotify) g_object_unref);
26612979
26622980 g_hash_table_unref (self->plugins_hash);
26632981 g_object_unref (self->config);
2982 g_object_unref (self->smbios);
26642983 g_object_unref (self->hwids);
26652984 g_object_unref (self->pending);
26662985 g_object_unref (self->profile);
26672986 g_object_unref (self->store);
26682987 g_ptr_array_unref (self->devices);
2988 g_ptr_array_unref (self->supported_guids);
26692989 g_ptr_array_unref (self->plugins);
26702990
26712991 G_OBJECT_CLASS (fu_engine_parent_class)->finalize (obj);
2626 #include <appstream-glib.h>
2727 #include <glib-object.h>
2828
29 #include "fwupd-result.h"
29 #include "fwupd-device.h"
3030 #include "fwupd-enums.h"
31
32 #include "fu-plugin.h"
3133
3234 #define FU_TYPE_ENGINE (fu_engine_get_type ())
3335 G_DECLARE_FINAL_TYPE (FuEngine, fu_engine, FU, ENGINE, GObject)
4244 gboolean fu_engine_check_plugins_pending (FuEngine *self,
4345 GError **error);
4446 AsStore *fu_engine_get_store_from_blob (FuEngine *self,
45 GBytes *blob,
47 GBytes *blob_cab,
4648 GError **error);
4749 const gchar *fu_engine_get_action_id_for_device (FuEngine *self,
4850 const gchar *device_id,
5254
5355 GPtrArray *fu_engine_get_devices (FuEngine *self,
5456 GError **error);
55 GPtrArray *fu_engine_get_updates (FuEngine *self,
56 GError **error);
5757 GPtrArray *fu_engine_get_remotes (FuEngine *self,
5858 GError **error);
5959 GPtrArray *fu_engine_get_releases (FuEngine *self,
6060 const gchar *device_id,
6161 GError **error);
62 FwupdResult *fu_engine_get_results (FuEngine *self,
62 GPtrArray *fu_engine_get_downgrades (FuEngine *self,
63 const gchar *device_id,
64 GError **error);
65 GPtrArray *fu_engine_get_upgrades (FuEngine *self,
66 const gchar *device_id,
67 GError **error);
68 FwupdDevice *fu_engine_get_results (FuEngine *self,
6369 const gchar *device_id,
6470 GError **error);
6571 gboolean fu_engine_clear_results (FuEngine *self,
7985 gboolean fu_engine_verify_update (FuEngine *self,
8086 const gchar *device_id,
8187 GError **error);
88 gboolean fu_engine_modify_remote (FuEngine *self,
89 const gchar *remote_id,
90 const gchar *key,
91 const gchar *value,
92 GError **error);
8293 gboolean fu_engine_install (FuEngine *self,
8394 const gchar *device_id,
8495 AsStore *store,
8596 GBytes *blob_cab,
8697 FwupdInstallFlags flags,
8798 GError **error);
88 GPtrArray *fu_engine_get_details_local (FuEngine *self,
99 GPtrArray *fu_engine_get_details (FuEngine *self,
89100 gint fd,
90101 GError **error);
102
103 /* for the self tests */
104 void fu_engine_add_device (FuEngine *self,
105 FuPlugin *plugin,
106 FuDevice *device);
91107
92108 G_END_DECLS
93109
2626 #include <appstream-glib.h>
2727
2828 #include "fu-hwids.h"
29 #include "fwupd-error.h"
2930
3031 struct _FuHwids {
3132 GObject parent_instance;
3940 /**
4041 * fu_hwids_get_value:
4142 * @self: A #FuHwids
42 * @key: A DMI ID, e.g. "BiosVersion"
43 * @key: A DMI ID, e.g. `BiosVersion`
4344 *
4445 * Gets the cached value for one specific key that is valid ASCII and suitable
4546 * for display.
4647 *
47 * Returns: the string, e.g. "1.2.3", or %NULL if not found
48 * Returns: the string, e.g. `1.2.3`, or %NULL if not found
4849 **/
4950 const gchar *
5051 fu_hwids_get_value (FuHwids *self, const gchar *key)
5556 /**
5657 * fu_hwids_has_guid:
5758 * @self: A #FuHwids
58 * @guid: A GUID, e.g. "059eb22d-6dc7-59af-abd3-94bbe017f67c"
59 * @guid: A GUID, e.g. `059eb22d-6dc7-59af-abd3-94bbe017f67c`
5960 *
6061 * Finds out if a hardware GUID exists.
6162 *
9394 /**
9495 * fu_hwids_get_replace_keys:
9596 * @self: A #FuHwids
96 * @key: A HardwareID key, e.g. "HardwareID-3"
97 * @key: A HardwareID key, e.g. `HardwareID-3`
9798 *
9899 * Gets the replacement key for a well known value.
99100 *
100 * Returns: the replacement value, e.g. "Manufacturer&ProductName", or %NULL for error.
101 * Returns: the replacement value, e.g. `Manufacturer&ProductName`, or %NULL for error.
101102 **/
102103 const gchar *
103104 fu_hwids_get_replace_keys (FuHwids *self, const gchar *key)
181182 /**
182183 * fu_hwids_get_replace_values:
183184 * @self: A #FuHwids
184 * @keys: A key, e.g. "HardwareID-3" or %FU_HWIDS_KEY_PRODUCT_SKU
185 * @keys: A key, e.g. `HardwareID-3` or %FU_HWIDS_KEY_PRODUCT_SKU
185186 * @error: A #GError or %NULL
186187 *
187188 * Gets the replacement values for a HardwareID key or plain key.
188189 *
189 * Returns: a string, e.g. "LENOVO&ThinkPad T440s", or %NULL for error.
190 * Returns: a string, e.g. `LENOVO&ThinkPad T440s`, or %NULL for error.
190191 **/
191192 gchar *
192193 fu_hwids_get_replace_values (FuHwids *self, const gchar *keys, GError **error)
219220 /**
220221 * fu_hwids_get_guid:
221222 * @self: A #FuHwids
222 * @keys: A key, e.g. "HardwareID-3" or %FU_HWIDS_KEY_PRODUCT_SKU
223 * @keys: A key, e.g. `HardwareID-3` or %FU_HWIDS_KEY_PRODUCT_SKU
223224 * @error: A #GError or %NULL
224225 *
225226 * Gets the GUID for a specific key.
235236 return fu_hwids_get_guid_for_str (tmp, error);
236237 }
237238
239 typedef gchar *(*FuHwidsConvertFunc) (FuSmbios *smbios,
240 guint8 type,
241 guint8 offset,
242 GError **error);
243
244 static gchar *
245 fu_hwids_convert_string_table_cb (FuSmbios *smbios,
246 guint8 type, guint8 offset,
247 GError **error)
248 {
249 const gchar *tmp;
250 tmp = fu_smbios_get_string (smbios, type, offset, error);
251 if (tmp == NULL)
252 return NULL;
253 return g_strdup (tmp);
254 }
255
256 static gchar *
257 fu_hwids_convert_base10_integer_cb (FuSmbios *smbios,
258 guint8 type, guint8 offset,
259 GError **error)
260 {
261 GBytes *data;
262 const guint8 *data_raw;
263 gsize data_sz = 0;
264 data = fu_smbios_get_data (smbios, type, error);
265 if (data == NULL)
266 return NULL;
267 data_raw = g_bytes_get_data (data, &data_sz);
268 if (offset >= data_sz) {
269 g_set_error_literal (error,
270 FWUPD_ERROR,
271 FWUPD_ERROR_INVALID_FILE,
272 "offset bigger than data");
273 return NULL;
274 }
275 return g_strdup_printf ("%u", data_raw[offset]);
276 }
277
238278 /**
239279 * fu_hwids_setup:
240280 * @self: A #FuHwids
241 * @sysfsdir: The sysfs directory, or %NULL for the default
281 * @smbios: A #FuSmbios
242282 * @error: A #GError or %NULL
243283 *
244284 * Reads all the SMBIOS values from the hardware.
246286 * Returns: %TRUE for success
247287 **/
248288 gboolean
249 fu_hwids_setup (FuHwids *self, const gchar *sysfsdir, GError **error)
289 fu_hwids_setup (FuHwids *self, FuSmbios *smbios, GError **error)
250290 {
251291 struct {
252 const gchar *key;
253 const gchar *value;
254 } sysfsfile[] = {
255 { FU_HWIDS_KEY_MANUFACTURER, "sys_vendor" },
256 { FU_HWIDS_KEY_ENCLOSURE_KIND, "chassis_type" },
257 { FU_HWIDS_KEY_FAMILY, "product_family" },
258 { FU_HWIDS_KEY_PRODUCT_NAME, "product_name" },
259 { FU_HWIDS_KEY_PRODUCT_SKU, "product_sku" },
260 { FU_HWIDS_KEY_BIOS_VENDOR, "bios_vendor" },
261 { FU_HWIDS_KEY_BIOS_VERSION, "bios_version" },
262 { FU_HWIDS_KEY_BIOS_MAJOR_RELEASE, "bios_major_release" },
263 { FU_HWIDS_KEY_BIOS_MINOR_RELEASE, "bios_minor_release" },
264 { FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, "board_vendor" },
265 { FU_HWIDS_KEY_BASEBOARD_PRODUCT, "board_name" },
266 { NULL, NULL }
292 const gchar *key;
293 guint8 type;
294 guint8 offset;
295 FuHwidsConvertFunc func;
296 } map[] = {
297 { FU_HWIDS_KEY_MANUFACTURER, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x04,
298 fu_hwids_convert_string_table_cb },
299 { FU_HWIDS_KEY_ENCLOSURE_KIND, FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, 0x05,
300 fu_hwids_convert_base10_integer_cb },
301 { FU_HWIDS_KEY_FAMILY, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x1a,
302 fu_hwids_convert_string_table_cb },
303 { FU_HWIDS_KEY_PRODUCT_NAME, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x05,
304 fu_hwids_convert_string_table_cb },
305 { FU_HWIDS_KEY_PRODUCT_SKU, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x19,
306 fu_hwids_convert_string_table_cb },
307 { FU_HWIDS_KEY_BIOS_VENDOR, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0x04,
308 fu_hwids_convert_string_table_cb },
309 { FU_HWIDS_KEY_BIOS_VERSION, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0x05,
310 fu_hwids_convert_string_table_cb },
311 { FU_HWIDS_KEY_BIOS_MAJOR_RELEASE, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0x14,
312 fu_hwids_convert_base10_integer_cb },
313 { FU_HWIDS_KEY_BIOS_MINOR_RELEASE, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0x15,
314 fu_hwids_convert_base10_integer_cb },
315 { FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, 0x04,
316 fu_hwids_convert_string_table_cb },
317 { FU_HWIDS_KEY_BASEBOARD_PRODUCT, FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, 0x05,
318 fu_hwids_convert_string_table_cb },
319 { NULL, 0x00, 0x00, NULL }
267320 };
268321
269322 g_return_val_if_fail (FU_IS_HWIDS (self), FALSE);
270
271 /* default value */
272 if (sysfsdir == NULL)
273 sysfsdir = "/sys/class/dmi/id";
274
275 /* does not exist in a container */
276 if (!g_file_test (sysfsdir, G_FILE_TEST_EXISTS))
277 return TRUE;
323 g_return_val_if_fail (FU_IS_SMBIOS (smbios), FALSE);
278324
279325 /* get all DMI data */
280 for (guint i = 0; sysfsfile[i].key != NULL; i++) {
326 for (guint i = 0; map[i].key != NULL; i++) {
327 const gchar *contents_hdr;
281328 g_autofree gchar *contents = NULL;
282329 g_autofree gchar *contents_safe = NULL;
283 g_autofree gchar *fn = NULL;
284 const gchar *contents_hdr;
285
286 fn = g_build_filename (sysfsdir, sysfsfile[i].value, NULL);
287 if (!g_file_test (fn, G_FILE_TEST_EXISTS)) {
288 g_debug ("no %s so ignoring", fn);
330 g_autoptr(GError) error_local = NULL;
331
332 /* get the data from a SMBIOS table */
333 contents = map[i].func (smbios, map[i].type, map[i].offset, &error_local);
334 if (contents == NULL) {
335 g_debug ("ignoring %s: %s", map[i].key, error_local->message);
289336 continue;
290337 }
291 if (!g_file_get_contents (fn, &contents, NULL, error))
292 return FALSE;
293 g_strdelimit (contents, "\n\r", '\0');
294 g_debug ("smbios property %s=%s", fn, contents);
295 if (g_strcmp0 (contents, "Not Available") == 0)
296 continue;
297 if (g_strcmp0 (contents, "Not Defined") == 0)
298 continue;
338 g_debug ("smbios property %s=%s", map[i].key, contents);
299339
300340 /* weirdly, remove leading zeros */
301341 contents_hdr = contents;
302342 while (contents_hdr[0] == '0')
303343 contents_hdr++;
304344 g_hash_table_insert (self->hash_dmi_hw,
305 g_strdup (sysfsfile[i].key),
345 g_strdup (map[i].key),
306346 g_strdup (contents_hdr));
307347
308348 /* make suitable for display */
309349 contents_safe = g_str_to_ascii (contents_hdr, "C");
350 g_strdelimit (contents_safe, "\n\r", '\0');
310351 g_strchomp (contents_safe);
311352 g_hash_table_insert (self->hash_dmi_display,
312 g_strdup (sysfsfile[i].key),
353 g_strdup (map[i].key),
313354 g_steal_pointer (&contents_safe));
314355 }
315356
2222 #define __FU_HWIDS_H
2323
2424 #include <glib-object.h>
25
26 #include "fu-smbios.h"
2527
2628 G_BEGIN_DECLS
2729
5658 gboolean fu_hwids_has_guid (FuHwids *self,
5759 const gchar *guid);
5860 gboolean fu_hwids_setup (FuHwids *self,
59 const gchar *sysfsdir,
61 FuSmbios *smbios,
6062 GError **error);
6163
6264 G_END_DECLS
106106 g_set_error (error,
107107 FWUPD_ERROR,
108108 FWUPD_ERROR_INTERNAL,
109 "failed to startup GPG: %s",
109 "failed to init: %s",
110110 gpgme_strerror (rc));
111111 return FALSE;
112112 }
2828 #include <polkit/polkit.h>
2929 #include <stdlib.h>
3030
31 #include "fwupd-device-private.h"
3132 #include "fwupd-release-private.h"
3233 #include "fwupd-remote-private.h"
3334 #include "fwupd-resources.h"
3435
3536 #include "fu-common.h"
3637 #include "fu-debug.h"
37 #include "fu-device.h"
38 #include "fu-device-private.h"
3839 #include "fu-engine.h"
3940
4041 #ifndef HAVE_POLKIT_0_114
7677 /* not yet connected */
7778 if (priv->connection == NULL)
7879 return;
79 val = fwupd_result_to_data (FWUPD_RESULT (device), "(a{sv})");
80 val = fwupd_device_to_variant (FWUPD_DEVICE (device));
8081 g_dbus_connection_emit_signal (priv->connection,
8182 NULL,
8283 FWUPD_DBUS_PATH,
8384 FWUPD_DBUS_INTERFACE,
8485 "DeviceAdded",
85 val, NULL);
86 g_variant_new_tuple (&val, 1), NULL);
8687 }
8788
8889 static void
9596 /* not yet connected */
9697 if (priv->connection == NULL)
9798 return;
98 val = fwupd_result_to_data (FWUPD_RESULT (device), "(a{sv})");
99 val = fwupd_device_to_variant (FWUPD_DEVICE (device));
99100 g_dbus_connection_emit_signal (priv->connection,
100101 NULL,
101102 FWUPD_DBUS_PATH,
102103 FWUPD_DBUS_INTERFACE,
103104 "DeviceRemoved",
104 val, NULL);
105 g_variant_new_tuple (&val, 1), NULL);
105106 }
106107
107108 static void
114115 /* not yet connected */
115116 if (priv->connection == NULL)
116117 return;
117 val = fwupd_result_to_data (FWUPD_RESULT (device), "(a{sv})");
118 val = fwupd_device_to_variant (FWUPD_DEVICE (device));
118119 g_dbus_connection_emit_signal (priv->connection,
119120 NULL,
120121 FWUPD_DBUS_PATH,
121122 FWUPD_DBUS_INTERFACE,
122123 "DeviceChanged",
123 val, NULL);
124 g_variant_new_tuple (&val, 1), NULL);
124125 }
125126
126127 static void
156157 g_variant_builder_clear (&invalidated_builder);
157158 }
158159
159
160 static void
161 fu_main_engine_status_changed_cb (FuEngine *engine,
162 FwupdStatus status,
163 FuMainPrivate *priv)
160 static void
161 fu_main_set_status (FuMainPrivate *priv, FwupdStatus status)
164162 {
165163 g_debug ("Emitting PropertyChanged('Status'='%s')",
166164 fwupd_status_to_string (status));
167165 fu_main_emit_property_changed (priv, "Status",
168166 g_variant_new_uint32 (status));
167 }
168
169 static void
170 fu_main_engine_status_changed_cb (FuEngine *engine,
171 FwupdStatus status,
172 FuMainPrivate *priv)
173 {
174 fu_main_set_status (priv, status);
169175 }
170176
171177 static void
186192 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
187193 for (guint i = 0; i < devices->len; i++) {
188194 FuDevice *device = g_ptr_array_index (devices, i);
189 GVariant *tmp = fwupd_result_to_data (FWUPD_RESULT (device), "{sa{sv}}");
195 GVariant *tmp = fwupd_device_to_variant (FWUPD_DEVICE (device));
190196 g_variant_builder_add_value (&builder, tmp);
191197 }
192 return g_variant_new ("(a{sa{sv}})", &builder);
198 return g_variant_new ("(aa{sv})", &builder);
193199 }
194200
195201 static GVariant *
200206 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
201207 for (guint i = 0; i < results->len; i++) {
202208 FwupdRelease *rel = g_ptr_array_index (results, i);
203 GVariant *tmp = fwupd_release_to_data (rel, "a{sv}");
209 GVariant *tmp = fwupd_release_to_variant (rel);
204210 g_variant_builder_add_value (&builder, tmp);
205211 }
206212 return g_variant_new ("(aa{sv})", &builder);
214220 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
215221 for (guint i = 0; i < remotes->len; i++) {
216222 FwupdRemote *remote = g_ptr_array_index (remotes, i);
217 GVariant *tmp = fwupd_remote_to_data (remote, "a{sv}");
223 GVariant *tmp = fwupd_remote_to_variant (remote);
218224 g_variant_builder_add_value (&builder, tmp);
219225 }
220226 return g_variant_new ("(aa{sv})", &builder);
227233 g_return_val_if_fail (results->len > 0, NULL);
228234 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
229235 for (guint i = 0; i < results->len; i++) {
230 FwupdResult *result = g_ptr_array_index (results, i);
231 GVariant *tmp = fwupd_result_to_data (result, "{sa{sv}}");
236 FwupdDevice *result = g_ptr_array_index (results, i);
237 GVariant *tmp = fwupd_device_to_variant (result);
232238 g_variant_builder_add_value (&builder, tmp);
233239 }
234 return g_variant_new ("(a{sa{sv}})", &builder);
240 return g_variant_new ("(aa{sv})", &builder);
235241 }
236242
237243 typedef struct {
241247 GBytes *blob_cab;
242248 FuMainPrivate *priv;
243249 gchar *device_id;
250 gchar *remote_id;
251 gchar *key;
252 gchar *value;
244253 } FuMainAuthHelper;
245254
246255 static void
251260 if (helper->store != NULL)
252261 g_object_unref (helper->store);
253262 g_free (helper->device_id);
263 g_free (helper->remote_id);
264 g_free (helper->key);
265 g_free (helper->value);
254266 g_object_unref (helper->invocation);
255267 g_free (helper);
256268 }
292304 g_autoptr(GError) error = NULL;
293305 g_autoptr(PolkitAuthorizationResult) auth = NULL;
294306
307
295308 /* get result */
309 fu_main_set_status (helper->priv, FWUPD_STATUS_IDLE);
296310 auth = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (source),
297311 res, &error);
298312 if (!fu_main_authorization_is_valid (auth, &error)) {
318332 g_autoptr(PolkitAuthorizationResult) auth = NULL;
319333
320334 /* get result */
335 fu_main_set_status (helper->priv, FWUPD_STATUS_IDLE);
321336 auth = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (source),
322337 res, &error);
323338 if (!fu_main_authorization_is_valid (auth, &error)) {
336351 }
337352
338353 static void
339 fu_main_authorize_install_cb (GObject *source, GAsyncResult *res, gpointer user_data)
354 fu_main_authorize_modify_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
340355 {
341356 g_autoptr(FuMainAuthHelper) helper = (FuMainAuthHelper *) user_data;
342357 g_autoptr(GError) error = NULL;
343358 g_autoptr(PolkitAuthorizationResult) auth = NULL;
344359
345360 /* get result */
361 fu_main_set_status (helper->priv, FWUPD_STATUS_IDLE);
362 auth = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (source),
363 res, &error);
364 if (!fu_main_authorization_is_valid (auth, &error)) {
365 g_dbus_method_invocation_return_gerror (helper->invocation, error);
366 return;
367 }
368
369 /* authenticated */
370 if (!fu_engine_modify_remote (helper->priv->engine,
371 helper->remote_id,
372 helper->key,
373 helper->value,
374 &error)) {
375 g_dbus_method_invocation_return_gerror (helper->invocation, error);
376 return;
377 }
378
379 /* success */
380 g_dbus_method_invocation_return_value (helper->invocation, NULL);
381 }
382
383 static void
384 fu_main_authorize_install_cb (GObject *source, GAsyncResult *res, gpointer user_data)
385 {
386 g_autoptr(FuMainAuthHelper) helper = (FuMainAuthHelper *) user_data;
387 g_autoptr(GError) error = NULL;
388 g_autoptr(PolkitAuthorizationResult) auth = NULL;
389
390 /* get result */
391 fu_main_set_status (helper->priv, FWUPD_STATUS_IDLE);
346392 auth = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (source),
347393 res, &error);
348394 if (!fu_main_authorization_is_valid (auth, &error)) {
387433 g_dbus_method_invocation_return_value (invocation, val);
388434 return;
389435 }
390 if (g_strcmp0 (method_name, "GetUpdates") == 0) {
391 g_autoptr(GPtrArray) updates = NULL;
392 g_debug ("Called %s()", method_name);
393 updates = fu_engine_get_updates (priv->engine, &error);
394 if (updates == NULL) {
395 g_dbus_method_invocation_return_gerror (invocation, error);
396 return;
397 }
398 val = fu_main_device_array_to_variant (updates);
399 g_dbus_method_invocation_return_value (invocation, val);
400 return;
401 }
402436 if (g_strcmp0 (method_name, "GetReleases") == 0) {
403437 const gchar *device_id;
404438 g_autoptr(GPtrArray) releases = NULL;
413447 g_dbus_method_invocation_return_value (invocation, val);
414448 return;
415449 }
450 if (g_strcmp0 (method_name, "GetDowngrades") == 0) {
451 const gchar *device_id;
452 g_autoptr(GPtrArray) releases = NULL;
453 g_variant_get (parameters, "(&s)", &device_id);
454 g_debug ("Called %s(%s)", method_name, device_id);
455 releases = fu_engine_get_downgrades (priv->engine, device_id, &error);
456 if (releases == NULL) {
457 g_dbus_method_invocation_return_gerror (invocation, error);
458 return;
459 }
460 val = fu_main_release_array_to_variant (releases);
461 g_dbus_method_invocation_return_value (invocation, val);
462 return;
463 }
464 if (g_strcmp0 (method_name, "GetUpgrades") == 0) {
465 const gchar *device_id;
466 g_autoptr(GPtrArray) releases = NULL;
467 g_variant_get (parameters, "(&s)", &device_id);
468 g_debug ("Called %s(%s)", method_name, device_id);
469 releases = fu_engine_get_upgrades (priv->engine, device_id, &error);
470 if (releases == NULL) {
471 g_dbus_method_invocation_return_gerror (invocation, error);
472 return;
473 }
474 val = fu_main_release_array_to_variant (releases);
475 g_dbus_method_invocation_return_value (invocation, val);
476 return;
477 }
416478 if (g_strcmp0 (method_name, "GetRemotes") == 0) {
417479 g_autoptr(GPtrArray) remotes = NULL;
418480 g_debug ("Called %s()", method_name);
438500 }
439501 if (g_strcmp0 (method_name, "GetResults") == 0) {
440502 const gchar *device_id = NULL;
441 g_autoptr(FwupdResult) result = NULL;
503 g_autoptr(FwupdDevice) result = NULL;
442504 g_variant_get (parameters, "(&s)", &device_id);
443505 g_debug ("Called %s(%s)", method_name, device_id);
444506 result = fu_engine_get_results (priv->engine, device_id, &error);
446508 g_dbus_method_invocation_return_gerror (invocation, error);
447509 return;
448510 }
449 val = fwupd_result_to_data (result, "(a{sv})");
450 g_dbus_method_invocation_return_value (invocation, val);
451 return;
452 }
453 if (g_strcmp0 (method_name, "UpdateMetadataWithId") == 0) {
511 val = fwupd_device_to_variant (result);
512 g_dbus_method_invocation_return_value (invocation,
513 g_variant_new_tuple (&val, 1));
514 return;
515 }
516 if (g_strcmp0 (method_name, "UpdateMetadata") == 0) {
454517 GDBusMessage *message;
455518 GUnixFDList *fd_list;
456519 const gchar *remote_id = NULL;
501564 g_debug ("Called %s(%s)", method_name, device_id);
502565
503566 /* authenticate */
567 fu_main_set_status (priv, FWUPD_STATUS_WAITING_FOR_AUTH);
504568 helper = g_new0 (FuMainAuthHelper, 1);
505569 helper->priv = priv;
506570 helper->invocation = g_object_ref (invocation);
515579 helper);
516580 return;
517581 }
582 if (g_strcmp0 (method_name, "ModifyRemote") == 0) {
583 FuMainAuthHelper *helper;
584 const gchar *remote_id = NULL;
585 const gchar *key = NULL;
586 const gchar *value = NULL;
587 g_autoptr(PolkitSubject) subject = NULL;
588
589 /* check the id exists */
590 g_variant_get (parameters, "(&s&s&s)", &remote_id, &key, &value);
591 g_debug ("Called %s(%s,%s=%s)", method_name, remote_id, key, value);
592
593 /* create helper object */
594 helper = g_new0 (FuMainAuthHelper, 1);
595 helper->invocation = g_object_ref (invocation);
596 helper->remote_id = g_strdup (remote_id);
597 helper->key = g_strdup (key);
598 helper->value = g_strdup (value);
599 helper->priv = priv;
600
601 /* authenticate */
602 fu_main_set_status (priv, FWUPD_STATUS_WAITING_FOR_AUTH);
603 subject = polkit_system_bus_name_new (sender);
604 polkit_authority_check_authorization (helper->priv->authority, subject,
605 "org.freedesktop.fwupd.modify-remote",
606 NULL,
607 POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
608 NULL,
609 fu_main_authorize_modify_remote_cb,
610 helper);
611 return;
612 }
518613 if (g_strcmp0 (method_name, "VerifyUpdate") == 0) {
519614 FuMainAuthHelper *helper;
520615 const gchar *device_id = NULL;
531626 helper->priv = priv;
532627
533628 /* authenticate */
629 fu_main_set_status (priv, FWUPD_STATUS_WAITING_FOR_AUTH);
534630 subject = polkit_system_bus_name_new (sender);
535631 polkit_authority_check_authorization (helper->priv->authority, subject,
536632 "org.freedesktop.fwupd.verify-update",
637733 g_dbus_method_invocation_return_gerror (invocation, error);
638734 return;
639735 }
736 fu_main_set_status (priv, FWUPD_STATUS_WAITING_FOR_AUTH);
640737 subject = polkit_system_bus_name_new (sender);
641738 polkit_authority_check_authorization (priv->authority, subject,
642739 action_id, NULL,
646743 helper);
647744 return;
648745 }
649 if (g_strcmp0 (method_name, "GetDetailsLocal") == 0) {
746 if (g_strcmp0 (method_name, "GetDetails") == 0) {
650747 GDBusMessage *message;
651748 GUnixFDList *fd_list;
652749 gint32 fd_handle = 0;
675772 }
676773
677774 /* get details about the file (will close the fd when done) */
678 results = fu_engine_get_details_local (priv->engine, fd, &error);
775 results = fu_engine_get_details (priv->engine, fd, &error);
679776 if (results == NULL) {
680777 g_dbus_method_invocation_return_gerror (invocation, error);
681778 return;
2626 #include <sqlite3.h>
2727 #include <stdlib.h>
2828
29 #include "fu-device-private.h"
2930 #include "fu-pending.h"
3031
3132 static void fu_pending_finalize (GObject *object);
8182 sqlite3_free (error_msg);
8283 statement = "CREATE TABLE pending ("
8384 "device_id TEXT PRIMARY KEY,"
84 "unique_id TEXT,"
8585 "state INTEGER DEFAULT 0,"
8686 "timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,"
8787 "error TEXT,"
129129 sqlite3_exec (priv->db, statement, NULL, NULL, NULL);
130130 }
131131
132 /* check pending has unique_id (since 0.7.3) */
133 rc = sqlite3_exec (priv->db,
134 "SELECT unique_id FROM pending LIMIT 1",
135 NULL, NULL, &error_msg);
136 if (rc != SQLITE_OK) {
137 g_debug ("FuPending: altering table to repair: %s", error_msg);
138 sqlite3_free (error_msg);
139 statement = "ALTER TABLE pending ADD COLUMN unique_id TEXT;";
140 sqlite3_exec (priv->db, statement, NULL, NULL, NULL);
141 }
142
143132 return TRUE;
144133 }
145134
146135 gboolean
147 fu_pending_add_device (FuPending *pending, FwupdResult *res, GError **error)
148 {
149 FuPendingPrivate *priv = GET_PRIVATE (pending);
150 FwupdDevice *dev = fwupd_result_get_device (res);
151 FwupdRelease *rel = fwupd_result_get_release (res);
136 fu_pending_add_device (FuPending *pending, FuDevice *device, GError **error)
137 {
138 FuPendingPrivate *priv = GET_PRIVATE (pending);
152139 char *error_msg = NULL;
153140 char *statement;
154141 gboolean ret = TRUE;
162149 return FALSE;
163150 }
164151
165 g_debug ("FuPending: add device %s", fwupd_device_get_id (dev));
152 g_debug ("FuPending: add device %s", fu_device_get_id (device));
166153 statement = sqlite3_mprintf ("INSERT INTO pending (device_id,"
167 "unique_id,"
168154 "state,"
169155 "filename,"
170156 "display_name,"
171157 "provider,"
172158 "version_old,"
173159 "version_new) "
174 "VALUES ('%q','%q','%i','%q','%q','%q','%q','%q')",
175 fwupd_device_get_id (dev),
176 fwupd_result_get_unique_id (res),
160 "VALUES ('%q','%i','%q','%q','%q','%q','%q')",
161 fu_device_get_id (device),
177162 FWUPD_UPDATE_STATE_PENDING,
178 fwupd_release_get_filename (rel),
179 fwupd_device_get_name (dev),
180 fwupd_device_get_provider (dev),
181 fwupd_device_get_version (dev),
182 fwupd_release_get_version (rel));
163 fu_device_get_filename_pending (device),
164 fu_device_get_name (device),
165 fu_device_get_plugin (device),
166 fu_device_get_version (device),
167 fu_device_get_version_new (device));
183168
184169 /* insert entry */
185170 rc = sqlite3_exec (priv->db, statement, NULL, NULL, &error_msg);
199184 }
200185
201186 gboolean
202 fu_pending_remove_device (FuPending *pending, FwupdResult *res, GError **error)
203 {
204 FuPendingPrivate *priv = GET_PRIVATE (pending);
205 FwupdDevice *dev = fwupd_result_get_device (res);
187 fu_pending_remove_all (FuPending *pending, GError **error)
188 {
189 FuPendingPrivate *priv = GET_PRIVATE (pending);
190 char *error_msg = NULL;
191 gint rc;
192
193 g_return_val_if_fail (FU_IS_PENDING (pending), FALSE);
194
195 /* lazy load */
196 if (priv->db == NULL) {
197 if (!fu_pending_load (pending, error))
198 return FALSE;
199 }
200
201 /* remove entries */
202 g_debug ("FuPending: removing all devices");
203 rc = sqlite3_exec (priv->db, "DELETE FROM pending;", NULL, NULL, &error_msg);
204 if (rc != SQLITE_OK) {
205 g_set_error (error,
206 FWUPD_ERROR,
207 FWUPD_ERROR_WRITE,
208 "SQL error: %s", error_msg);
209 sqlite3_free (error_msg);
210 return FALSE;
211 }
212 return TRUE;
213 }
214
215 gboolean
216 fu_pending_remove_device (FuPending *pending, FuDevice *device, GError **error)
217 {
218 FuPendingPrivate *priv = GET_PRIVATE (pending);
206219 char *error_msg = NULL;
207220 char *statement;
208221 gboolean ret = TRUE;
216229 return FALSE;
217230 }
218231
219 g_debug ("FuPending: remove device %s", fwupd_device_get_id (dev));
232 g_debug ("FuPending: remove device %s", fu_device_get_id (device));
220233 statement = sqlite3_mprintf ("DELETE FROM pending WHERE "
221234 "device_id = '%q';",
222 fwupd_device_get_id (dev));
235 fu_device_get_id (device));
223236
224237 /* remove entry */
225238 rc = sqlite3_exec (priv->db, statement, NULL, NULL, &error_msg);
245258 gchar **col_name)
246259 {
247260 GPtrArray *array = (GPtrArray *) data;
248 FwupdDevice *dev;
249 FwupdRelease *rel;
250 FwupdResult *res;
261 FuDevice *device;
251262
252263 /* create new result */
253 res = fwupd_result_new ();
254 rel = fwupd_result_get_release (res);
255 dev = fwupd_result_get_device (res);
256 g_ptr_array_add (array, res);
264 device = fu_device_new ();
265 g_ptr_array_add (array, device);
257266
258267 g_debug ("FuPending: got sql result %s", argv[0]);
259268 for (gint i = 0; i < argc; i++) {
260269 if (g_strcmp0 (col_name[i], "device_id") == 0) {
261 fwupd_device_set_id (dev, argv[i]);
262 continue;
263 }
264 if (g_strcmp0 (col_name[i], "unique_id") == 0) {
265 fwupd_result_set_unique_id (res, argv[i]);
270 fu_device_set_id (device, argv[i]);
266271 continue;
267272 }
268273 if (g_strcmp0 (col_name[i], "filename") == 0) {
269 fwupd_release_set_filename (rel, argv[i]);
274 fu_device_set_filename_pending (device, argv[i]);
270275 continue;
271276 }
272277 if (g_strcmp0 (col_name[i], "display_name") == 0) {
273 fwupd_device_set_name (dev, argv[i]);
278 fu_device_set_name (device, argv[i]);
274279 continue;
275280 }
276281 if (g_strcmp0 (col_name[i], "version_old") == 0) {
277 fwupd_device_set_version (dev, argv[i]);
282 fu_device_set_version (device, argv[i]);
278283 continue;
279284 }
280285 if (g_strcmp0 (col_name[i], "version_new") == 0) {
281 fwupd_release_set_version (rel, argv[i]);
286 fu_device_set_version_new (device, argv[i]);
282287 continue;
283288 }
284289 if (g_strcmp0 (col_name[i], "provider") == 0) {
285 fwupd_device_set_provider (dev, argv[i]);
290 fu_device_set_plugin (device, argv[i]);
286291 continue;
287292 }
288293 if (g_strcmp0 (col_name[i], "state") == 0) {
289294 FwupdUpdateState state = atoi (argv[i]);
290 fwupd_result_set_update_state (res, state);
295 fu_device_set_update_state (device, state);
291296 continue;
292297 }
293298 if (g_strcmp0 (col_name[i], "timestamp") == 0) {
294299 guint64 timestamp = g_ascii_strtoull (argv[i], NULL, 10);
295300 if (timestamp > 0)
296 fwupd_device_set_created (dev, timestamp);
301 fu_device_set_created (device, timestamp);
297302 continue;
298303 }
299304 if (g_strcmp0 (col_name[i], "error") == 0) {
300305 if (argv[i] != NULL)
301 fwupd_result_set_update_error (res, argv[i]);
306 fu_device_set_update_error (device, argv[i]);
302307 continue;
303308 }
304309 }
306311 return 0;
307312 }
308313
309 FwupdResult *
314 FuDevice *
310315 fu_pending_get_device (FuPending *pending, const gchar *device_id, GError **error)
311316 {
312317 FuPendingPrivate *priv = GET_PRIVATE (pending);
313 FwupdResult *res = NULL;
318 FuDevice *device = NULL;
314319 char *error_msg = NULL;
315320 char *statement;
316321 gint rc;
325330 }
326331
327332 /* get all the devices */
328 g_debug ("FuPending: get res");
333 g_debug ("FuPending: get device");
329334 statement = sqlite3_mprintf ("SELECT * FROM pending WHERE "
330335 "device_id = '%q';",
331336 device_id);
351356 "No devices found");
352357 goto out;
353358 }
354 res = g_object_ref (g_ptr_array_index (array_tmp, 0));
359 device = g_object_ref (g_ptr_array_index (array_tmp, 0));
355360 out:
356361 sqlite3_free (statement);
357 return res;
362 return device;
358363 }
359364
360365 GPtrArray *
403408
404409 gboolean
405410 fu_pending_set_state (FuPending *pending,
406 FwupdResult *res,
411 FuDevice *device,
407412 FwupdUpdateState state,
408413 GError **error)
409414 {
410415 FuPendingPrivate *priv = GET_PRIVATE (pending);
411 FwupdDevice *dev = fwupd_result_get_device (res);
412416 char *error_msg = NULL;
413417 char *statement;
414418 gboolean ret = TRUE;
423427 }
424428
425429 g_debug ("FuPending: set state of %s to %s",
426 fwupd_device_get_id (dev),
430 fu_device_get_id (device),
427431 fwupd_update_state_to_string (state));
428432 statement = sqlite3_mprintf ("UPDATE pending SET state='%i' WHERE "
429433 "device_id = '%q';",
430 state, fwupd_device_get_id (dev));
434 state, fu_device_get_id (device));
431435
432436 /* remove entry */
433437 rc = sqlite3_exec (priv->db, statement, NULL, NULL, &error_msg);
448452
449453 gboolean
450454 fu_pending_set_error_msg (FuPending *pending,
451 FwupdResult *res,
455 FuDevice *device,
452456 const gchar *error_msg2,
453457 GError **error)
454458 {
455459 FuPendingPrivate *priv = GET_PRIVATE (pending);
456 FwupdDevice *dev = fwupd_result_get_device (res);
457460 char *error_msg = NULL;
458461 char *statement;
459462 gboolean ret = TRUE;
468471 }
469472
470473 g_debug ("FuPending: add comment to %s: %s",
471 fwupd_device_get_id (dev), error_msg2);
474 fu_device_get_id (device), error_msg2);
472475 statement = sqlite3_mprintf ("UPDATE pending SET error='%q' WHERE "
473476 "device_id = '%q';",
474477 error_msg2,
475 fwupd_device_get_id (dev));
478 fu_device_get_id (device));
476479
477480 /* remove entry */
478481 rc = sqlite3_exec (priv->db, statement, NULL, NULL, &error_msg);
3838 FuPending *fu_pending_new (void);
3939
4040 gboolean fu_pending_add_device (FuPending *pending,
41 FwupdResult *res,
41 FuDevice *device,
4242 GError **error);
4343 gboolean fu_pending_set_state (FuPending *pending,
44 FwupdResult *res,
45 FwupdUpdateState state,
44 FuDevice *device,
45 FwupdUpdateState state,
4646 GError **error);
4747 gboolean fu_pending_set_error_msg (FuPending *pending,
48 FwupdResult *res,
48 FuDevice *device,
4949 const gchar *error_msg,
5050 GError **error);
5151 gboolean fu_pending_remove_device (FuPending *pending,
52 FwupdResult *res,
52 FuDevice *device,
5353 GError **error);
54 FwupdResult *fu_pending_get_device (FuPending *pending,
54 gboolean fu_pending_remove_all (FuPending *pending,
55 GError **error);
56 FuDevice *fu_pending_get_device (FuPending *pending,
5557 const gchar *device_id,
5658 GError **error);
5759 GPtrArray *fu_pending_get_devices (FuPending *pending,
2222 #define __FU_PLUGIN_PRIVATE_H
2323
2424 #include "fu-plugin.h"
25 #include "fu-smbios.h"
2526
2627 G_BEGIN_DECLS
2728
2829 #define FU_OFFLINE_TRIGGER_FILENAME FU_OFFLINE_DESTDIR "/system-update"
2930
3031 FuPlugin *fu_plugin_new (void);
32 gboolean fu_plugin_has_device_delay (FuPlugin *plugin);
3133 void fu_plugin_set_usb_context (FuPlugin *plugin,
3234 GUsbContext *usb_ctx);
3335 void fu_plugin_set_hwids (FuPlugin *plugin,
3436 FuHwids *hwids);
37 void fu_plugin_set_supported (FuPlugin *plugin,
38 GPtrArray *supported_guids);
39 void fu_plugin_set_smbios (FuPlugin *plugin,
40 FuSmbios *smbios);
41 guint fu_plugin_get_order (FuPlugin *plugin);
42 void fu_plugin_set_order (FuPlugin *plugin,
43 guint order);
44 GPtrArray *fu_plugin_get_rules (FuPlugin *plugin,
45 FuPluginRule rule);
3546 gboolean fu_plugin_open (FuPlugin *plugin,
3647 const gchar *filename,
3748 GError **error);
3030 #include <valgrind.h>
3131 #endif /* HAVE_VALGRIND */
3232
33 #include "fu-device-private.h"
3334 #include "fu-plugin-private.h"
3435 #include "fu-pending.h"
36
37 /**
38 * SECTION:fu-plugin
39 * @short_description: a daemon plugin
40 *
41 * An object that represents a plugin run by the daemon.
42 *
43 * See also: #FuDevice
44 */
3545
3646 #define FU_PLUGIN_COLDPLUG_DELAY_MAXIMUM 3000u /* ms */
3747
4151 GModule *module;
4252 GUsbContext *usb_ctx;
4353 gboolean enabled;
54 guint order;
55 GPtrArray *rules[FU_PLUGIN_RULE_LAST];
4456 gchar *name;
4557 FuHwids *hwids;
58 GPtrArray *supported_guids;
59 FuSmbios *smbios;
4660 GHashTable *devices; /* platform_id:GObject */
4761 GHashTable *devices_delay; /* FuDevice:FuPluginHelper */
4862 FuPluginData *data;
162176 * fu_plugin_get_data:
163177 * @plugin: A #FuPlugin
164178 *
165 * Gets the per-plugin allocated private data.
166 *
167 * Returns: (transfer full): a pointer to a structure, or %NULL for unset.
179 * Gets the per-plugin allocated private data. This will return %NULL unless
180 * fu_plugin_alloc_data() has been called by the plugin.
181 *
182 * Returns: (transfer none): a pointer to a structure, or %NULL for unset.
168183 *
169184 * Since: 0.8.0
170185 **/
229244 * fu_plugin_get_enabled:
230245 * @plugin: A #FuPlugin
231246 *
232 * Returns if the plugin is enabled.
247 * Returns if the plugin is enabled. Plugins may self-disable using
248 * fu_plugin_set_enabled() or can be disabled by the daemon.
233249 *
234250 * Returns: %TRUE if the plugin is currently enabled.
235251 *
369385 fu_plugin_device_add_delay_cb (gpointer user_data)
370386 {
371387 FuPluginHelper *helper = (FuPluginHelper *) user_data;
388 fu_plugin_device_add (helper->plugin, helper->device);
372389 g_hash_table_remove (helper->devices, helper->device);
373 fu_plugin_device_add (helper->plugin, helper->device);
374390 fu_plugin_helper_free (helper);
375391 return FALSE;
376392 }
429445 }
430446
431447 /**
432 * fu_plugin_device_add:
448 * fu_plugin_device_remove:
433449 * @plugin: A #FuPlugin
434450 * @device: A #FuDevice
435451 *
516532 /**
517533 * fu_plugin_check_hwid:
518534 * @plugin: A #FuPlugin
519 * @hwid: A Hardware ID GUID, e.g. "6de5d951-d755-576b-bd09-c5cf66b27234"
535 * @hwid: A Hardware ID GUID, e.g. `6de5d951-d755-576b-bd09-c5cf66b27234`
520536 *
521537 * Checks to see if a specific GUID exists. All hardware IDs on a
522538 * specific system can be shown using the `fwupdmgr hwids` command.
523539 *
540 * Returns: %TRUE if the HwId is found on the system.
541 *
524542 * Since: 0.9.1
525543 **/
526544 gboolean
533551 }
534552
535553 /**
554 * fu_plugin_check_supported:
555 * @plugin: A #FuPlugin
556 * @guid: A Hardware ID GUID, e.g. `6de5d951-d755-576b-bd09-c5cf66b27234`
557 *
558 * Checks to see if a specific device GUID is supported, i.e. available in the
559 * AppStream metadata.
560 *
561 * Returns: %TRUE if the device is supported.
562 *
563 * Since: 1.0.0
564 **/
565 gboolean
566 fu_plugin_check_supported (FuPlugin *plugin, const gchar *guid)
567 {
568 FuPluginPrivate *priv = GET_PRIVATE (plugin);
569 if (priv->supported_guids == NULL)
570 return FALSE;
571 for (guint i = 0; i < priv->supported_guids->len; i++) {
572 const gchar *guid_tmp = g_ptr_array_index (priv->supported_guids, i);
573 if (g_strcmp0 (guid, guid_tmp) == 0)
574 return TRUE;
575 }
576 return FALSE;
577 }
578
579 /**
536580 * fu_plugin_get_dmi_value:
537581 * @plugin: A #FuPlugin
538 * @dmi_id: A DMI ID, e.g. "BiosVersion"
582 * @dmi_id: A DMI ID, e.g. `BiosVersion`
539583 *
540584 * Gets a hardware DMI value.
585 *
586 * Returns: The string, or %NULL
541587 *
542588 * Since: 0.9.7
543589 **/
550596 return fu_hwids_get_value (priv->hwids, dmi_id);
551597 }
552598
599 /**
600 * fu_plugin_get_smbios_string:
601 * @plugin: A #FuPlugin
602 * @structure_type: A SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
603 * @offset: A SMBIOS offset
604 *
605 * Gets a hardware SMBIOS string.
606 *
607 * The @type and @offset can be referenced from the DMTF SMBIOS specification:
608 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
609 *
610 * Returns: A string, or %NULL
611 *
612 * Since: 0.9.8
613 **/
614 const gchar *
615 fu_plugin_get_smbios_string (FuPlugin *plugin, guint8 structure_type, guint8 offset)
616 {
617 FuPluginPrivate *priv = GET_PRIVATE (plugin);
618 if (priv->smbios == NULL)
619 return NULL;
620 return fu_smbios_get_string (priv->smbios, structure_type, offset, NULL);
621 }
622
623 /**
624 * fu_plugin_get_smbios_data:
625 * @plugin: A #FuPlugin
626 * @structure_type: A SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
627 *
628 * Gets a hardware SMBIOS data.
629 *
630 * Returns: (transfer none): A #GBytes, or %NULL
631 *
632 * Since: 0.9.8
633 **/
634 GBytes *
635 fu_plugin_get_smbios_data (FuPlugin *plugin, guint8 structure_type)
636 {
637 FuPluginPrivate *priv = GET_PRIVATE (plugin);
638 if (priv->smbios == NULL)
639 return NULL;
640 return fu_smbios_get_data (priv->smbios, structure_type, NULL);
641 }
642
553643 void
554644 fu_plugin_set_hwids (FuPlugin *plugin, FuHwids *hwids)
555645 {
556646 FuPluginPrivate *priv = GET_PRIVATE (plugin);
557647 g_set_object (&priv->hwids, hwids);
648 }
649
650 void
651 fu_plugin_set_supported (FuPlugin *plugin, GPtrArray *supported_guids)
652 {
653 FuPluginPrivate *priv = GET_PRIVATE (plugin);
654 if (priv->supported_guids != NULL)
655 g_ptr_array_unref (priv->supported_guids);
656 priv->supported_guids = g_ptr_array_ref (supported_guids);
657 }
658
659 /**
660 * fu_plugin_get_supported:
661 * @plugin: A #FuPlugin
662 *
663 * Gets all the device GUIDs supported by the daemon.
664 *
665 * Returns: (element-type utf8) (transfer none): GUIDs
666 *
667 * Since: 1.0.0
668 **/
669 GPtrArray *
670 fu_plugin_get_supported (FuPlugin *plugin)
671 {
672 FuPluginPrivate *priv = GET_PRIVATE (plugin);
673 return priv->supported_guids;
674 }
675
676 void
677 fu_plugin_set_smbios (FuPlugin *plugin, FuSmbios *smbios)
678 {
679 FuPluginPrivate *priv = GET_PRIVATE (plugin);
680 g_set_object (&priv->smbios, smbios);
558681 }
559682
560683 /**
797920 gchar tmpname[] = {"XXXXXX.cap"};
798921 g_autofree gchar *dirname = NULL;
799922 g_autofree gchar *filename = NULL;
800 g_autoptr(FwupdResult) res_tmp = NULL;
923 g_autoptr(FuDevice) res_tmp = NULL;
801924 g_autoptr(FuPending) pending = NULL;
802925 g_autoptr(GFile) file = NULL;
803926
837960 /* schedule for next boot */
838961 g_debug ("schedule %s to be installed to %s on next boot",
839962 filename, fu_device_get_id (device));
840 fu_device_set_update_filename (device, filename);
963 fu_device_set_filename_pending (device, filename);
841964
842965 /* add to database */
843 if (!fu_pending_add_device (pending, FWUPD_RESULT (device), error))
966 if (!fu_pending_add_device (pending, device, error))
844967 return FALSE;
845968
846969 /* next boot we run offline */
9271050 FuPluginPrivate *priv = GET_PRIVATE (plugin);
9281051 FuPluginUpdateFunc update_func;
9291052 g_autoptr(FuPending) pending = NULL;
930 g_autoptr(FwupdResult) res_pending = NULL;
1053 g_autoptr(FuDevice) device_pending = NULL;
9311054 GError *error_update = NULL;
9321055 GPtrArray *checksums;
9331056
9591082
9601083 /* online */
9611084 pending = fu_pending_new ();
962 res_pending = fu_pending_get_device (pending, fu_device_get_id (device), NULL);
1085 device_pending = fu_pending_get_device (pending, fu_device_get_id (device), NULL);
9631086 if (!update_func (plugin, device, blob_fw, flags, &error_update)) {
9641087 /* save the error to the database */
965 if (res_pending != NULL) {
966 fu_pending_set_error_msg (pending, FWUPD_RESULT (device),
1088 if (device_pending != NULL) {
1089 fu_pending_set_error_msg (pending, device,
9671090 error_update->message, NULL);
9681091 }
9691092 g_propagate_error (error, error_update);
9751098 g_ptr_array_set_size (checksums, 0);
9761099
9771100 /* cleanup */
978 if (res_pending != NULL) {
1101 if (device_pending != NULL) {
9791102 const gchar *tmp;
980 FwupdRelease *rel = fwupd_result_get_release (res_pending);
9811103
9821104 /* update pending database */
983 fu_pending_set_state (pending, FWUPD_RESULT (device),
1105 fu_pending_set_state (pending, device,
9841106 FWUPD_UPDATE_STATE_SUCCESS, NULL);
9851107
9861108 /* delete cab file */
987 tmp = fwupd_release_get_filename (rel);
1109 tmp = fu_device_get_filename_pending (device_pending);
9881110 if (tmp != NULL && g_str_has_prefix (tmp, LIBEXECDIR)) {
9891111 g_autoptr(GError) error_local = NULL;
9901112 g_autoptr(GFile) file = NULL;
10081130 FuPluginPrivate *priv = GET_PRIVATE (plugin);
10091131 FuPluginDeviceFunc func = NULL;
10101132 g_autoptr(GError) error_local = NULL;
1011 g_autoptr(FwupdResult) res_pending = NULL;
1133 g_autoptr(FuDevice) device_pending = NULL;
10121134 g_autoptr(FuPending) pending = NULL;
10131135
10141136 /* not enabled */
10281150
10291151 /* handled using the database */
10301152 pending = fu_pending_new ();
1031 res_pending = fu_pending_get_device (pending,
1153 device_pending = fu_pending_get_device (pending,
10321154 fu_device_get_id (device),
10331155 &error_local);
1034 if (res_pending == NULL) {
1156 if (device_pending == NULL) {
10351157 g_set_error (error,
10361158 FWUPD_ERROR,
10371159 FWUPD_ERROR_INVALID_FILE,
10421164 }
10431165
10441166 /* remove from pending database */
1045 return fu_pending_remove_device (pending, FWUPD_RESULT (device), error);
1167 return fu_pending_remove_device (pending, device, error);
10461168 }
10471169
10481170 gboolean
10511173 FuPluginPrivate *priv = GET_PRIVATE (plugin);
10521174 FuPluginDeviceFunc func = NULL;
10531175 FwupdUpdateState update_state;
1054 FwupdRelease *rel;
1055 FwupdDevice *dev;
10561176 const gchar *tmp;
10571177 g_autoptr(GError) error_local = NULL;
1058 g_autoptr(FwupdResult) res_pending = NULL;
1178 g_autoptr(FuDevice) device_pending = NULL;
10591179 g_autoptr(FuPending) pending = NULL;
10601180
10611181 /* not enabled */
10751195
10761196 /* handled using the database */
10771197 pending = fu_pending_new ();
1078 res_pending = fu_pending_get_device (pending,
1198 device_pending = fu_pending_get_device (pending,
10791199 fu_device_get_id (device),
10801200 &error_local);
1081 if (res_pending == NULL) {
1201 if (device_pending == NULL) {
10821202 g_set_error (error,
10831203 FWUPD_ERROR,
10841204 FWUPD_ERROR_NOTHING_TO_DO,
10891209 }
10901210
10911211 /* copy the important parts from the pending device to the real one */
1092 update_state = fwupd_result_get_update_state (res_pending);
1212 update_state = fu_device_get_update_state (device_pending);
10931213 if (update_state == FWUPD_UPDATE_STATE_UNKNOWN ||
10941214 update_state == FWUPD_UPDATE_STATE_PENDING) {
10951215 g_set_error (error,
11021222
11031223 /* copy */
11041224 fu_device_set_update_state (device, update_state);
1105 tmp = fwupd_result_get_update_error (res_pending);
1225 tmp = fu_device_get_update_error (device_pending);
11061226 if (tmp != NULL)
11071227 fu_device_set_update_error (device, tmp);
1108 dev = fwupd_result_get_device (res_pending);
1109 tmp = fwupd_device_get_version (dev);
1228 tmp = fu_device_get_version (device_pending);
11101229 if (tmp != NULL)
11111230 fu_device_set_version (device, tmp);
1112 rel = fwupd_result_get_release (res_pending);
1113 tmp = fwupd_release_get_version (rel);
1231 tmp = fu_device_get_version_new (device_pending);
11141232 if (tmp != NULL)
1115 fu_device_set_update_version (device, tmp);
1233 fu_device_set_version_new (device, tmp);
11161234 return TRUE;
1235 }
1236
1237 /**
1238 * fu_plugin_get_order:
1239 * @plugin: a #FuPlugin
1240 *
1241 * Gets the plugin order, where higher numbers are run after lower
1242 * numbers.
1243 *
1244 * Returns: the integer value
1245 **/
1246 guint
1247 fu_plugin_get_order (FuPlugin *plugin)
1248 {
1249 FuPluginPrivate *priv = fu_plugin_get_instance_private (plugin);
1250 return priv->order;
1251 }
1252
1253 /**
1254 * fu_plugin_set_order:
1255 * @plugin: a #FuPlugin
1256 * @order: a integer value
1257 *
1258 * Sets the plugin order, where higher numbers are run after lower
1259 * numbers.
1260 **/
1261 void
1262 fu_plugin_set_order (FuPlugin *plugin, guint order)
1263 {
1264 FuPluginPrivate *priv = fu_plugin_get_instance_private (plugin);
1265 priv->order = order;
1266 }
1267
1268 /**
1269 * fu_plugin_add_rule:
1270 * @plugin: a #FuPlugin
1271 * @rule: a #FuPluginRule, e.g. %FU_PLUGIN_RULE_CONFLICTS
1272 * @name: a plugin name, e.g. `upower`
1273 *
1274 * If the plugin name is found, the rule will be used to sort the plugin list,
1275 * for example the plugin specified by @name will be ordered after this plugin
1276 * when %FU_PLUGIN_RULE_RUN_AFTER is used.
1277 *
1278 * NOTE: The depsolver is iterative and may not solve overly-complicated rules;
1279 * If depsolving fails then fwupd will not start.
1280 **/
1281 void
1282 fu_plugin_add_rule (FuPlugin *plugin, FuPluginRule rule, const gchar *name)
1283 {
1284 FuPluginPrivate *priv = fu_plugin_get_instance_private (plugin);
1285 g_ptr_array_add (priv->rules[rule], g_strdup (name));
1286 }
1287
1288 /**
1289 * fu_plugin_get_rules:
1290 * @plugin: a #FuPlugin
1291 * @rule: a #FuPluginRule, e.g. %FU_PLUGIN_RULE_CONFLICTS
1292 *
1293 * Gets the plugin IDs that should be run after this plugin.
1294 *
1295 * Returns: (element-type utf8) (transfer none): the list of plugin names, e.g. ['appstream']
1296 **/
1297 GPtrArray *
1298 fu_plugin_get_rules (FuPlugin *plugin, FuPluginRule rule)
1299 {
1300 FuPluginPrivate *priv = fu_plugin_get_instance_private (plugin);
1301 return priv->rules[rule];
11171302 }
11181303
11191304 static void
11731358 priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
11741359 g_free, (GDestroyNotify) g_object_unref);
11751360 priv->devices_delay = g_hash_table_new (g_direct_hash, g_direct_equal);
1361 for (guint i = 0; i < FU_PLUGIN_RULE_LAST; i++)
1362 priv->rules[i] = g_ptr_array_new_with_free_func (g_free);
11761363 }
11771364
11781365 static void
11911378 }
11921379 }
11931380
1381 for (guint i = 0; i < FU_PLUGIN_RULE_LAST; i++)
1382 g_ptr_array_unref (priv->rules[i]);
1383
11941384 if (priv->usb_ctx != NULL)
11951385 g_object_unref (priv->usb_ctx);
11961386 if (priv->hwids != NULL)
11971387 g_object_unref (priv->hwids);
1388 if (priv->supported_guids != NULL)
1389 g_ptr_array_unref (priv->supported_guids);
1390 if (priv->smbios != NULL)
1391 g_object_unref (priv->smbios);
11981392 #ifndef RUNNING_ON_VALGRIND
11991393 if (priv->module != NULL)
12001394 g_module_close (priv->module);
2828
2929 #include "fu-common.h"
3030 #include "fu-device.h"
31 #include "fu-device-locker.h"
3132 #include "fu-hwids.h"
3233
3334 G_BEGIN_DECLS
5657 gpointer padding[24];
5758 };
5859
60 /**
61 * FuPluginVerifyFlags:
62 * @FU_PLUGIN_VERIFY_FLAG_NONE: No flags set
63 *
64 * Flags used when verifying, currently unused.
65 **/
5966 typedef enum {
6067 FU_PLUGIN_VERIFY_FLAG_NONE = 0,
68 /*< private >*/
6169 FU_PLUGIN_VERIFY_FLAG_LAST
6270 } FuPluginVerifyFlags;
71
72 /**
73 * FuPluginRule:
74 * @FU_PLUGIN_RULE_CONFLICTS: The plugin conflicts with another
75 * @FU_PLUGIN_RULE_RUN_AFTER: Order the plugin after another
76 * @FU_PLUGIN_RULE_RUN_BEFORE: Order the plugin before another
77 *
78 * The rules used for ordering plugins.
79 * Plugins are expected to add rules in fu_plugin_initialize().
80 **/
81 typedef enum {
82 FU_PLUGIN_RULE_CONFLICTS,
83 FU_PLUGIN_RULE_RUN_AFTER,
84 FU_PLUGIN_RULE_RUN_BEFORE,
85 /*< private >*/
86 FU_PLUGIN_RULE_LAST
87 } FuPluginRule;
6388
6489 typedef struct FuPluginData FuPluginData;
6590
7297 void fu_plugin_set_enabled (FuPlugin *plugin,
7398 gboolean enabled);
7499 GUsbContext *fu_plugin_get_usb_context (FuPlugin *plugin);
100 GPtrArray *fu_plugin_get_supported (FuPlugin *plugin);
75101 void fu_plugin_device_add (FuPlugin *plugin,
76102 FuDevice *device);
77103 void fu_plugin_device_add_delay (FuPlugin *plugin,
87113 void fu_plugin_recoldplug (FuPlugin *plugin);
88114 void fu_plugin_set_coldplug_delay (FuPlugin *plugin,
89115 guint duration);
90 gboolean fu_plugin_has_device_delay (FuPlugin *plugin);
91116 gpointer fu_plugin_cache_lookup (FuPlugin *plugin,
92117 const gchar *id);
93118 void fu_plugin_cache_remove (FuPlugin *plugin,
97122 gpointer dev);
98123 gboolean fu_plugin_check_hwid (FuPlugin *plugin,
99124 const gchar *hwid);
125 gboolean fu_plugin_check_supported (FuPlugin *plugin,
126 const gchar *guid);
100127 const gchar *fu_plugin_get_dmi_value (FuPlugin *plugin,
101128 const gchar *dmi_id);
129 const gchar *fu_plugin_get_smbios_string (FuPlugin *plugin,
130 guint8 structure_type,
131 guint8 offset);
132 GBytes *fu_plugin_get_smbios_data (FuPlugin *plugin,
133 guint8 structure_type);
134 void fu_plugin_add_rule (FuPlugin *plugin,
135 FuPluginRule rule,
136 const gchar *name);
102137
103138 G_END_DECLS
104139
3737 guint percentage;
3838 guint to_erase; /* chars */
3939 guint timer_id;
40 gint64 last_animated; /* monotonic */
4041 };
4142
4243 G_DEFINE_TYPE (FuProgressbar, fu_progressbar, G_TYPE_OBJECT)
6162 /* TRANSLATORS: restarting the device to pick up new F/W */
6263 return _("Restarting device…");
6364 break;
65 case FWUPD_STATUS_DEVICE_READ:
66 /* TRANSLATORS: reading from the flash chips */
67 return _("Reading…");
68 break;
6469 case FWUPD_STATUS_DEVICE_WRITE:
6570 /* TRANSLATORS: writing to the flash chips */
6671 return _("Writing…");
6772 break;
73 case FWUPD_STATUS_DEVICE_ERASE:
74 /* TRANSLATORS: erasing contents of the flash chips */
75 return _("Erasing…");
76 break;
6877 case FWUPD_STATUS_DEVICE_VERIFY:
6978 /* TRANSLATORS: verifying we wrote the firmware correctly */
7079 return _("Verifying…");
7786 /* TRANSLATORS: downloading from a remote server */
7887 return _("Downloading…");
7988 break;
89 case FWUPD_STATUS_WAITING_FOR_AUTH:
90 /* TRANSLATORS: waiting for user to authenticate */
91 return _("Authenticating…");
92 break;
8093 default:
8194 break;
8295 }
8699 }
87100
88101 static void
89 fu_progressbar_refresh (FuProgressbar *self)
102 fu_progressbar_refresh (FuProgressbar *self, FwupdStatus status, guint percentage)
90103 {
91104 const gchar *title;
92105 guint i;
106 gboolean is_idle_newline = FALSE;
93107 g_autoptr(GString) str = g_string_new (NULL);
94108
95109 /* erase previous line */
97111 g_print ("\b");
98112
99113 /* add status */
100 if (self->status == FWUPD_STATUS_IDLE) {
101 if (self->to_erase > 0)
102 g_print ("\n");
103 self->to_erase = 0;
104 return;
105 }
106 title = fu_progressbar_status_to_string (self->status);
114 if (status == FWUPD_STATUS_IDLE) {
115 percentage = 100;
116 status = self->status;
117 is_idle_newline = TRUE;
118 }
119 title = fu_progressbar_status_to_string (status);
107120 g_string_append (str, title);
108121 for (i = str->len; i < self->length_status; i++)
109122 g_string_append_c (str, ' ');
110123
111124 /* add progressbar */
112125 g_string_append (str, "[");
113 if (self->percentage > 0) {
114 for (i = 0; i < self->length_percentage * self->percentage / 100; i++)
126 if (percentage > 0) {
127 for (i = 0; i < (self->length_percentage - 1) * percentage / 100; i++)
115128 g_string_append_c (str, '*');
116129 for (i = i + 1; i < self->length_percentage; i++)
117130 g_string_append_c (str, ' ');
120133 for (i = 0; i < self->spinner_idx; i++)
121134 g_string_append_c (str, ' ');
122135 g_string_append_c (str, chars[i / 4 % G_N_ELEMENTS(chars)]);
123 for (i = i + 1; i < self->length_percentage; i++)
136 for (i = i + 1; i < self->length_percentage - 1; i++)
124137 g_string_append_c (str, ' ');
125138 }
126139 g_string_append_c (str, ']');
127140
128141 /* dump to screen */
129142 g_print ("%s", str->str);
130 self->to_erase = str->len;
131 }
132
133 static gboolean
134 fu_progressbar_spin_cb (gpointer user_data)
135 {
136 FuProgressbar *self = FU_PROGRESSBAR (user_data);
137
138 /* move the spinner index up to down */
143 self->to_erase = str->len - 2;
144
145 /* done */
146 if (is_idle_newline) {
147 g_print ("\n");
148 self->to_erase = 0;
149 return;
150 }
151 }
152
153 static void
154 fu_progressbar_spin_inc (FuProgressbar *self)
155 {
156 /* reset */
157 self->last_animated = g_get_monotonic_time ();
158
159 /* up to down */
139160 if (self->spinner_count_up) {
140 if (++self->spinner_idx > self->length_percentage - 2)
161 if (++self->spinner_idx > self->length_percentage - 3)
141162 self->spinner_count_up = FALSE;
142163 } else {
143164 if (--self->spinner_idx == 0)
144165 self->spinner_count_up = TRUE;
145166 }
167 }
168
169 static gboolean
170 fu_progressbar_spin_cb (gpointer user_data)
171 {
172 FuProgressbar *self = FU_PROGRESSBAR (user_data);
173
174 /* ignore */
175 if (self->status == FWUPD_STATUS_IDLE)
176 return G_SOURCE_CONTINUE;
177
178 /* move the spinner index up to down */
179 fu_progressbar_spin_inc (self);
146180
147181 /* update the terminal */
148 fu_progressbar_refresh (self);
182 fu_progressbar_refresh (self, self->status, self->percentage);
149183
150184 return G_SOURCE_CONTINUE;
151185 }
176210 {
177211 g_return_if_fail (FU_IS_PROGRESSBAR (self));
178212
179 /* cache */
180 self->status = status;
181 self->percentage = percentage;
213 /* use cached value */
214 if (status == FWUPD_STATUS_UNKNOWN)
215 status = self->status;
216
217 /* if the main loop isn't spinning and we've not had a chance to
218 * execute the callback just do the refresh now manually */
219 if (percentage == 0 &&
220 status != FWUPD_STATUS_IDLE &&
221 self->status != FWUPD_STATUS_UNKNOWN) {
222 if ((g_get_monotonic_time () - self->last_animated) / 1000 > 40) {
223 fu_progressbar_spin_inc (self);
224 fu_progressbar_refresh (self, status, percentage);
225 }
226 }
227
228 /* ignore duplicates */
229 if (self->status == status &&
230 self->percentage == percentage)
231 return;
182232
183233 /* enable or disable the spinner timeout */
184234 if (percentage > 0) {
188238 }
189239
190240 /* update the terminal */
191 fu_progressbar_refresh (self);
241 fu_progressbar_refresh (self, status, percentage);
242
243 /* cache */
244 self->status = status;
245 self->percentage = percentage;
192246 }
193247
194248 void
2828 #include <stdlib.h>
2929 #include <string.h>
3030
31 #include "fu-device.h"
31 #include "fu-device-private.h"
32 #include "fu-engine.h"
3233 #include "fu-keyring.h"
3334 #include "fu-pending.h"
3435 #include "fu-plugin-private.h"
36 #include "fu-progressbar.h"
3537 #include "fu-hwids.h"
38 #include "fu-smbios.h"
3639 #include "fu-test.h"
3740
3841 #ifdef ENABLE_GPG
4346 #endif
4447
4548 static void
49 fu_engine_func (void)
50 {
51 FwupdRelease *rel;
52 gboolean ret;
53 g_autofree gchar *testdatadir = NULL;
54 g_autoptr(FuDevice) device = fu_device_new ();
55 g_autoptr(FuEngine) engine = fu_engine_new ();
56 g_autoptr(FuPlugin) plugin = fu_plugin_new ();
57 g_autoptr(GError) error = NULL;
58 g_autoptr(GPtrArray) devices = NULL;
59 g_autoptr(GPtrArray) devices_pre = NULL;
60 g_autoptr(GPtrArray) releases_dg = NULL;
61 g_autoptr(GPtrArray) releases = NULL;
62 g_autoptr(GPtrArray) releases_up = NULL;
63 g_autoptr(GPtrArray) remotes = NULL;
64
65 /* write a broken file */
66 ret = g_file_set_contents ("/tmp/fwupd-self-test/broken.xml.gz",
67 "this is not a valid", -1, &error);
68 g_assert_no_error (error);
69 g_assert (ret);
70
71 /* write the main file */
72 ret = g_file_set_contents ("/tmp/fwupd-self-test/stable.xml",
73 "<components>"
74 " <component type=\"firmware\">"
75 " <id>test</id>"
76 " <name>Test Device</name>"
77 " <provides>"
78 " <firmware type=\"flashed\">aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</firmware>"
79 " </provides>"
80 " <releases>"
81 " <release version=\"1.2.3\" date=\"2017-09-15\">"
82 " <size type=\"installed\">123</size>"
83 " <size type=\"download\">456</size>"
84 " <location>https://test.org/foo.cab</location>"
85 " <checksum filename=\"foo.cab\" target=\"container\" type=\"md5\">deadbeefdeadbeefdeadbeefdeadbeef</checksum>"
86 " <checksum filename=\"firmware.bin\" target=\"content\" type=\"md5\">deadbeefdeadbeefdeadbeefdeadbeef</checksum>"
87 " </release>"
88 " <release version=\"1.2.2\" date=\"2017-09-01\">"
89 " <size type=\"installed\">123</size>"
90 " <size type=\"download\">456</size>"
91 " <location>https://test.org/foo.cab</location>"
92 " <checksum filename=\"foo.cab\" target=\"container\" type=\"md5\">deadbeefdeadbeefdeadbeefdeadbeef</checksum>"
93 " <checksum filename=\"firmware.bin\" target=\"content\" type=\"md5\">deadbeefdeadbeefdeadbeefdeadbeef</checksum>"
94 " </release>"
95 " </releases>"
96 " </component>"
97 "</components>", -1, &error);
98 g_assert_no_error (error);
99 g_assert (ret);
100
101 /* write the extra file */
102 ret = g_file_set_contents ("/tmp/fwupd-self-test/testing.xml",
103 "<components>"
104 " <component type=\"firmware\">"
105 " <id>test</id>"
106 " <name>Test Device</name>"
107 " <provides>"
108 " <firmware type=\"flashed\">aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</firmware>"
109 " </provides>"
110 " <releases>"
111 " <release version=\"1.2.4\" date=\"2017-09-15\">"
112 " <size type=\"installed\">123</size>"
113 " <size type=\"download\">456</size>"
114 " <location>https://test.org/foo.cab</location>"
115 " <checksum filename=\"foo.cab\" target=\"container\" type=\"md5\">deadbeefdeadbeefdeadbeefdeadbeef</checksum>"
116 " <checksum filename=\"firmware.bin\" target=\"content\" type=\"md5\">deadbeefdeadbeefdeadbeefdeadbeef</checksum>"
117 " </release>"
118 " </releases>"
119 " </component>"
120 "</components>", -1, &error);
121 g_assert_no_error (error);
122 g_assert (ret);
123
124 /* expect just one broken remote to fail */
125 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
126 "failed to load remote broken: *");
127
128 testdatadir = fu_test_get_filename (TESTDATADIR, ".");
129 g_assert (testdatadir != NULL);
130 g_setenv ("FU_SELF_TEST_REMOTES_DIR", testdatadir, TRUE);
131 ret = fu_engine_load (engine, &error);
132 g_assert_no_error (error);
133 g_assert (ret);
134 g_assert_cmpint (fu_engine_get_status (engine), ==, FWUPD_STATUS_IDLE);
135 g_test_assert_expected_messages ();
136
137 /* return all the remotes, even the broken one */
138 remotes = fu_engine_get_remotes (engine, &error);
139 g_assert_no_error (error);
140 g_assert (remotes != NULL);
141 g_assert_cmpint (remotes->len, ==, 3);
142
143 /* ensure there are no devices already */
144 devices_pre = fu_engine_get_devices (engine, &error);
145 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO);
146 g_assert (devices_pre == NULL);
147 g_clear_error (&error);
148
149 /* add a device so we can get upgrades and downgrades */
150 fu_device_set_version (device, "1.2.3");
151 fu_device_set_id (device, "test_device");
152 fu_device_set_name (device, "Test Device");
153 fu_device_add_guid (device, "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
154 fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
155 fu_engine_add_device (engine, plugin, device);
156 devices = fu_engine_get_devices (engine, &error);
157 g_assert_no_error (error);
158 g_assert (devices != NULL);
159 g_assert_cmpint (devices->len, ==, 1);
160 g_assert (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_SUPPORTED));
161 g_assert (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REGISTERED));
162
163 /* get the releases for one device */
164 releases = fu_engine_get_releases (engine, fu_device_get_id (device), &error);
165 g_assert_no_error (error);
166 g_assert (releases != NULL);
167 g_assert_cmpint (releases->len, ==, 3);
168
169 /* upgrades */
170 releases_up = fu_engine_get_upgrades (engine, fu_device_get_id (device), &error);
171 g_assert_no_error (error);
172 g_assert (releases_up != NULL);
173 g_assert_cmpint (releases_up->len, ==, 1);
174 rel = FWUPD_RELEASE (g_ptr_array_index (releases_up, 0));
175 g_assert_cmpstr (fwupd_release_get_version (rel), ==, "1.2.4");
176
177 /* downgrades */
178 releases_dg = fu_engine_get_downgrades (engine, fu_device_get_id (device), &error);
179 g_assert_no_error (error);
180 g_assert (releases_dg != NULL);
181 g_assert_cmpint (releases_dg->len, ==, 1);
182 rel = FWUPD_RELEASE (g_ptr_array_index (releases_dg, 0));
183 g_assert_cmpstr (fwupd_release_get_version (rel), ==, "1.2.2");
184 }
185
186 static void
46187 fu_device_metadata_func (void)
47188 {
48189 g_autoptr(FuDevice) device = fu_device_new ();
74215 }
75216
76217 static void
218 fu_smbios_func (void)
219 {
220 const gchar *str;
221 gboolean ret;
222 g_autofree gchar *dump = NULL;
223 g_autoptr(FuSmbios) smbios = NULL;
224 g_autoptr(GError) error = NULL;
225
226 smbios = fu_smbios_new ();
227 ret = fu_smbios_setup (smbios, &error);
228 g_assert_no_error (error);
229 g_assert (ret);
230 dump = fu_smbios_to_string (smbios);
231 if (g_getenv ("VERBOSE") != NULL)
232 g_debug ("%s", dump);
233
234 /* test for missing table */
235 str = fu_smbios_get_string (smbios, 0xff, 0, &error);
236 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE);
237 g_assert_null (str);
238 g_clear_error (&error);
239
240 /* check for invalid offset */
241 str = fu_smbios_get_string (smbios, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0xff, &error);
242 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE);
243 g_assert_null (str);
244 g_clear_error (&error);
245
246 /* get vendor */
247 str = fu_smbios_get_string (smbios, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0x04, &error);
248 g_assert_no_error (error);
249 g_assert_cmpstr (str, ==, "LENOVO");
250 }
251
252 static void
253 fu_smbios3_func (void)
254 {
255 const gchar *str;
256 gboolean ret;
257 g_autofree gchar *path = NULL;
258 g_autoptr(FuSmbios) smbios = NULL;
259 g_autoptr(GError) error = NULL;
260
261 path = fu_test_get_filename (TESTDATADIR, "dmi/tables64");
262 g_assert_nonnull (path);
263
264 smbios = fu_smbios_new ();
265 ret = fu_smbios_setup_from_path (smbios, path, &error);
266 g_assert_no_error (error);
267 g_assert (ret);
268 if (g_getenv ("VERBOSE") != NULL) {
269 g_autofree gchar *dump = fu_smbios_to_string (smbios);
270 g_debug ("%s", dump);
271 }
272
273 /* get vendor */
274 str = fu_smbios_get_string (smbios, FU_SMBIOS_STRUCTURE_TYPE_BIOS, 0x04, &error);
275 g_assert_no_error (error);
276 g_assert_cmpstr (str, ==, "Dell Inc.");
277 }
278
279 static void
77280 fu_hwids_func (void)
78281 {
79282 g_autoptr(FuHwids) hwids = NULL;
283 g_autoptr(FuSmbios) smbios = NULL;
80284 g_autoptr(GError) error = NULL;
81 g_autofree gchar *sysfsdir = NULL;
82285 gboolean ret;
83286
84287 struct {
85288 const gchar *key;
86289 const gchar *value;
87290 } guids[] = {
88 { "Manufacturer", "11b4a036-3b64-5421-a372-22c07df10a4d" },
89 { "HardwareID-14", "11b4a036-3b64-5421-a372-22c07df10a4d" },
90 { "HardwareID-13", "7ccbb6f1-9641-5f84-b00d-51ff218a4066" },
91 { "HardwareID-12", "482f3f58-6045-593a-9be4-611717ce4770" },
92 { "HardwareID-11", "6525c6e5-28e9-5f9c-abe4-20fd82504002" },
93 { "HardwareID-10", "c00fe015-014c-5301-90d1-b5c8ab037eb4" },
94 { "HardwareID-9", "6525c6e5-28e9-5f9c-abe4-20fd82504002" },
95 { "HardwareID-8", "c00fe015-014c-5301-90d1-b5c8ab037eb4" },
96 { "HardwareID-7", "5a127cba-be28-5d3b-84f0-0e450d266d97" },
97 { "HardwareID-6", "2c2d02cc-357e-539d-a44d-d10e902391dd" },
98 { "HardwareID-5", "7ccbb6f1-9641-5f84-b00d-51ff218a4066" },
99 { "HardwareID-4", "d78b474d-dee0-5412-bc9d-e9f7d7783df2" },
100 { "HardwareID-3", "a2f225b3-f4f0-5590-8973-08dd81602d69" },
101 { "HardwareID-2", "2e7c87e3-a52c-537f-a5f6-907110143cf7" },
102 { "HardwareID-1", "6453b900-1fd8-55fb-a936-7fca22823bcc" },
103 { "HardwareID-0", "d777e0a5-4db6-51b4-a927-86d4ccdc5c0d" },
291 { "Manufacturer", "6de5d951-d755-576b-bd09-c5cf66b27234" },
292 { "HardwareID-14", "6de5d951-d755-576b-bd09-c5cf66b27234" },
293 { "HardwareID-13", "f8e1de5f-b68c-5f52-9d1a-f1ba52f1f773" },
294 { "HardwareID-12", "5e820764-888e-529d-a6f9-dfd12bacb160" },
295 { "HardwareID-11", "db73af4c-4612-50f7-b8a7-787cf4871847" },
296 { "HardwareID-10", "f4275c1f-6130-5191-845c-3426247eb6a1" },
297 { "HardwareID-9", "0cf8618d-9eff-537c-9f35-46861406eb9c" },
298 { "HardwareID-8", "059eb22d-6dc7-59af-abd3-94bbe017f67c" },
299 { "HardwareID-7", "da1da9b6-62f5-5f22-8aaa-14db7eeda2a4" },
300 { "HardwareID-6", "178cd22d-ad9f-562d-ae0a-34009822cdbe" },
301 { "HardwareID-5", "8dc9b7c5-f5d5-5850-9ab3-bd6f0549d814" },
302 { "HardwareID-4", "660ccba8-1b78-5a33-80e6-9fb8354ee873" },
303 { "HardwareID-3", "3faec92a-3ae3-5744-be88-495e90a7d541" },
304 { "HardwareID-2", "705f45c6-fbca-5245-b9dd-6d4fab25e262" },
305 { "HardwareID-1", "309d9985-e453-587e-8486-ff7c835a9ef2" },
306 { "HardwareID-0", "d37363b8-5ec4-5725-b618-b75368a1ad28" },
104307 { NULL, NULL }
105308 };
106309
107 sysfsdir = fu_test_get_filename (TESTDATADIR, "hwids");
108 g_assert (sysfsdir != NULL);
310 smbios = fu_smbios_new ();
311 ret = fu_smbios_setup (smbios, &error);
312 g_assert_no_error (error);
313 g_assert (ret);
109314
110315 hwids = fu_hwids_new ();
111 ret = fu_hwids_setup (hwids, sysfsdir, &error);
316 ret = fu_hwids_setup (hwids, smbios, &error);
112317 g_assert_no_error (error);
113318 g_assert (ret);
114319
115320 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_MANUFACTURER), ==,
116 "To be filled by O.E.M.");
321 "LENOVO");
117322 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_ENCLOSURE_KIND), ==,
118 "3");
323 "10");
119324 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_FAMILY), ==,
120 "To be filled by O.E.M.");
325 "ThinkPad T440s");
121326 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_PRODUCT_NAME), ==,
122 "To be filled by O.E.M.");
327 "20ARS19C0C");
123328 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_VENDOR), ==,
124 "American Megatrends Inc.");
125 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_VERSION), ==, "1201");
126 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE), ==, "4");
127 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_MINOR_RELEASE), ==, "6");
128 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_PRODUCT_SKU), ==, "SKU");
329 "LENOVO");
330 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_VERSION), ==,
331 "GJET75WW (2.25 )");
332 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE), ==, "2");
333 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_BIOS_MINOR_RELEASE), ==, "25");
334 g_assert_cmpstr (fu_hwids_get_value (hwids, FU_HWIDS_KEY_PRODUCT_SKU), ==,
335 "LENOVO_MT_20AR_BU_Think_FM_ThinkPad T440s");
129336 for (guint i = 0; guids[i].key != NULL; i++) {
130337 g_autofree gchar *guid = fu_hwids_get_guid (hwids, guids[i].key, &error);
131338 g_assert_no_error (error);
210417 {
211418 GError *error = NULL;
212419 FuDevice *device_tmp;
213 FwupdResult *res;
214420 gboolean ret;
215421 guint cnt = 0;
216422 g_autofree gchar *mapped_file_fn = NULL;
217423 g_autofree gchar *pending_cap = NULL;
218424 g_autofree gchar *pending_db = NULL;
219425 g_autoptr(FuDevice) device = NULL;
426 g_autoptr(FuDevice) device2 = NULL;
427 g_autoptr(FuDevice) device3 = NULL;
220428 g_autoptr(FuPending) pending = NULL;
221429 g_autoptr(FuPlugin) plugin = NULL;
222430 g_autoptr(GBytes) blob_cab = NULL;
223431 g_autoptr(GMappedFile) mapped_file = NULL;
224
225 /* the test plugin is only usable if this is set */
226 g_setenv ("FWUPD_TESTS", "true", TRUE);
227432
228433 /* create a fake device */
229434 plugin = fu_plugin_new ();
272477
273478 /* lets check the pending */
274479 pending = fu_pending_new ();
275 res = fu_pending_get_device (pending, fu_device_get_id (device), &error);
276 g_assert_no_error (error);
277 g_assert (res != NULL);
278 g_assert_cmpint (fu_device_get_update_state (res), ==, FWUPD_UPDATE_STATE_PENDING);
279 g_assert_cmpstr (fu_device_get_update_error (res), ==, NULL);
280 g_assert_cmpstr (fu_device_get_update_filename (res), !=, NULL);
480 device2 = fu_pending_get_device (pending, fu_device_get_id (device), &error);
481 g_assert_no_error (error);
482 g_assert (device2 != NULL);
483 g_assert_cmpint (fu_device_get_update_state (device2), ==, FWUPD_UPDATE_STATE_PENDING);
484 g_assert_cmpstr (fu_device_get_update_error (device2), ==, NULL);
485 g_assert_cmpstr (fu_device_get_filename_pending (device2), !=, NULL);
281486
282487 /* save this; we'll need to delete it later */
283 pending_cap = g_strdup (fu_device_get_update_filename (res));
284 g_object_unref (res);
488 pending_cap = g_strdup (fu_device_get_filename_pending (device2));
285489
286490 /* lets do this online */
287491 ret = fu_plugin_runner_update (plugin, device, blob_cab, NULL,
295499 g_assert_cmpstr (fu_device_get_version_bootloader (device), ==, "0.1.2");
296500
297501 /* lets check the pending */
298 res = fu_pending_get_device (pending, fu_device_get_id (device), &error);
299 g_assert_no_error (error);
300 g_assert (res != NULL);
301 g_assert_cmpint (fu_device_get_update_state (res), ==, FWUPD_UPDATE_STATE_SUCCESS);
302 g_assert_cmpstr (fu_device_get_update_error (res), ==, NULL);
303 g_object_unref (res);
502 device3 = fu_pending_get_device (pending, fu_device_get_id (device), &error);
503 g_assert_no_error (error);
504 g_assert (device3 != NULL);
505 g_assert_cmpint (fu_device_get_update_state (device3), ==, FWUPD_UPDATE_STATE_SUCCESS);
506 g_assert_cmpstr (fu_device_get_update_error (device3), ==, NULL);
304507
305508 /* get the status */
306509 device_tmp = fu_device_new ();
335538 {
336539 GError *error = NULL;
337540 gboolean ret;
338 FwupdDevice *dev;
339 FwupdRelease *rel;
340 FwupdResult *res;
541 FuDevice *device;
341542 g_autoptr(FuPending) pending = NULL;
342543 g_autofree gchar *dirname = NULL;
343544 g_autofree gchar *filename = NULL;
354555 g_unlink (filename);
355556
356557 /* add a device */
357 res = FWUPD_RESULT (fu_device_new ());
358 fu_device_set_id (res, "self-test");
359 fu_device_set_update_filename (res, "/var/lib/dave.cap"),
360 fu_device_set_name (FU_DEVICE (res), "ColorHug"),
361 fu_device_set_version (res, "3.0.1"),
362 fu_device_set_update_version (res, "3.0.2");
363 ret = fu_pending_add_device (pending, res, &error);
364 g_assert_no_error (error);
365 g_assert (ret);
366 g_object_unref (res);
558 device = fu_device_new ();
559 fu_device_set_id (device, "self-test");
560 fu_device_set_filename_pending (device, "/var/lib/dave.cap"),
561 fu_device_set_name (device, "ColorHug"),
562 fu_device_set_version (device, "3.0.1"),
563 fu_device_set_version_new (device, "3.0.2");
564 ret = fu_pending_add_device (pending, device, &error);
565 g_assert_no_error (error);
566 g_assert (ret);
567 g_object_unref (device);
367568
368569 /* ensure database was created */
369570 g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
370571
371572 /* add some extra data */
372 res = fwupd_result_new ();
373 fu_device_set_id (res, "self-test");
374 ret = fu_pending_set_state (pending, res, FWUPD_UPDATE_STATE_PENDING, &error);
375 g_assert_no_error (error);
376 g_assert (ret);
377 ret = fu_pending_set_error_msg (pending, res, "word", &error);
378 g_assert_no_error (error);
379 g_assert (ret);
380 g_object_unref (res);
573 device = fu_device_new ();
574 fu_device_set_id (device, "self-test");
575 ret = fu_pending_set_state (pending, device, FWUPD_UPDATE_STATE_PENDING, &error);
576 g_assert_no_error (error);
577 g_assert (ret);
578 ret = fu_pending_set_error_msg (pending, device, "word", &error);
579 g_assert_no_error (error);
580 g_assert (ret);
581 g_object_unref (device);
381582
382583 /* get device */
383 res = fu_pending_get_device (pending, "self-test", &error);
384 g_assert_no_error (error);
385 g_assert (res != NULL);
386 dev = fwupd_result_get_device (res);
387 g_assert_cmpstr (fwupd_device_get_id (dev), ==, "self-test");
388 g_assert_cmpstr (fwupd_device_get_name (dev), ==, "ColorHug");
389 g_assert_cmpstr (fwupd_device_get_version (dev), ==, "3.0.1");
390 g_assert_cmpint (fwupd_result_get_update_state (res), ==, FWUPD_UPDATE_STATE_PENDING);
391 g_assert_cmpstr (fwupd_result_get_update_error (res), ==, "word");
392 rel = fwupd_result_get_release (res);
393 g_assert (rel != NULL);
394 g_assert_cmpstr (fwupd_release_get_filename (rel), ==, "/var/lib/dave.cap");
395 g_assert_cmpstr (fwupd_release_get_version (rel), ==, "3.0.2");
396 g_object_unref (res);
584 device = fu_pending_get_device (pending, "self-test", &error);
585 g_assert_no_error (error);
586 g_assert (device != NULL);
587 g_assert_cmpstr (fu_device_get_id (device), ==, "self-test");
588 g_assert_cmpstr (fu_device_get_name (device), ==, "ColorHug");
589 g_assert_cmpstr (fu_device_get_version (device), ==, "3.0.1");
590 g_assert_cmpint (fu_device_get_update_state (device), ==, FWUPD_UPDATE_STATE_PENDING);
591 g_assert_cmpstr (fu_device_get_update_error (device), ==, "word");
592 g_assert_cmpstr (fu_device_get_filename_pending (device), ==, "/var/lib/dave.cap");
593 g_assert_cmpstr (fu_device_get_version_new (device), ==, "3.0.2");
594 g_object_unref (device);
397595
398596 /* get device that does not exist */
399 res = fu_pending_get_device (pending, "XXXXXXXXXXXXX", &error);
597 device = fu_pending_get_device (pending, "XXXXXXXXXXXXX", &error);
400598 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
401 g_assert (res == NULL);
599 g_assert (device == NULL);
402600 g_clear_error (&error);
403601
404602 /* remove device */
405 res = fwupd_result_new ();
406 fu_device_set_id (res, "self-test");
407 ret = fu_pending_remove_device (pending, res, &error);
408 g_assert_no_error (error);
409 g_assert (ret);
410 g_object_unref (res);
603 device = fu_device_new ();
604 fu_device_set_id (device, "self-test");
605 ret = fu_pending_remove_device (pending, device, &error);
606 g_assert_no_error (error);
607 g_assert (ret);
608 g_object_unref (device);
411609
412610 /* get device that does not exist */
413 res = fu_pending_get_device (pending, "self-test", &error);
611 device = fu_pending_get_device (pending, "self-test", &error);
414612 g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
415 g_assert (res == NULL);
613 g_assert (device == NULL);
416614 g_clear_error (&error);
417615 }
418616
601799 (*lines)++;
602800 }
603801
802 static gboolean
803 _open_cb (GObject *device, GError **error)
804 {
805 g_assert_cmpstr (g_object_get_data (device, "state"), ==, "closed");
806 g_object_set_data (device, "state", "opened");
807 return TRUE;
808 }
809
810 static gboolean
811 _close_cb (GObject *device, GError **error)
812 {
813 g_assert_cmpstr (g_object_get_data (device, "state"), ==, "opened");
814 g_object_set_data (device, "state", "closed-on-unref");
815 return TRUE;
816 }
817
818 static void
819 fu_device_locker_func (void)
820 {
821 g_autoptr(FuDeviceLocker) locker = NULL;
822 g_autoptr(GError) error = NULL;
823 g_autoptr(GObject) device = g_object_new (G_TYPE_OBJECT, NULL);
824
825 g_object_set_data (device, "state", "closed");
826 locker = fu_device_locker_new_full (device, _open_cb, _close_cb, &error);
827 g_assert_no_error (error);
828 g_assert_nonnull (locker);
829 g_clear_object (&locker);
830 g_assert_cmpstr (g_object_get_data (device, "state"), ==, "closed-on-unref");
831 }
832
833 static gboolean
834 _fail_open_cb (GObject *device, GError **error)
835 {
836 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "fail");
837 return FALSE;
838 }
839
840 static gboolean
841 _fail_close_cb (GObject *device, GError **error)
842 {
843 g_assert_not_reached ();
844 return TRUE;
845 }
846
847 static void
848 fu_device_locker_fail_func (void)
849 {
850 g_autoptr(FuDeviceLocker) locker = NULL;
851 g_autoptr(GError) error = NULL;
852 g_autoptr(GObject) device = g_object_new (G_TYPE_OBJECT, NULL);
853 locker = fu_device_locker_new_full (device, _fail_open_cb, _fail_close_cb, &error);
854 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
855 g_assert_null (locker);
856 }
857
604858 static void
605859 fu_common_spawn_func (void)
606860 {
620874 g_assert_cmpint (lines, ==, 6);
621875 }
622876
877 static void
878 fu_progressbar_func (void)
879 {
880 g_autoptr(FuProgressbar) progressbar = fu_progressbar_new ();
881
882 fu_progressbar_set_length_status (progressbar, 20);
883 fu_progressbar_set_length_percentage (progressbar, 50);
884
885 g_print ("\n");
886 for (guint i = 0; i < 100; i++) {
887 fu_progressbar_update (progressbar, FWUPD_STATUS_DECOMPRESSING, i);
888 g_usleep (10000);
889 }
890 fu_progressbar_update (progressbar, FWUPD_STATUS_IDLE, 0);
891 for (guint i = 0; i < 100; i++) {
892 guint pc = (i > 25 && i < 75) ? 0 : i;
893 fu_progressbar_update (progressbar, FWUPD_STATUS_LOADING, pc);
894 g_usleep (10000);
895 }
896 fu_progressbar_update (progressbar, FWUPD_STATUS_IDLE, 0);
897
898 for (guint i = 0; i < 5000; i++) {
899 fu_progressbar_update (progressbar, FWUPD_STATUS_LOADING, 0);
900 g_usleep (1000);
901 }
902 fu_progressbar_update (progressbar, FWUPD_STATUS_IDLE, 0);
903 }
904
623905 int
624906 main (int argc, char **argv)
625907 {
632914 g_assert_cmpint (g_mkdir_with_parents ("/tmp/fwupd-self-test/var/lib/fwupd", 0755), ==, 0);
633915
634916 /* tests go here */
917 if (g_test_slow ())
918 g_test_add_func ("/fwupd/progressbar", fu_progressbar_func);
919 g_test_add_func ("/fwupd/device-locker{success}", fu_device_locker_func);
920 g_test_add_func ("/fwupd/device-locker{fail}", fu_device_locker_fail_func);
635921 g_test_add_func ("/fwupd/device{metadata}", fu_device_metadata_func);
922 g_test_add_func ("/fwupd/engine", fu_engine_func);
636923 g_test_add_func ("/fwupd/hwids", fu_hwids_func);
924 g_test_add_func ("/fwupd/smbios", fu_smbios_func);
925 g_test_add_func ("/fwupd/smbios3", fu_smbios3_func);
637926 g_test_add_func ("/fwupd/pending", fu_pending_func);
638927 g_test_add_func ("/fwupd/plugin{delay}", fu_plugin_delay_func);
639928 g_test_add_func ("/fwupd/plugin{module}", fu_plugin_module_func);
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include <gio/gio.h>
24 #include <string.h>
25
26 #include "fu-smbios.h"
27 #include "fwupd-error.h"
28
29 struct _FuSmbios {
30 GObject parent_instance;
31 gchar *smbios_ver;
32 guint32 structure_table_len;
33 GPtrArray *items;
34 };
35
36 /* little endian */
37 typedef struct __attribute__((packed)) {
38 gchar anchor_str[4];
39 guint8 entry_point_csum;
40 guint8 entry_point_len;
41 guint8 smbios_major_ver;
42 guint8 smbios_minor_ver;
43 guint16 max_structure_sz;
44 guint8 entry_point_rev;
45 guint8 formatted_area[5];
46 gchar intermediate_anchor_str[5];
47 guint8 intermediate_csum;
48 guint16 structure_table_len;
49 guint32 structure_table_addr;
50 guint16 number_smbios_structs;
51 guint8 smbios_bcd_rev;
52 } FuSmbiosStructureEntryPoint32;
53
54 /* little endian */
55 typedef struct __attribute__((packed)) {
56 gchar anchor_str[5];
57 guint8 entry_point_csum;
58 guint8 entry_point_len;
59 guint8 smbios_major_ver;
60 guint8 smbios_minor_ver;
61 guint8 smbios_docrev;
62 guint8 entry_point_rev;
63 guint8 reserved0;
64 guint32 structure_table_len;
65 guint64 structure_table_addr;
66 } FuSmbiosStructureEntryPoint64;
67
68 /* little endian */
69 typedef struct __attribute__((packed)) {
70 guint8 type;
71 guint8 len;
72 guint16 handle;
73 } FuSmbiosStructure;
74
75 typedef struct {
76 guint8 type;
77 guint16 handle;
78 GBytes *data;
79 GPtrArray *strings;
80 } FuSmbiosItem;
81
82 G_DEFINE_TYPE (FuSmbios, fu_smbios, G_TYPE_OBJECT)
83
84 static gboolean
85 fu_smbios_setup_from_data (FuSmbios *self, const guint8 *buf, gsize sz, GError **error)
86 {
87 /* go through each structure */
88 for (gsize i = 0; i < sz; i++) {
89 FuSmbiosStructure *str = (FuSmbiosStructure *) &buf[i];
90 FuSmbiosItem *item;
91
92 /* invalid */
93 if (str->len == 0x00)
94 break;
95 if (str->len >= sz) {
96 g_set_error_literal (error,
97 FWUPD_ERROR,
98 FWUPD_ERROR_INVALID_FILE,
99 "structure larger than available data");
100 return FALSE;
101 }
102
103 /* create a new result */
104 item = g_new0 (FuSmbiosItem, 1);
105 item->type = str->type;
106 item->handle = GUINT16_FROM_LE (str->handle);
107 item->data = g_bytes_new (buf + i, str->len);
108 item->strings = g_ptr_array_new_with_free_func (g_free);
109 g_ptr_array_add (self->items, item);
110
111 /* jump to the end of the struct */
112 i += str->len;
113 if (buf[i] == '\0' && buf[i+1] == '\0') {
114 i++;
115 continue;
116 }
117
118 /* add strings from table */
119 for (gsize start_offset = i; i < sz; i++) {
120 if (buf[i] == '\0') {
121 if (start_offset == i)
122 break;
123 g_ptr_array_add (item->strings,
124 g_strdup ((const gchar *) &buf[start_offset]));
125 start_offset = i + 1;
126 }
127 }
128 }
129 return TRUE;
130 }
131
132 /**
133 * fu_smbios_setup_from_file:
134 * @self: A #FuSmbios
135 * @filename: A filename
136 * @error: A #GError or %NULL
137 *
138 * Reads all the SMBIOS values from a DMI blob.
139 *
140 * Returns: %TRUE for success
141 **/
142 gboolean
143 fu_smbios_setup_from_file (FuSmbios *self, const gchar *filename, GError **error)
144 {
145 gsize sz = 0;
146 g_autofree gchar *buf = NULL;
147 if (!g_file_get_contents (filename, &buf, &sz, error))
148 return FALSE;
149 return fu_smbios_setup_from_data (self, (guint8 *) buf, sz, error);
150 }
151
152 static gboolean
153 fu_smbios_parse_ep32 (FuSmbios *self, const gchar *buf, gsize sz, GError **error)
154 {
155 FuSmbiosStructureEntryPoint32 *ep;
156 guint8 csum = 0;
157
158 /* verify size */
159 if (sz != sizeof(FuSmbiosStructureEntryPoint32)) {
160 g_set_error (error,
161 FWUPD_ERROR,
162 FWUPD_ERROR_INVALID_FILE,
163 "invalid smbios entry point got %" G_GSIZE_FORMAT
164 " bytes, expected %" G_GSIZE_FORMAT,
165 sz, sizeof(FuSmbiosStructureEntryPoint32));
166 return FALSE;
167 }
168
169 /* verify checksum */
170 for (guint i = 0; i < sz; i++)
171 csum += buf[i];
172 if (csum != 0x00) {
173 g_set_error_literal (error,
174 FWUPD_ERROR,
175 FWUPD_ERROR_INVALID_FILE,
176 "entry point checksum invalid");
177 return FALSE;
178 }
179
180 /* verify intermediate section */
181 ep = (FuSmbiosStructureEntryPoint32 *) buf;
182 if (memcmp (ep->intermediate_anchor_str, "_DMI_", 5) != 0) {
183 g_autofree gchar *tmp = g_strndup (ep->intermediate_anchor_str, 5);
184 g_set_error (error,
185 FWUPD_ERROR,
186 FWUPD_ERROR_INVALID_FILE,
187 "intermediate anchor signature invalid, got %s", tmp);
188 return FALSE;
189 }
190 for (guint i = 10; i < sz; i++)
191 csum += buf[i];
192 if (csum != 0x00) {
193 g_set_error_literal (error,
194 FWUPD_ERROR,
195 FWUPD_ERROR_INVALID_FILE,
196 "intermediate checksum invalid");
197 return FALSE;
198 }
199 self->structure_table_len = GUINT16_FROM_LE (ep->structure_table_len);
200 self->smbios_ver = g_strdup_printf ("%u.%u",
201 ep->smbios_major_ver,
202 ep->smbios_minor_ver);
203 return TRUE;
204 }
205
206 static gboolean
207 fu_smbios_parse_ep64 (FuSmbios *self, const gchar *buf, gsize sz, GError **error)
208 {
209 FuSmbiosStructureEntryPoint64 *ep;
210 guint8 csum = 0;
211
212 /* verify size */
213 if (sz != sizeof(FuSmbiosStructureEntryPoint64)) {
214 g_set_error (error,
215 FWUPD_ERROR,
216 FWUPD_ERROR_INVALID_FILE,
217 "invalid smbios3 entry point got %" G_GSIZE_FORMAT
218 " bytes, expected %" G_GSIZE_FORMAT,
219 sz, sizeof(FuSmbiosStructureEntryPoint32));
220 return FALSE;
221 }
222
223 /* verify checksum */
224 for (guint i = 0; i < sz; i++)
225 csum += buf[i];
226 if (csum != 0x00) {
227 g_set_error_literal (error,
228 FWUPD_ERROR,
229 FWUPD_ERROR_INVALID_FILE,
230 "entry point checksum invalid");
231 return FALSE;
232 }
233 ep = (FuSmbiosStructureEntryPoint64 *) buf;
234 self->structure_table_len = GUINT32_FROM_LE (ep->structure_table_len);
235 self->smbios_ver = g_strdup_printf ("%u.%u",
236 ep->smbios_major_ver,
237 ep->smbios_minor_ver);
238 return TRUE;
239 }
240
241 /**
242 * fu_smbios_setup:
243 * @self: A #FuSmbios
244 * @path: A path, e.g. `/sys/firmware/dmi/tables`
245 * @error: A #GError or %NULL
246 *
247 * Reads all the SMBIOS values from a specific path.
248 *
249 * Returns: %TRUE for success
250 **/
251 gboolean
252 fu_smbios_setup_from_path (FuSmbios *self, const gchar *path, GError **error)
253 {
254 gsize sz = 0;
255 g_autofree gchar *dmi_fn = NULL;
256 g_autofree gchar *dmi_raw = NULL;
257 g_autofree gchar *ep_fn = NULL;
258 g_autofree gchar *ep_raw = NULL;
259
260 g_return_val_if_fail (FU_IS_SMBIOS (self), FALSE);
261
262 /* get the smbios entry point */
263 ep_fn = g_build_filename (path, "smbios_entry_point", NULL);
264 if (!g_file_get_contents (ep_fn, &ep_raw, &sz, error))
265 return FALSE;
266
267 /* check we got enough data to read the signature */
268 if (sz < 5) {
269 g_set_error (error,
270 FWUPD_ERROR,
271 FWUPD_ERROR_INVALID_FILE,
272 "invalid smbios entry point got %" G_GSIZE_FORMAT
273 " bytes, expected %" G_GSIZE_FORMAT
274 " or %" G_GSIZE_FORMAT, sz,
275 sizeof(FuSmbiosStructureEntryPoint32),
276 sizeof(FuSmbiosStructureEntryPoint64));
277 return FALSE;
278 }
279
280 /* parse 32 bit structure */
281 if (memcmp (ep_raw, "_SM_", 4) == 0) {
282 if (!fu_smbios_parse_ep32 (self, ep_raw, sz, error))
283 return FALSE;
284 } else if (memcmp (ep_raw, "_SM3_", 5) == 0) {
285 if (!fu_smbios_parse_ep64 (self, ep_raw, sz, error))
286 return FALSE;
287 } else {
288 g_autofree gchar *tmp = g_strndup (ep_raw, 4);
289 g_set_error (error,
290 FWUPD_ERROR,
291 FWUPD_ERROR_INVALID_FILE,
292 "SMBIOS signature invalid, got %s", tmp);
293 return FALSE;
294 }
295
296 /* get the DMI data */
297 dmi_fn = g_build_filename (path, "DMI", NULL);
298 if (!g_file_get_contents (dmi_fn, &dmi_raw, &sz, error))
299 return FALSE;
300 if (sz != self->structure_table_len) {
301 g_set_error (error,
302 FWUPD_ERROR,
303 FWUPD_ERROR_INVALID_FILE,
304 "invalid DMI data size, got %" G_GSIZE_FORMAT
305 " bytes, expected %" G_GUINT32_FORMAT,
306 sz, self->structure_table_len);
307 return FALSE;
308 }
309
310 /* parse blob */
311 return fu_smbios_setup_from_data (self, (guint8 *) dmi_raw, sz, error);
312 }
313
314 /**
315 * fu_smbios_setup:
316 * @self: A #FuSmbios
317 * @error: A #GError or %NULL
318 *
319 * Reads all the SMBIOS values from the hardware.
320 *
321 * Returns: %TRUE for success
322 **/
323 gboolean
324 fu_smbios_setup (FuSmbios *self, GError **error)
325 {
326 g_autofree gchar *path = NULL;
327 g_return_val_if_fail (FU_IS_SMBIOS (self), FALSE);
328 path = g_build_filename (SYSFSFIRMWAREDIR, "dmi", "tables", NULL);
329 return fu_smbios_setup_from_path (self, path, error);
330 }
331
332 /**
333 * fu_smbios_to_string:
334 * @self: A #FuSmbios
335 *
336 * Dumps the parsed SMBIOS data to a string.
337 *
338 * Returns: a UTF-8 string
339 **/
340 gchar *
341 fu_smbios_to_string (FuSmbios *self)
342 {
343 GString *str;
344
345 g_return_val_if_fail (FU_IS_SMBIOS (self), NULL);
346
347 str = g_string_new (NULL);
348 g_string_append_printf (str, "SmbiosVersion: %s\n", self->smbios_ver);
349 for (guint i = 0; i < self->items->len; i++) {
350 FuSmbiosItem *item = g_ptr_array_index (self->items, i);
351 g_string_append_printf (str, "Type: %02x\n", item->type);
352 g_string_append_printf (str, " Length: %" G_GSIZE_FORMAT "\n",
353 g_bytes_get_size (item->data));
354 g_string_append_printf (str, " Handle: 0x%04x\n", item->handle);
355 for (guint j = 0; j < item->strings->len; j++) {
356 const gchar *tmp = g_ptr_array_index (item->strings, j);
357 g_string_append_printf (str, " String[%02u]: %s\n", j, tmp);
358 }
359 }
360 return g_string_free (str, FALSE);
361 }
362
363 static FuSmbiosItem *
364 fu_smbios_get_item_for_type (FuSmbios *self, guint8 type)
365 {
366 for (guint i = 0; i < self->items->len; i++) {
367 FuSmbiosItem *item = g_ptr_array_index (self->items, i);
368 if (item->type == type)
369 return item;
370 }
371 return NULL;
372 }
373
374 /**
375 * fu_smbios_get_data:
376 * @self: A #FuSmbios
377 * @type: A structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
378 * @error: A #GError or %NULL
379 *
380 * Reads a SMBIOS data blob, which includes the SMBIOS section header.
381 *
382 * Returns: a #GBytes, or %NULL if invalid or not found
383 **/
384 GBytes *
385 fu_smbios_get_data (FuSmbios *self, guint8 type, GError **error)
386 {
387 FuSmbiosItem *item;
388 g_return_val_if_fail (FU_IS_SMBIOS (self), NULL);
389 item = fu_smbios_get_item_for_type (self, type);
390 if (item == NULL) {
391 g_set_error (error,
392 FWUPD_ERROR,
393 FWUPD_ERROR_INVALID_FILE,
394 "no structure with type %02x", type);
395 return NULL;
396 }
397 return item->data;
398 }
399
400 /**
401 * fu_smbios_get_string:
402 * @self: A #FuSmbios
403 * @type: A structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS
404 * @offset: A structure offset
405 * @error: A #GError or %NULL
406 *
407 * Reads a string from the SMBIOS string table of a specific structure.
408 *
409 * The @type and @offset can be referenced from the DMTF SMBIOS specification:
410 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf
411 *
412 * Returns: a string, or %NULL if invalid or not found
413 **/
414 const gchar *
415 fu_smbios_get_string (FuSmbios *self, guint8 type, guint8 offset, GError **error)
416 {
417 FuSmbiosItem *item;
418 const guint8 *data;
419 gsize sz;
420
421 g_return_val_if_fail (FU_IS_SMBIOS (self), NULL);
422
423 /* get item */
424 item = fu_smbios_get_item_for_type (self, type);
425 if (item == NULL) {
426 g_set_error (error,
427 FWUPD_ERROR,
428 FWUPD_ERROR_INVALID_FILE,
429 "no structure with type %02x", type);
430 return NULL;
431 }
432
433 /* check offset valid */
434 data = g_bytes_get_data (item->data, &sz);
435 if (offset >= sz) {
436 g_set_error (error,
437 FWUPD_ERROR,
438 FWUPD_ERROR_INVALID_FILE,
439 "offset bigger than size %" G_GSIZE_FORMAT, sz);
440 return NULL;
441 }
442 if (data[offset] == 0x00) {
443 g_set_error (error,
444 FWUPD_ERROR,
445 FWUPD_ERROR_NOT_FOUND,
446 "no data available");
447 return NULL;
448 }
449
450 /* check string index valid */
451 if (data[offset] > item->strings->len) {
452 g_set_error (error,
453 FWUPD_ERROR,
454 FWUPD_ERROR_INVALID_FILE,
455 "index larger than string table %u",
456 data[offset]);
457 return NULL;
458 }
459 return g_ptr_array_index (item->strings, data[offset] - 1);
460 }
461
462 static void
463 fu_smbios_item_free (FuSmbiosItem *item)
464 {
465 g_bytes_unref (item->data);
466 g_ptr_array_unref (item->strings);
467 g_free (item);
468 }
469
470 static void
471 fu_smbios_finalize (GObject *object)
472 {
473 FuSmbios *self = FU_SMBIOS (object);
474 g_free (self->smbios_ver);
475 g_ptr_array_unref (self->items);
476 G_OBJECT_CLASS (fu_smbios_parent_class)->finalize (object);
477 }
478
479 static void
480 fu_smbios_class_init (FuSmbiosClass *klass)
481 {
482 GObjectClass *object_class = G_OBJECT_CLASS (klass);
483 object_class->finalize = fu_smbios_finalize;
484 }
485
486 static void
487 fu_smbios_init (FuSmbios *self)
488 {
489 self->items = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_smbios_item_free);
490 }
491
492 /**
493 * fu_smbios_new:
494 *
495 * Creates a new object to parse SMBIOS data.
496 *
497 * Returns: a #FuSmbios
498 **/
499 FuSmbios *
500 fu_smbios_new (void)
501 {
502 FuSmbios *self;
503 self = g_object_new (FU_TYPE_SMBIOS, NULL);
504 return FU_SMBIOS (self);
505 }
0 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
1 *
2 * Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
3 *
4 * Licensed under the GNU Lesser General Public License Version 2.1
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef __FU_SMBIOS_H
22 #define __FU_SMBIOS_H
23
24 #include <glib-object.h>
25
26 G_BEGIN_DECLS
27
28 #define FU_TYPE_SMBIOS (fu_smbios_get_type ())
29
30 G_DECLARE_FINAL_TYPE (FuSmbios, fu_smbios, FU, SMBIOS, GObject)
31
32 FuSmbios *fu_smbios_new (void);
33
34 #define FU_SMBIOS_STRUCTURE_TYPE_BIOS 0x00
35 #define FU_SMBIOS_STRUCTURE_TYPE_SYSTEM 0x01
36 #define FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD 0x02
37 #define FU_SMBIOS_STRUCTURE_TYPE_CHASSIS 0x03
38
39 gboolean fu_smbios_setup (FuSmbios *self,
40 GError **error);
41 gboolean fu_smbios_setup_from_path (FuSmbios *self,
42 const gchar *path,
43 GError **error);
44 gboolean fu_smbios_setup_from_file (FuSmbios *self,
45 const gchar *filename,
46 GError **error);
47 gchar *fu_smbios_to_string (FuSmbios *self);
48
49 const gchar *fu_smbios_get_string (FuSmbios *self,
50 guint8 type,
51 guint8 offset,
52 GError **error);
53 GBytes *fu_smbios_get_data (FuSmbios *self,
54 guint8 type,
55 GError **error);
56
57 G_END_DECLS
58
59 #endif /* __FU_SMBIOS_H */
244244 g_autoptr(GPtrArray) devices_filtered = NULL;
245245
246246 /* get devices from daemon */
247 devices = fwupd_client_get_devices_simple (priv->client, NULL, error);
247 devices = fwupd_client_get_devices (priv->client, NULL, error);
248248 if (devices == NULL)
249249 return NULL;
250250
292292 g_autoptr(GPtrArray) devs = NULL;
293293
294294 /* get results from daemon */
295 devs = fwupd_client_get_devices_simple (priv->client, NULL, error);
295 devs = fwupd_client_get_devices (priv->client, NULL, error);
296296 if (devs == NULL)
297297 return FALSE;
298298
311311 }
312312
313313 return TRUE;
314 }
315
316 static gboolean
317 fu_util_install_with_fallback (FuUtilPrivate *priv, const gchar *id,
318 const gchar *filename, GError **error)
319 {
320 g_autoptr(GError) error_local = NULL;
321
322 /* install with flags chosen by the user */
323 if (fwupd_client_install (priv->client, id, filename, priv->flags,
324 NULL, &error_local))
325 return TRUE;
326
327 /* some other failure */
328 if ((priv->flags & FWUPD_INSTALL_FLAG_OFFLINE) > 0 ||
329 !g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) {
330 g_propagate_error (error, error_local);
331 error_local = NULL;
332 return FALSE;
333 }
334
335 /* TRANSLATOR: the plugin only supports offline */
336 g_print ("%s...\n", _("Retrying as an offline update"));
337 priv->flags |= FWUPD_INSTALL_FLAG_OFFLINE;
338 return fwupd_client_install (priv->client, id, filename, priv->flags,
339 NULL, error);
340314 }
341315
342316 static gboolean
357331 return FALSE;
358332 }
359333
360 /* install with flags chosen by the user then falling back to offline */
361 return fu_util_install_with_fallback (priv, id, values[0], error);
334 /* install with flags chosen by the user */
335 return fwupd_client_install (priv->client, id, values[0], priv->flags, NULL, error);
362336 }
363337
364338 static gboolean
374348 "Invalid arguments: expected 'filename'");
375349 return FALSE;
376350 }
377 array = fwupd_client_get_details_local (priv->client, values[0], NULL, error);
351 array = fwupd_client_get_details (priv->client, values[0], NULL, error);
378352 if (array == NULL)
379353 return FALSE;
380354 for (guint i = 0; i < array->len; i++) {
381 FwupdResult *res = g_ptr_array_index (array, i);
355 FwupdDevice *dev = g_ptr_array_index (array, i);
382356 g_autofree gchar *tmp = NULL;
383 tmp = fwupd_result_to_string (res);
357 tmp = fwupd_device_to_string (dev);
384358 g_print ("%s", tmp);
385359 }
386360 return TRUE;
482456
483457 /* apply each update */
484458 for (guint i = 0; i < results->len; i++) {
485 FwupdResult *res = g_ptr_array_index (results, i);
486 FwupdDevice *dev = fwupd_result_get_device (res);
487 FwupdRelease *rel = fwupd_result_get_release (res);
459 FwupdDevice *dev = g_ptr_array_index (results, i);
460 FwupdRelease *rel = fwupd_device_get_release_default (dev);
488461
489462 /* check not already done */
490 if (fwupd_result_get_update_state (res) != FWUPD_UPDATE_STATE_PENDING)
463 if (fwupd_device_get_update_state (dev) != FWUPD_UPDATE_STATE_PENDING)
491464 continue;
492465
493466 /* tell the user what's going to happen */
557530 }
558531
559532 static gboolean
533 fu_util_clear_offline (FuUtilPrivate *priv, gchar **values, GError **error)
534 {
535 g_autoptr(FuPending) pending = fu_pending_new ();
536 return fu_pending_remove_all (pending, error);
537 }
538
539 static gboolean
560540 fu_util_verify_update_all (FuUtilPrivate *priv, GError **error)
561541 {
562542 g_autoptr(GPtrArray) devs = NULL;
563543
564544 /* get devices from daemon */
565 devs = fwupd_client_get_devices_simple (priv->client, NULL, error);
545 devs = fwupd_client_get_devices (priv->client, NULL, error);
566546 if (devs == NULL)
567547 return FALSE;
568548
774754 FwupdRemote *remote,
775755 GError **error)
776756 {
757 g_autofree gchar *basename_asc = NULL;
758 g_autofree gchar *basename_id_asc = NULL;
759 g_autofree gchar *basename_id = NULL;
760 g_autofree gchar *basename = NULL;
777761 g_autofree gchar *cache_dir = NULL;
778762 g_autofree gchar *filename = NULL;
779763 g_autofree gchar *filename_asc = NULL;
780764 g_autoptr(SoupURI) uri = NULL;
781765 g_autoptr(SoupURI) uri_sig = NULL;
782766
767 /* generate some plausible local filenames */
768 basename = g_path_get_basename (fwupd_remote_get_filename_cache (remote));
769 basename_id = g_strdup_printf ("%s-%s", fwupd_remote_get_id (remote), basename);
770
783771 /* download the metadata */
784772 cache_dir = g_build_filename (g_get_user_cache_dir (), "fwupdmgr", NULL);
785 filename = g_build_filename (cache_dir, fwupd_remote_get_filename (remote), NULL);
773 filename = g_build_filename (cache_dir, basename_id, NULL);
786774 if (!fu_common_mkdir_parent (filename, error))
787775 return FALSE;
788776 uri = soup_uri_new (fwupd_remote_get_metadata_uri (remote));
790778 return FALSE;
791779
792780 /* download the signature */
793 filename_asc = g_build_filename (cache_dir, fwupd_remote_get_filename_asc (remote), NULL);
781 basename_asc = g_path_get_basename (fwupd_remote_get_filename_cache_sig (remote));
782 basename_id_asc = g_strdup_printf ("%s-%s", fwupd_remote_get_id (remote), basename_asc);
783 filename_asc = g_build_filename (cache_dir, basename_id_asc, NULL);
794784 uri_sig = soup_uri_new (fwupd_remote_get_metadata_uri_sig (remote));
795785 if (!fu_util_download_file (priv, uri_sig, filename_asc, NULL, error))
796786 return FALSE;
797787
798788 /* send all this to fwupd */
799 return fwupd_client_update_metadata_with_id (priv->client,
789 return fwupd_client_update_metadata (priv->client,
800790 fwupd_remote_get_id (remote),
801791 filename,
802792 filename_asc,
836826 }
837827
838828 /* open file */
839 return fwupd_client_update_metadata_with_id (priv->client,
840 values[2],
841 values[0],
842 values[1],
843 NULL,
844 error);
829 return fwupd_client_update_metadata (priv->client,
830 values[2],
831 values[0],
832 values[1],
833 NULL,
834 error);
845835 }
846836
847837 static gboolean
848838 fu_util_get_results (FuUtilPrivate *priv, gchar **values, GError **error)
849839 {
850840 g_autofree gchar *tmp = NULL;
851 g_autoptr(FwupdResult) res = NULL;
841 g_autoptr(FwupdDevice) dev = NULL;
852842
853843 if (g_strv_length (values) != 1) {
854844 g_set_error_literal (error,
857847 "Invalid arguments: expected 'DeviceID'");
858848 return FALSE;
859849 }
860 res = fwupd_client_get_results (priv->client, values[0], NULL, error);
861 if (res == NULL)
862 return FALSE;
863 tmp = fwupd_result_to_string (res);
850 dev = fwupd_client_get_results (priv->client, values[0], NULL, error);
851 if (dev == NULL)
852 return FALSE;
853 tmp = fwupd_device_to_string (dev);
864854 g_print ("%s", tmp);
865855 return TRUE;
866856 }
896886 /* TRANSLATORS: section header for release version number */
897887 fu_util_print_data (_("Version"), fwupd_release_get_version (rel));
898888
889 /* TRANSLATORS: section header for the remote the file is coming from */
890 fu_util_print_data (_("Remote"), fwupd_release_get_remote_id (rel));
891
899892 /* TRANSLATORS: section header for firmware URI */
900893 fu_util_print_data (_("URI"), fwupd_release_get_uri (rel));
901894 tmp = fwupd_release_get_description (rel);
962955 g_autoptr(GPtrArray) devs = NULL;
963956
964957 /* get devices from daemon */
965 devs = fwupd_client_get_devices_simple (priv->client, NULL, error);
958 devs = fwupd_client_get_devices (priv->client, NULL, error);
966959 if (devs == NULL)
967960 return FALSE;
968961
10171010 static gboolean
10181011 fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error)
10191012 {
1020 GPtrArray *guids;
1021 const gchar *tmp;
1022 g_autoptr(GPtrArray) results = NULL;
1023
1024 /* print any updates */
1025 results = fwupd_client_get_updates (priv->client, NULL, error);
1026 if (results == NULL)
1027 return FALSE;
1028 for (guint i = 0; i < results->len; i++) {
1029 FwupdResult *res = g_ptr_array_index (results, i);
1030 FwupdDevice *dev = fwupd_result_get_device (res);
1031 FwupdRelease *rel = fwupd_result_get_release (res);
1032 GPtrArray *checksums;
1013 g_autoptr(GPtrArray) devices = NULL;
1014
1015 /* get devices from daemon */
1016 devices = fwupd_client_get_devices (priv->client, NULL, error);
1017 if (devices == NULL)
1018 return FALSE;
1019 for (guint i = 0; i < devices->len; i++) {
1020 FwupdDevice *dev = g_ptr_array_index (devices, i);
1021 GPtrArray *guids;
1022 const gchar *tmp;
1023 g_autoptr(GPtrArray) rels = NULL;
1024 g_autoptr(GError) error_local = NULL;
1025
1026 /* not going to have results, so save a D-Bus round-trip */
1027 if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED))
1028 continue;
1029
1030 /* get the releases for this device and filter for validity */
1031 rels = fwupd_client_get_upgrades (priv->client,
1032 fwupd_device_get_id (dev),
1033 NULL, &error_local);
1034 if (rels == NULL) {
1035 g_printerr ("%s\n", error_local->message);
1036 continue;
1037 }
10331038
10341039 /* TRANSLATORS: first replacement is device name */
10351040 g_print (_("%s has firmware updates:"), fwupd_device_get_name (dev));
10361041 g_print ("\n");
1037
1038 /* TRANSLATORS: Appstream ID for the hardware type */
1039 fu_util_print_data (_("ID"), fwupd_release_get_appstream_id (rel));
10401042
10411043 /* TRANSLATORS: a GUID for the hardware */
10421044 guids = fwupd_device_get_guids (dev);
10451047 fu_util_print_data (_("GUID"), tmp);
10461048 }
10471049
1048 /* TRANSLATORS: section header for firmware version */
1049 fu_util_print_data (_("Update Version"),
1050 fwupd_release_get_version (rel));
1051
1052 /* TRANSLATORS: section header for remote ID, e.g. lvfs-testing */
1053 fu_util_print_data (_("Update Remote ID"),
1054 fwupd_release_get_remote_id (rel));
1055
1056 checksums = fwupd_release_get_checksums (rel);
1057 for (guint j = 0; j < checksums->len; j++) {
1058 const gchar *checksum = g_ptr_array_index (checksums, j);
1059 g_autofree gchar *checksum_display = NULL;
1060 checksum_display = fwupd_checksum_format_for_display (checksum);
1061 /* TRANSLATORS: section header for firmware checksum */
1062 fu_util_print_data (_("Update Checksum"), checksum_display);
1063 }
1064
1065 /* TRANSLATORS: section header for firmware remote http:// */
1066 fu_util_print_data (_("Update Location"), fwupd_release_get_uri (rel));
1067
1068 /* convert XML -> text */
1069 tmp = fwupd_release_get_description (rel);
1070 if (tmp != NULL) {
1071 g_autofree gchar *md = NULL;
1072 md = as_markup_convert (tmp,
1073 AS_MARKUP_CONVERT_FORMAT_SIMPLE,
1074 NULL);
1075 if (md != NULL) {
1076 /* TRANSLATORS: section header for long firmware desc */
1077 fu_util_print_data (_("Update Description"), md);
1050 /* print all releases */
1051 for (guint j = 0; j < rels->len; j++) {
1052 FwupdRelease *rel = g_ptr_array_index (rels, j);
1053 GPtrArray *checksums;
1054
1055 /* TRANSLATORS: Appstream ID for the hardware type */
1056 fu_util_print_data (_("ID"), fwupd_release_get_appstream_id (rel));
1057
1058 /* TRANSLATORS: section header for firmware version */
1059 fu_util_print_data (_("Update Version"),
1060 fwupd_release_get_version (rel));
1061
1062 /* TRANSLATORS: section header for remote ID, e.g. lvfs-testing */
1063 fu_util_print_data (_("Update Remote ID"),
1064 fwupd_release_get_remote_id (rel));
1065
1066 checksums = fwupd_release_get_checksums (rel);
1067 for (guint k = 0; k < checksums->len; k++) {
1068 const gchar *checksum = g_ptr_array_index (checksums, k);
1069 g_autofree gchar *checksum_display = NULL;
1070 checksum_display = fwupd_checksum_format_for_display (checksum);
1071 /* TRANSLATORS: section header for firmware checksum */
1072 fu_util_print_data (_("Update Checksum"), checksum_display);
10781073 }
1079 }
1080 }
1081
1074
1075 /* TRANSLATORS: section header for firmware remote http:// */
1076 fu_util_print_data (_("Update Location"), fwupd_release_get_uri (rel));
1077
1078 /* convert XML -> text */
1079 tmp = fwupd_release_get_description (rel);
1080 if (tmp != NULL) {
1081 g_autofree gchar *md = NULL;
1082 md = as_markup_convert (tmp,
1083 AS_MARKUP_CONVERT_FORMAT_SIMPLE,
1084 NULL);
1085 if (md != NULL) {
1086 /* TRANSLATORS: section header for long firmware desc */
1087 fu_util_print_data (_("Update Description"), md);
1088 }
1089 }
1090 }
1091 }
10821092 return TRUE;
10831093 }
10841094
11031113 fu_util_print_data (_("Remote ID"),
11041114 fwupd_remote_get_id (remote));
11051115
1116 /* TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" */
1117 fu_util_print_data (_("Title"),
1118 fwupd_remote_get_title (remote));
1119
11061120 /* TRANSLATORS: remote type, e.g. remote or local */
11071121 fu_util_print_data (_("Type"),
11081122 fwupd_remote_kind_to_string (kind));
11161130 /* TRANSLATORS: if the remote is enabled */
11171131 fu_util_print_data (_("Enabled"),
11181132 fwupd_remote_get_enabled (remote) ? "True" : "False");
1133
1134 /* TRANSLATORS: remote checksum */
1135 fu_util_print_data (_("Checksum"),
1136 fwupd_remote_get_checksum (remote));
11191137
11201138 /* optional parameters */
11211139 age = fwupd_remote_get_age (remote);
11601178 /* TRANSLATORS: remote filename base */
11611179 fu_util_print_data (_("Password"), tmp);
11621180 }
1163 tmp = fwupd_remote_get_filename (remote);
1164 if (tmp != NULL) {
1165 /* TRANSLATORS: remote filename base */
1166 fu_util_print_data (_("Filename"), tmp);
1167 }
1168 tmp = fwupd_remote_get_filename_asc (remote);
1169 if (tmp != NULL) {
1170 /* TRANSLATORS: remote filename base */
1171 fu_util_print_data (_("Filename Signature"), tmp);
1172 }
11731181 tmp = fwupd_remote_get_filename_cache (remote);
11741182 if (tmp != NULL) {
1175 /* TRANSLATORS: locatation of the local file */
1176 fu_util_print_data (_("Location"), tmp);
1183 /* TRANSLATORS: filename of the local file */
1184 fu_util_print_data (_("Filename"), tmp);
11771185 }
11781186 tmp = fwupd_remote_get_filename_cache_sig (remote);
11791187 if (tmp != NULL) {
1180 /* TRANSLATORS: locatation of the local file */
1181 fu_util_print_data (_("Location Signature"), tmp);
1188 /* TRANSLATORS: filename of the local file */
1189 fu_util_print_data (_("Filename Signature"), tmp);
11821190 }
11831191 tmp = fwupd_remote_get_metadata_uri (remote);
11841192 if (tmp != NULL) {
12151223
12161224 static void
12171225 fu_util_device_added_cb (FwupdClient *client,
1218 FwupdResult *device,
1226 FwupdDevice *device,
12191227 gpointer user_data)
12201228 {
1221 g_autofree gchar *tmp = fwupd_result_to_string (device);
1229 g_autofree gchar *tmp = fwupd_device_to_string (device);
12221230 /* TRANSLATORS: this is when a device is hotplugged */
12231231 g_print ("%s\n%s", _("Device added:"), tmp);
12241232 }
12251233
12261234 static void
12271235 fu_util_device_removed_cb (FwupdClient *client,
1228 FwupdResult *device,
1236 FwupdDevice *device,
12291237 gpointer user_data)
12301238 {
1231 g_autofree gchar *tmp = fwupd_result_to_string (device);
1239 g_autofree gchar *tmp = fwupd_device_to_string (device);
12321240 /* TRANSLATORS: this is when a device is hotplugged */
12331241 g_print ("%s\n%s", _("Device removed:"), tmp);
12341242 }
12351243
12361244 static void
12371245 fu_util_device_changed_cb (FwupdClient *client,
1238 FwupdResult *device,
1246 FwupdDevice *device,
12391247 gpointer user_data)
12401248 {
1241 g_autofree gchar *tmp = fwupd_result_to_string (device);
1249 g_autofree gchar *tmp = fwupd_device_to_string (device);
12421250 /* TRANSLATORS: this is when a device has been updated */
12431251 g_print ("%s\n%s", _("Device changed:"), tmp);
12441252 }
12481256 {
12491257 /* TRANSLATORS: this is when the daemon state changes */
12501258 g_print ("%s\n", _("Changed"));
1259 }
1260
1261 static gboolean
1262 fu_util_smbios_dump (FuUtilPrivate *priv, gchar **values, GError **error)
1263 {
1264 g_autofree gchar *tmp = NULL;
1265 g_autoptr(FuSmbios) smbios = NULL;
1266 if (g_strv_length (values) < 1) {
1267 g_set_error_literal (error,
1268 FWUPD_ERROR,
1269 FWUPD_ERROR_INVALID_ARGS,
1270 "Invalid arguments: expected FILENAME");
1271 return FALSE;
1272 }
1273 smbios = fu_smbios_new ();
1274 if (!fu_smbios_setup_from_file (smbios, values[0], error))
1275 return FALSE;
1276 tmp = fu_smbios_to_string (smbios);
1277 g_print ("%s\n", tmp);
1278 return TRUE;
12511279 }
12521280
12531281 static gboolean
13131341 const gchar *uri_tmp;
13141342 g_autofree gchar *basename = NULL;
13151343 g_autofree gchar *fn = NULL;
1344 g_autofree gchar *uri_str = NULL;
13161345 g_autoptr(SoupURI) uri = NULL;
13171346
13181347 /* work out what remote-specific URI fields this should use */
13311360 if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) {
13321361 const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
13331362 g_autofree gchar *path = g_path_get_dirname (fn_cache);
1363
1364 /* install with flags chosen by the user */
13341365 fn = g_build_filename (path, uri_tmp, NULL);
1335 return fu_util_install_with_fallback (priv,
1336 fwupd_device_get_id (dev),
1337 fn, error);
1338 }
1339
1340 uri = fwupd_remote_build_uri (remote, uri_tmp, error);
1341 if (uri == NULL)
1366 return fwupd_client_install (priv->client,
1367 fwupd_device_get_id (dev),
1368 fn, priv->flags, NULL, error);
1369 }
1370
1371 uri_str = fwupd_remote_build_firmware_uri (remote, uri_tmp, error);
1372 if (uri_str == NULL)
13421373 return FALSE;
13431374 } else {
1344 uri = soup_uri_new (uri_tmp);
1375 uri_str = g_strdup (uri_tmp);
13451376 }
13461377
13471378 /* download file */
13531384 if (!fu_common_mkdir_parent (fn, error))
13541385 return FALSE;
13551386 checksums = fwupd_release_get_checksums (rel);
1387 uri = soup_uri_new (uri_tmp);
13561388 if (!fu_util_download_file (priv, uri, fn,
13571389 fwupd_checksum_get_best (checksums),
13581390 error))
13601392 g_print ("Updating %s on %s...\n",
13611393 fwupd_release_get_version (rel),
13621394 fwupd_device_get_name (dev));
1363 return fu_util_install_with_fallback (priv, fwupd_device_get_id (dev), fn, error);
1395 return fwupd_client_install (priv->client,
1396 fwupd_device_get_id (dev), fn,
1397 priv->flags, NULL, error);
13641398 }
13651399
13661400 static gboolean
13671401 fu_util_update (FuUtilPrivate *priv, gchar **values, GError **error)
13681402 {
1369 g_autoptr(GPtrArray) results = NULL;
1370
1371 /* apply any updates */
1372 results = fwupd_client_get_updates (priv->client, NULL, error);
1373 if (results == NULL)
1374 return FALSE;
1375 for (guint i = 0; i < results->len; i++) {
1376 FwupdResult *res = g_ptr_array_index (results, i);
1377 FwupdDevice *dev = fwupd_result_get_device (res);
1378 FwupdRelease *rel = fwupd_result_get_release (res);
1379 GPtrArray *checksums = fwupd_release_get_checksums (rel);
1380 if (checksums->len == 0)
1403 g_autoptr(GPtrArray) devices = NULL;
1404
1405 /* get devices from daemon */
1406 devices = fwupd_client_get_devices (priv->client, NULL, error);
1407 if (devices == NULL)
1408 return FALSE;
1409 for (guint i = 0; i < devices->len; i++) {
1410 FwupdDevice *dev = g_ptr_array_index (devices, i);
1411 FwupdRelease *rel;
1412 g_autoptr(GPtrArray) rels = NULL;
1413 g_autoptr(GError) error_local = NULL;
1414
1415 /* not going to have results, so save a D-Bus round-trip */
1416 if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED))
13811417 continue;
1382 if (fwupd_release_get_uri (rel) == NULL)
1418
1419 /* get the releases for this device and filter for validity */
1420 rels = fwupd_client_get_upgrades (priv->client,
1421 fwupd_device_get_id (dev),
1422 NULL, &error_local);
1423 if (rels == NULL) {
1424 g_printerr ("%s\n", error_local->message);
13831425 continue;
1426 }
1427 rel = g_ptr_array_index (rels, 0);
13841428 if (!fu_util_update_device_with_release (priv, dev, rel, error))
13851429 return FALSE;
13861430 }
1387
13881431 return TRUE;
1432 }
1433
1434 static gboolean
1435 fu_util_modify_remote (FuUtilPrivate *priv, gchar **values, GError **error)
1436 {
1437 if (g_strv_length (values) < 3) {
1438 g_set_error_literal (error,
1439 FWUPD_ERROR,
1440 FWUPD_ERROR_INVALID_ARGS,
1441 "Invalid arguments: expected REMOTE-ID KEY VALUE");
1442 return FALSE;
1443 }
1444 return fwupd_client_modify_remote (priv->client,
1445 values[0], values[1], values[2],
1446 NULL, error);
13891447 }
13901448
13911449 static gboolean
13941452 g_autoptr(FwupdDevice) dev = NULL;
13951453 g_autoptr(FwupdRelease) rel = NULL;
13961454 g_autoptr(GPtrArray) rels = NULL;
1397 g_autoptr(GPtrArray) rels_filtered = NULL;
13981455
13991456 /* get device to use */
14001457 if (g_strv_length (values) == 1) {
14091466 }
14101467
14111468 /* get the releases for this device and filter for validity */
1412 rels = fwupd_client_get_releases (priv->client,
1413 fwupd_device_get_id (dev),
1414 NULL, error);
1469 rels = fwupd_client_get_downgrades (priv->client,
1470 fwupd_device_get_id (dev),
1471 NULL, error);
14151472 if (rels == NULL)
14161473 return FALSE;
1417 rels_filtered = g_ptr_array_new ();
1418 for (guint i = 0; i < rels->len; i++) {
1419 FwupdRelease *rel_tmp = g_ptr_array_index (rels, i);
1420
1421 /* only include older firmware */
1422 if (as_utils_vercmp (fwupd_release_get_version (rel_tmp),
1423 fwupd_device_get_version (dev)) >= 0) {
1424 g_debug ("ignoring %s as older than %s",
1425 fwupd_release_get_version (rel_tmp),
1426 fwupd_device_get_version (dev));
1427 continue;
1428 }
1429
1430 /* don't show releases we are not allowed to dowgrade to */
1431 if (fwupd_device_get_version_lowest (dev) != NULL) {
1432 if (as_utils_vercmp (fwupd_release_get_version (rel_tmp),
1433 fwupd_device_get_version_lowest (dev)) <= 0) {
1434 g_debug ("ignoring %s as older than lowest %s",
1435 fwupd_release_get_version (rel_tmp),
1436 fwupd_device_get_version_lowest (dev));
1437 continue;
1438 }
1439 }
1440
1441 /* don't show releases without URIs */
1442 if (fwupd_release_get_uri (rel_tmp) == NULL) {
1443 g_debug ("ignoring %s as no URI",
1444 fwupd_release_get_version (rel_tmp));
1445 continue;
1446 }
1447
1448 g_ptr_array_add (rels_filtered, rel_tmp);
1449 }
14501474
14511475 /* get the chosen release */
1452 rel = fu_util_prompt_for_release (priv, rels_filtered, error);
1476 rel = fu_util_prompt_for_release (priv, rels, error);
14531477 if (rel == NULL)
14541478 return FALSE;
14551479 priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_OLDER;
14591483 static gboolean
14601484 fu_util_hwids (FuUtilPrivate *priv, gchar **values, GError **error)
14611485 {
1486 g_autoptr(FuSmbios) smbios = fu_smbios_new ();
14621487 g_autoptr(FuHwids) hwids = fu_hwids_new ();
14631488 const gchar *hwid_keys[] = {
14641489 FU_HWIDS_KEY_BIOS_VENDOR,
14741499 FU_HWIDS_KEY_BASEBOARD_PRODUCT,
14751500 NULL };
14761501
1477 /* read files in /sys */
1478 if (!fu_hwids_setup (hwids, g_getenv ("SYSFSPATH"), error))
1502 /* read DMI data */
1503 if (!fu_smbios_setup (smbios, error))
1504 return FALSE;
1505 if (!fu_hwids_setup (hwids, smbios, error))
14791506 return FALSE;
14801507
14811508 /* show debug output */
16601687 _("Clears the results from the last update"),
16611688 fu_util_clear_results);
16621689 fu_util_add (priv->cmd_array,
1690 "clear-offline",
1691 NULL,
1692 /* TRANSLATORS: command description */
1693 _("Clears any updates scheduled to be updated offline"),
1694 fu_util_clear_offline);
1695 fu_util_add (priv->cmd_array,
16631696 "get-results",
16641697 NULL,
16651698 /* TRANSLATORS: command description */
17071740 /* TRANSLATORS: command description */
17081741 _("Build firmware using a sandbox"),
17091742 fu_util_firmware_builder);
1743 fu_util_add (priv->cmd_array,
1744 "smbios-dump",
1745 NULL,
1746 /* TRANSLATORS: command description */
1747 _("Dump SMBIOS data from a file"),
1748 fu_util_smbios_dump);
1749 fu_util_add (priv->cmd_array,
1750 "modify-remote",
1751 NULL,
1752 /* TRANSLATORS: command description */
1753 _("Modifies a given remote"),
1754 fu_util_modify_remote);
17101755
17111756 /* do stuff on ctrl+c */
17121757 priv->cancellable = g_cancellable_new ();
0 Fuzzing
1 =======
2
3 CC=afl-gcc meson --default-library=static ../
4 AFL_HARDEN=1 ninja
5 afl-fuzz -m 300 -i ../src/fuzzing/smbios -o src/smbios/findings ./src/fwupdmgr smbios-dump @@
0 <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
1 <!-- Please adjust the date whenever revising the manpage. -->
2 <!ENTITY date "<date>26 February,2015</date>">
3 <!ENTITY package "fwupdmgr">
4 <!ENTITY gnu "<acronym>GNU</acronym>">
5 <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
6 ]>
7
8 <refentry>
9 <refentryinfo>
10 <address>
11 <email>richard@hughsie.com</email>;
12 </address>
13 <author>
14 <firstname>Richard</firstname>
15 <surname>Hughes</surname>
16 </author>
17 <copyright>
18 <year>2015</year>
19 <holder>Richard Hughes</holder>
20 </copyright>
21 &date;
22 </refentryinfo>
23 <refmeta>
24 <refentrytitle>fwupdmgr</refentrytitle>
25 <manvolnum>1</manvolnum>
26 </refmeta>
27 <refnamediv>
28 <refname>&package;</refname>
29 <refpurpose>fwupd client tool</refpurpose>
30 </refnamediv>
31 <refsynopsisdiv>
32 <cmdsynopsis>
33 <command>&package;</command>
34 <arg><option>options</option></arg>
35 <arg>COMMAND</arg>
36 </cmdsynopsis>
37 </refsynopsisdiv>
38 <refsect1>
39 <title>DESCRIPTION</title>
40 <para>
41 This manual page documents briefly the <command>&package;</command> command.
42 </para>
43 <para>
44 <command>&package;</command> allows an administrator to update firmware.
45 </para>
46 </refsect1>
47 <refsect1>
48 <title>OPTIONS</title>
49 <para>
50 This program follows the usual &gnu; command line syntax,
51 with long options starting with two dashes (`-'). A summary of
52 options is included below.
53 </para>
54 <variablelist>
55 <varlistentry>
56 <term>
57 <option>--help</option>
58 </term>
59 <listitem>
60 <para>Show summary of options.</para>
61 </listitem>
62 </varlistentry>
63 <varlistentry>
64 <term>
65 <option>--verbose</option>
66 </term>
67 <listitem>
68 <para>Show extra debugging information.</para>
69 </listitem>
70 </varlistentry>
71 <varlistentry>
72 <term>
73 <option>--allow-reinstall</option>
74 </term>
75 <listitem>
76 <para>Allow re-installing existing firmware versions.</para>
77 </listitem>
78 </varlistentry>
79 <varlistentry>
80 <term>
81 <option>--allow-older</option>
82 </term>
83 <listitem>
84 <para>Allow downgrading firmware versions.</para>
85 </listitem>
86 </varlistentry>
87 <varlistentry>
88 <term>
89 <option>--offline</option>
90 </term>
91 <listitem>
92 <para>Schedule installation for next reboot when possible.</para>
93 </listitem>
94 </varlistentry>
95 <varlistentry>
96 <term>
97 <option>--force</option>
98 </term>
99 <listitem>
100 <para>Override plugin warning.</para>
101 </listitem>
102 </varlistentry>
103 </variablelist>
104 </refsect1>
105 <refsect1>
106 <title>COMMANDS</title>
107 <para>
108 This program takes commands with a variable number of arguments.
109 </para>
110 <variablelist>
111 <varlistentry>
112 <term>
113 <option>get-details</option>
114 </term>
115 <listitem>
116 <para>Gets details about a firmware file.</para>
117 </listitem>
118 </varlistentry>
119 <varlistentry>
120 <term>
121 <option>get-devices</option>
122 </term>
123 <listitem>
124 <para>Get the list of hardware that supports firmware updates.</para>
125 </listitem>
126 </varlistentry>
127 <varlistentry>
128 <term>
129 <option>get-updates</option>
130 </term>
131 <listitem>
132 <para>Gets the list of updates for connected hardware.</para>
133 </listitem>
134 </varlistentry>
135 <varlistentry>
136 <term>
137 <option>update</option>
138 </term>
139 <listitem>
140 <para>Updates all firmware to latest versions available.</para>
141 </listitem>
142 </varlistentry>
143 <varlistentry>
144 <term>
145 <option>install</option>
146 </term>
147 <listitem>
148 <para>Install a firmware file on this hardware.</para>
149 </listitem>
150 </varlistentry>
151 <varlistentry>
152 <term>
153 <option>install-prepared</option>
154 </term>
155 <listitem>
156 <para>Install prepared updates now.</para>
157 </listitem>
158 </varlistentry>
159 <varlistentry>
160 <term>
161 <option>clear-results</option>
162 </term>
163 <listitem>
164 <para>Clears the results from the last update.</para>
165 </listitem>
166 </varlistentry>
167 <varlistentry>
168 <term>
169 <option>dump-rom</option>
170 </term>
171 <listitem>
172 <para>Dump the ROM checksum.</para>
173 </listitem>
174 </varlistentry>
175 <varlistentry>
176 <term>
177 <option>monitor</option>
178 </term>
179 <listitem>
180 <para>Monitor the daemon for events.</para>
181 </listitem>
182 </varlistentry>
183 <varlistentry>
184 <term>
185 <option>unlock</option>
186 </term>
187 <listitem>
188 <para>Unlocks the devicefor firmware access.</para>
189 </listitem>
190 </varlistentry>
191 <varlistentry>
192 <term>
193 <option>verify</option>
194 </term>
195 <listitem>
196 <para>Gets the cryptographic hash of the dumped firmware.</para>
197 </listitem>
198 </varlistentry>
199 <varlistentry>
200 <term>
201 <option>verify-update</option>
202 </term>
203 <listitem>
204 <para>Update the stored metadata with current ROM contents.</para>
205 </listitem>
206 </varlistentry>
207 <varlistentry>
208 <term>
209 <option>refresh</option>
210 </term>
211 <listitem>
212 <para>Refresh metadata from remote server.</para>
213 </listitem>
214 </varlistentry>
215 <varlistentry>
216 <term>
217 <option>get-results</option>
218 </term>
219 <listitem>
220 <para>Gets the results from the last update.</para>
221 </listitem>
222 </varlistentry>
223 </variablelist>
224 </refsect1>
225 <refsect1>
226 <title>AUTHOR</title>
227 <para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
228 </para>
229 </refsect1>
230 </refentry>
231
232 <!-- Keep this comment at the end of the file
233 Local variables:
234 mode: sgml
235 sgml-omittag:t
236 sgml-shorttag:t
237 sgml-minimize-attributes:nil
238 sgml-always-quote-attributes:t
239 sgml-indent-step:2
240 sgml-indent-data:t
241 sgml-parent-document:nil
242 sgml-default-dtd-file:nil
243 sgml-exposed-tags:nil
244 sgml-local-catalogs:nil
245 sgml-local-ecat-files:nil
246 End:
247 -->
2222 sources : [
2323 'fu-common.c',
2424 'fu-device.c',
25 'fu-device-locker.c',
2526 'fu-hwids.c',
2627 'fu-pending.c',
2728 'fu-plugin.c',
29 'fu-progressbar.c',
30 'fu-smbios.c',
2831 'fu-test.c',
2932 ],
3033 include_directories : [
4548 c_args : [
4649 cargs,
4750 '-DLOCALSTATEDIR="' + localstatedir + '"',
51 '-DSYSFSFIRMWAREDIR="/sys/firmware"',
4852 '-DFU_OFFLINE_DESTDIR=""',
4953 ],
5054 )
5256 executable(
5357 'fwupdmgr',
5458 sources : [
55 'fu-progressbar.c',
5659 'fu-util.c',
5760 ],
5861 include_directories : [
8184 install : true,
8285 install_dir : get_option('bindir')
8386 )
87
88 if get_option('enable-man')
89 docbook2man = find_program('docbook2man')
90 custom_target('fwupdmgr-man',
91 input : 'fwupdmgr.sgml',
92 output : 'fwupdmgr.1',
93 command : [
94 docbook2man, '@INPUT@',
95 '--output', meson.current_build_dir(),
96 ],
97 install : true,
98 install_dir : join_paths(get_option('mandir'), 'man1'),
99 )
100 endif
84101
85102 resources_src = gnome.compile_resources(
86103 'fwupd-resources',
103120 'fu-hwids.c',
104121 'fu-debug.c',
105122 'fu-device.c',
123 'fu-device-locker.c',
106124 'fu-keyring.c',
107125 'fu-pending.c',
108126 'fu-plugin.c',
127 'fu-smbios.c',
109128 ],
110129 include_directories : [
111130 include_directories('..'),
128147 c_args : [
129148 cargs,
130149 '-DLOCALSTATEDIR="' + localstatedir + '"',
150 '-DPLUGINDIR="' + plugin_dir + '"',
151 '-DSYSFSFIRMWAREDIR="/sys/firmware"',
152 '-DSYSCONFDIR="' + default_sysconfdir + '"',
153 '-DFWUPDCONFIGDIR="' + join_paths(default_sysconfdir, 'fwupd') + '"',
131154 '-DFU_OFFLINE_DESTDIR=""',
132155 ],
133156 install : true,
140163 pluginbuilddir = join_paths(meson.build_root(), 'plugins', 'test')
141164 e = executable(
142165 'fu-self-test',
166 resources_src,
143167 colorhug_test_firmware,
144168 colorhug_pkcs7_signature,
145169 builder_test_firmware,
147171 keyring_src,
148172 'fu-self-test.c',
149173 'fu-common.c',
174 'fu-config.c',
175 'fu-engine.c',
150176 'fu-keyring.c',
151177 'fu-hwids.c',
152178 'fu-device.c',
179 'fu-device-locker.c',
153180 'fu-pending.c',
154181 'fu-keyring.c',
155182 'fu-keyring-result.c',
156183 'fu-plugin.c',
184 'fu-progressbar.c',
185 'fu-smbios.c',
157186 'fu-test.c',
158187 ],
159188 include_directories : [
184213 '-DLOCALSTATEDIR="/tmp/fwupd-self-test/var"',
185214 '-DPLUGINBUILDDIR="' + pluginbuilddir + '"',
186215 '-DFU_OFFLINE_DESTDIR="/tmp/fwupd-self-test"',
216 '-DPLUGINDIR="' + testdatadir_src + '"',
217 '-DSYSFSFIRMWAREDIR="' + testdatadir_src + '"',
218 '-DSYSCONFDIR="' + testdatadir_src + '"',
219 '-DFWUPDCONFIGDIR="' + testdatadir_src + '"',
187220 ],
188221 )
189222 test('fu-self-test', e, is_parallel:false)
190223 endif
224
225 if get_option('enable-introspection')
226 gir_dep = declare_dependency(sources: gir)
227 gnome.generate_gir(fwupd,
228 sources : [
229 'fu-common.c',
230 'fu-common.h',
231 'fu-device.c',
232 'fu-device.h',
233 'fu-device-locker.c',
234 'fu-device-locker.h',
235 'fu-plugin.c',
236 'fu-plugin.h',
237 ],
238 nsversion : '1.0',
239 namespace : 'Fu',
240 symbol_prefix : 'fu',
241 identifier_prefix : 'Fu',
242 export_packages : 'fu',
243 include_directories : [
244 include_directories('..'),
245 include_directories('../libfwupd'),
246 ],
247 dependencies : [
248 appstream_glib,
249 gir_dep,
250 giounix,
251 gusb,
252 soup,
253 sqlite,
254 ],
255 link_with : [
256 libfwupdprivate,
257 ],
258 includes : [
259 'Gio-2.0',
260 'GObject-2.0',
261 'GUsb-1.0',
262 ],
263 )
264 endif
5252 </doc:para>
5353 </doc:description>
5454 </doc:doc>
55 <arg type='a{sa{sv}}' name='devices' direction='out'>
56 <doc:doc>
57 <doc:summary>
58 <doc:para>An array of devices, with any properties set on each.</doc:para>
59 </doc:summary>
60 </doc:doc>
61 </arg>
62 </method>
63
64 <!--***********************************************************-->
65 <method name='GetUpdates'>
66 <doc:doc>
67 <doc:description>
68 <doc:para>
69 Gets a list of all the devices that can be updated.
70 </doc:para>
71 </doc:description>
72 </doc:doc>
73 <arg type='a{sa{sv}}' name='devices' direction='out'>
55 <arg type='aa{sv}' name='devices' direction='out'>
7456 <doc:doc>
7557 <doc:summary>
7658 <doc:para>An array of devices, with any properties set on each.</doc:para>
11092 </method>
11193
11294 <!--***********************************************************-->
113 <method name='GetDetailsLocal'>
95 <method name='GetDowngrades'>
96 <doc:doc>
97 <doc:description>
98 <doc:para>
99 Gets a list of all the downgrades possible for a specific device.
100 </doc:para>
101 </doc:description>
102 </doc:doc>
103 <arg type='s' name='device_id' direction='in'>
104 <doc:doc>
105 <doc:summary>
106 <doc:para>
107 A device ID.
108 </doc:para>
109 </doc:summary>
110 </doc:doc>
111 </arg>
112 <arg type='aa{sv}' name='releases' direction='out'>
113 <doc:doc>
114 <doc:summary>
115 <doc:para>
116 An array of releases (with the release number as the key),
117 with any properties set on each.
118 </doc:para>
119 </doc:summary>
120 </doc:doc>
121 </arg>
122 </method>
123
124 <!--***********************************************************-->
125 <method name='GetUpgrades'>
126 <doc:doc>
127 <doc:description>
128 <doc:para>
129 Gets a list of all the upgrades possible for a specific device.
130 </doc:para>
131 </doc:description>
132 </doc:doc>
133 <arg type='s' name='device_id' direction='in'>
134 <doc:doc>
135 <doc:summary>
136 <doc:para>
137 A device ID.
138 </doc:para>
139 </doc:summary>
140 </doc:doc>
141 </arg>
142 <arg type='aa{sv}' name='releases' direction='out'>
143 <doc:doc>
144 <doc:summary>
145 <doc:para>
146 An array of releases (with the release number as the key),
147 with any properties set on each.
148 </doc:para>
149 </doc:summary>
150 </doc:doc>
151 </arg>
152 </method>
153
154 <!--***********************************************************-->
155 <method name='GetDetails'>
114156 <doc:doc>
115157 <doc:description>
116158 <doc:para>
128170 </doc:summary>
129171 </doc:doc>
130172 </arg>
131 <arg type='a{sa{sv}}' name='results' direction='out'>
173 <arg type='aa{sv}' name='results' direction='out'>
132174 <doc:doc>
133175 <doc:summary>
134176 <doc:para>An array of results, with any properties set on each.</doc:para>
301343 </method>
302344
303345 <!--***********************************************************-->
304 <method name='UpdateMetadataWithId'>
346 <method name='UpdateMetadata'>
305347 <doc:doc>
306348 <doc:description>
307349 <doc:para>
332374 <doc:summary>
333375 <doc:para>
334376 File handle to AppStream metadata GPG signature.
377 </doc:para>
378 </doc:summary>
379 </doc:doc>
380 </arg>
381 </method>
382
383 <!--***********************************************************-->
384 <method name='ModifyRemote'>
385 <doc:doc>
386 <doc:description>
387 <doc:para>
388 Modifies a remote in some way.
389 </doc:para>
390 </doc:description>
391 </doc:doc>
392 <arg type='s' name='remote_id' direction='in'>
393 <doc:doc>
394 <doc:summary>
395 <doc:para>
396 Remote ID, e.g. 'lvfs-testing'.
397 </doc:para>
398 </doc:summary>
399 </doc:doc>
400 </arg>
401 <arg type='s' name='key' direction='in'>
402 <doc:doc>
403 <doc:summary>
404 <doc:para>
405 The key, e.g. 'Enabled'.
406 </doc:para>
407 </doc:summary>
408 </doc:doc>
409 </arg>
410 <arg type='s' name='value' direction='in'>
411 <doc:doc>
412 <doc:summary>
413 <doc:para>
414 The value of the correct type, e.g. a URL.
335415 </doc:para>
336416 </doc:summary>
337417 </doc:doc>